前言:
一个场景中,任何物体都可以用三角形网格来逼近表示。也就是说,三角形网格是构成物体模型的基本单元。
如图:
利用线框模式绘制可旋转的正方体的具体操作:
1.顶点缓存和索引缓存:
一个多边形中相邻的交汇点称为顶点,描述三角形单元时,我们需要指定该三角形3个顶点的位置。那么如果我们要通过三角形单元来描述一个物体,就需要指定构成该物体的三角形单元。但是要知道的是,在构成一个3D物体时,三角形单元之间会存在很多的公共顶点。如果模型的复杂度特别高,那么顶点的重复会更多。比如说:一个正方体,如果用简单的三角形构成,需要12个三角形,如果分开来算,需要36个顶点。但是实际上一个正方体只需要8个顶点。那么在Direct3D中使用了顶点缓存和索引缓存来处理这种情况。
如:对于一个立方体:
我们利用顶点缓存,来存储这8个顶点并对顶点进行编号,然后利用索引缓存来记录每个三角形都使用了哪些顶点:
Vertex vertexList[8] = { 0, 1, 2, 3 ,4,5,6,7};
WORD IndexList[6] = {0,1,2 //三角形0
0,2,3//三角形1
}
代码实现:
我们利用IDirect3DDevice9::CreateVertexBuffer(...)和IDirect3DDevice9::CreateIndexBuffer(...)来分别创建顶点缓存和索引缓存。那么如何来写入数据呢?
为了能够访问顶端缓存和索引缓存的数据,需要获得指向该缓存内部的指针,然后通过Lock(...)获取指向缓存内容的指针,进行锁定。然后进行读取或写入,但是要注意:当访问结束后需要利用Unlock()方法进行解锁。
//创建顶点缓存和索引缓存
Device->CreateVertexBuffer(8 * sizeof(Vertex),D3DUSAGE_WRITEONLY,Vertex::FVF,D3DPOOL_MANAGED,&VB,0);
Device->CreateIndexBuffer(36 * sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&IB,0);
//访问顶点缓存,将Cube顶点数据写入
Vertex* vertices;
VB->Lock(0, 0, (void**)&vertices, 0);
vertices[0] = Vertex(-1.0f, -1.0f, -1.0f);
vertices[1] = Vertex(-1.0f, 1.0f, -1.0f);
vertices[2] = Vertex(1.0f, 1.0f, -1.0f);
vertices[3] = Vertex(1.0f, -1.0f, -1.0f);
vertices[4] = Vertex(-1.0f, -1.0f, 1.0f);
vertices[5] = Vertex(-1.0f, 1.0f, 1.0f);
vertices[6] = Vertex(1.0f, 1.0f, 1.0f);
vertices[7] = Vertex(1.0f, -1.0f, 1.0f);
VB->Unlock();
//访问索引缓存,将三角形单元的顶点构成数据写入
WORD* indices = 0;
IB->Lock(0, 0, (void**)&indices, 0);
// front side
indices[0] = 0; indices[1] = 1; indices[2] = 2;
indices[3] = 0; indices[4] = 2; indices[5] = 3;
// back side
indices[6] = 4; indices[7] = 6; indices[8] = 5;
indices[9] = 4; indices[10] = 7; indices[11] = 6;
// left side
indices[12] = 4; indices[13] = 5; indices[14] = 1;
indices[15] = 4; indices[16] = 1; indices[17] = 0;
// right side
indices[18] = 3; indices[19] = 2; indices[20] = 6;
indices[21] = 3; indices[22] = 6; indi