索引缓存INDEXBUFFER
作用:对顶点数据进行优化节约内存空间加快运算速度。
如一个正方体有8个点,但如果每个三角形定义3个点的话用D3DPT_TRIANGLELIST需要8*3=24个,但如果给每个点建立一个索引编号,告知pc这个编号的点跟哪些点结合为一个三角形,这样就可以减少定义那些重复的点。
例子:
//定义四个顶点
{-0.3f, -0.3f, 0.0f, D3DCOLOR_XRGB(255,255,0)},
{0.3f, -0.3f, 0.0f, D3DCOLOR_XRGB(255,0,0)},
{0.0f, 0.3f, 0.0f, D3DCOLOR_XRGB(0,0,255)},
{0.3f, 0.3f, 0.0f, D3DCOLOR_XRGB(0,0,255)}
//定义顶点索引:
WORD g_Indices[] = {0,1,2,1,2,3};
//然后最后用D3DPT_TRIANGLELIST进行渲染:
g_D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,2);
这样索引与顶点之间利用编号建立了联系,从而避免了顶点重复定义带来的内存浪费问题,更提高了效率。
使用索引缓存的步骤:
1.创建IndexBuffer 对象
LPDIRECT3DINDEXBUFFER9 g_D3DIndexBuffer;
初始化3D物体顶点阶段:
2.创建索引数组
WORD g_Indices[] = {0,1,2,1,2,3};
注意:为何要使用WORD类型?
win32SDK中定义的WORD和DWORD类型是整型类。
其中WORD其是16-bit unsigned integer,即只有16位;
DWORD为32-bit unsigned integer,即有32位。
二者的位数不会随计算机位数的变化而变化。
由于数组内容为编号,固为int类型,且编号不会为负数,固为unsigned正数,16位与32为皆可,但要与后面
CreateIndexBuffer函数的D3DFORMAT format参数对应使用。
3.创建索引缓冲区
CreateIndexBuffer(sizeof(g_Indices), //缓存的大小
0, //DWORD usage,指定创建的索引缓冲区的属性。
D3DFMT_INDEX16, //指明索引数组的元素格式,可以是16位整数索引,也可以是32位整数索引
D3DPOOL_DEFAULT, //D3DPOOL:这里用D3DPOOL_DEFAULT,表示尽量储存在显存中。
&g_D3DIndexBuffer, //保存我们得到的索引缓冲区的入口,用于操作内存的。
NULL) //pSharedHandle: 也是一个保留参数,值为零。
4.锁定索引缓冲区,拷贝,解锁
g_D3DVetexBuffer->Lock(0,sizeof(objData),&pAimVertex,0);
memcpy(pAimVertex,objData,sizeof(objData));
g_D3DVetexBuffer->Unlock();
渲染阶段:
5.设置索引缓存,用索引缓存渲染函数
g_D3DDevice->SetIndices(g_D3DIndexBuffer);
g_D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,2);
HRESULT DrawIndexedPrimitive(D3DPRIMITIVETYPE Type, //图元类型
UINT MinIndex, //最小索引值
UINT NumVertices, //最大索引值
UINT StartIndex, //从这个索引开始
UINT PrimitiveCount //图元数量
);
其中要注意的是索引数组所定义的元素,是要符合图元类型的规则的。
例如:上面用的是D3DPT_TRIANGLELIST,数组是WORD g_Indices[] = {0,1,2,1,2,3};
但如果图元类型改为D3DPT_TRIANGLELFAN的话数组就应该是,WORD g_Indices[] = {0,1,2,3}了,
因为TRIANGLELFAN的顶点定义规则是1,2,3;1,3,4。所以在根据TRIANGLELFAN规则判断过后,顺序就变成
了012,023了~
附3种三角形图元定义规则:
D3DPT_TRIANGLELIST
由1,2,3或4.5.6构成对应的三角形
D3DPT_TRIANGLELSTRIP
由1,2,3或2.3.4构成对应的三角形
D3DPT_TRIANGLELFAN
由1,2,3或1.3.4构成对应的三角形