要创建一个网格,首先需要知道ID3DXMesh这个网格接口,它继承了ID3DXBaseMesh的大部分功能,这一点很重要,因为其他类型的网格接口,如ID3DXPMesh(渐近网格),也继承自该接口。
ID3DXMesh接口包含有一个顶点缓存(用于存储顶点数据),一个索引缓存(用于定义顶点以何种方式构成网格的三角形单元),还有一个属性缓存(其中每一项用于对应一个三角形单元,并指定面片所属的子集)。
IDirect3D9VertexBuffer* vb=0;
ID3DXMesh* mesh;
mesh->GetVertexBuffer(&vb);
IDirect3D9IndexBuffer* ib=0;
mesh->GetIndexBuffer(&ib);
以上代码通过网格对象,得到了一个顶点缓存跟索引缓存,要往缓存中填入数据,则需要对缓存进行锁定如:
Vertex* v=0;
mesh->LockVertexBuffer(0,(void**) &v);
v[0]=Vertex(....);
....
mesh->UnlockVertexBuffer();
WORD* i=0;
mesh->LockIndexBuffer(0,(void**)&i);
i[0]=...;
...
填入顶点数据及索引数据进入缓存后,我们必须指定每个面片所属于的子集。属性缓存里正存储了网格中每个面片的所属子集。如:
DWORD* attributeBuffer=0;
mesh->LockAttributeBuffer(0,&attributeBuffer);
...
...
mesh->UnlockAttributeBuffer();
将三角面片指定相应的子集。
从上面我们就创建了一个合法数据的网格,然后就可以进行绘制网格了。在绘制之前,我们可以对网格进行相应的优化处理。
对网格进行优化时,我们需要计算该网格的邻接信息:即需要知道对任意给定的三角形面片,哪些面片与其邻接。这些邻接信息被存储在一个邻接数组当中。每个三角形都有三条边,所以任意一个三角形将至多有3个三角形面片于其邻接,定义一个邻接数组维度为:
std::vector<DWORD> adjacencyBuffer(mesh->GetNumFaces()*3);
mesh->GenerateAdjacency(0.0f,adjacency);
HRESULT hr;
hr=mesh->OptimizeInplace(....);
从以上的过程,网格生成已设置全部完成,现在就可以进行render了。
绘制时:
NumSubsets子集个数变量的获取可通过:mesh->GetAttributeTable(0,&NumSubsets);
for(int i=0;i<NumSubsets;i++)
{
Device->SetTexture(0,Texture[i];
mesh->DrawSub(i);
}
整个简单的网格建立,并根据属性表中的子集来进行相应三角形面片的绘制及纹理渲染过程基本完成。上面的网格数据是手工生成填入相应缓存的,我们也可以通过加载磁盘中的复杂的3D网格模型并将该模型绘制出来或者可以利用渐进网格接口来控制网格的细节层次(LOD)...