以前我为每个网格使用了一个单独的顶点和索引缓冲区,但是我想尝试使用一个大的顶点缓冲区来减少DrawIndexed()调用。假设我有以下数组:
SimpleVertex vertices[] =
{
{ XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f) },
};
WORD indices[] =
{
3,1,0,
2,1,3,
0,5,4,
1,5,0,
3,4,7,
0,4,3,
1,6,5,
2,6,1,
2,7,6,
3,7,2,
6,4,5,
7,4,6,
};
这适用于单个索引多维数据集。但是,如果我想绘制两个立方体怎么办?如何设置索引缓冲区来处理它?我很困惑这些索引是否是每个多维数据集的本地,因此应该重复每36个索引,或者它们是否应该按此递增:
SimpleVertex vertices[] =
{
//first cube
{ XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f) },
//second cube
{ XMFLOAT3(-2.0f, 2.0f, -2.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(2.0f, 2.0f, -2.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(2.0f, 2.0f, 2.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-2.0f, 2.0f, 2.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(-2.0f, -2.0f, -2.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(2.0f, -2.0f, -2.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(2.0f, -2.0f, 2.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-2.0f, -2.0f, 2.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f) },
};
WORD indices[] =
{
//First cube
3,1,0,
2,1,3,
0,5,4,
1,5,0,
3,4,7,
0,4,3,
1,6,5,
2,6,1,
2,7,6,
3,7,2,
6,4,5,
7,4,6,
//second cube
11,9,8,
10,9,11,
8,13,12,
9,13,8,
11,12,15,
8,12,11,
9,14,13,
10,14,9,
10,15,14,
11,15,10,
14,12,13,
15,12,14,
};
基本上,我正在尝试理解如何使用多个对象绘制一个大型索引缓冲区。我是否正确地考虑了这个问题,还是应该让缓冲区一遍又一遍地重复使用相同的索引缓冲区?
我知道使用Instancing,但有时候几何体会发生变化,所以在这种情况下我需要避免使用它。
答案 0 :(得分:0)
决定开始编写代码来攻击理论盲。事实证明,确实需要增加索引数组以将大型顶点数组视为一个网格。我写了一个函数来为那些感兴趣的人说明这一点:
UINT* VertexCompiler::BuildIndexArray()
{
UINT* indices;
int indexCount = 0;
for (int i = 0; i < (int)mVertexObjects.size(); i++)
indexCount += mVertexObjects[i].NumIndices;
mIndexCount = indexCount;
indices = new UINT[indexCount];
int numObjects = (int)mVertexObjects.size();
int index = 0;
for (int i = 0; i < numObjects; i++)
{
for (int j = 0; j < (int)mVertexObjects[i].NumIndices; j++)
{
indices[index] = mVertexObjects[i].Indices[j] + (mVertexObjects[i].NumVertices * i);
index++;
}
}
return indices;
}
确保在完成索引后删除索引指针。通常,在函数内部分配内存并在外部删除它的设计很差,但这仅用于演示目的。通常,您应该在外部分配索引数组,并将其作为指向函数的指针传递。
需要注意的一件重要事情是使用UINT。关于该主题的大多数教科书和文章使用WORD分配较小的索引缓冲区。使用WORD内存分配,递增的索引数组将在索引值65535处溢出。因此,如果您要渲染索引超过16位的大量顶点,请使用UINT并且不要忘记切换到DXGI_FORMAT_R32_UINT而不是DXGI_FORMAT_R16_UINT。
E.g。
IASetIndexBuffer(indicesBuffer, DXGI_FORMAT_R32_UINT, 0);