DirectX11 索引缓存

索引缓存

1. 索引缓存如何创建?

由于索引要由GPU访问,所以它们必须放在一个特定的资源容器中,该容器称为索引缓冲(index buffer)。创建索引缓冲的过程与创建顶点缓冲的过程非常相似,只不过索引缓冲存储的是索引而非顶点。所以,这里不再赘述之前讨论过的内容,我们直接给出一个创建索引缓冲区的示例:

UINT indices [24] = {
    0, 1, 2,   //  Triangle  0
    0, 2, 3,   //  Triangle  1
    0, 3, 4,   //  Triangle  2
    0, 4, 5,   //  Triangle  3
    0, 5, 6,   //  Triangle  4
    0, 6, 7,   //  Triangle  5
    0, 7, 8,   //  Triangle  6
    0, 8, 1    //  Triangle  7
} ;

// 要创建的索引的描述
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT) * 24;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;

// 设定用于初始化索引缓冲的数据
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = indices;

// 创建索引缓冲
ID3D11Buffer* mIB;
HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mIB));

2. 如何绑定索引缓存?

与顶点缓冲区相同,所有的Direct3D资源在使用之前都必须先绑定到管线上。我们使用ID3D11DeviceContext::IASetIndexBuffer方法将一个索引缓冲区绑定到输入装配阶段。下面是一个例子:

md3dImmediateContext->IASetIndexBuffer(mIB, DXGI_FORMAT_R32_UINT, 0);

第2个参数表示索引格式。在本例中,我们使用的是32位无符号整数(DWORD);所以,该参数设为DXGI_FORMAT_R32_UINT。如果你希望节约一些内存,不需要这大的取值范围,那么可以改用16位无符号整数。还要注意的是,在IASetIndexBuffer方法中指定的格式必须与D3D11_BUFFER_DESC::ByteWidth数据成员指定的字节长度一致,否则会出现问题。索引缓冲区只支持DXGI_FORMAT_R16_UINT和DXGI_FORMAT_R32_UINT两种格式。第3个参数是一个偏移值,它表示从索引缓冲区的起始位置开始、到输入装配时实际读取数据的位置之间的字节长度。如果希望跳过索引缓冲区前面的一部分数据,那么可以使用该参数。

3. 索引缓存如何创建?

最后,当使用索引时,我们必须用DrawIndexed方法代替Draw方法:

void ID3D11DeviceContext::DrawIndexed(
    UINT IndexCount,
    UINT StartIndexLocation,
    INT BaseVertexLocation);

1.IndexCount:在当前绘图操作中使用的索引的数量。在一次绘图操作中不一定使用索引缓冲区中的全部索引;也就是说,我们可以绘制索引的一个连续子集。

2.StartIndexLocation:指定从索引缓冲区的哪个位置开始读取索引数据。

3.BaseVertexLocation:在绘图调用中与索引相加的一个整数。

DirectX11 索引缓存_第1张图片
我们可以使用以下3条语句依次绘制球体、立方体和圆柱体:

md3dImmediateContext->DrawIndexed(numSphereIndices, 0, 0);
md3dImmediateContex->DrawIndexed(numBoxIndices, firstBoxIndex, firstBoxVertexPos);
md3dImmediateContex->DrawIndexed(numCylIndices, firstCylIndex, firstCylVertexPos);

你可能感兴趣的:(2.,DirectX11龙书,学习笔记,DirectX11游戏开发)