本章主要是对与ID3DXMesh接口
相关的数据和方法的介绍
ID3DXMesh接口
和ID3DXPMesh接口
都继承自ID3DXBaseMesh接口
,所以前两者有很多相同的特性
要熟悉ID3DXMesh接口对象
的内部数据组织的细节
如何创建、优化、绘制
ID3DXMesh接口的对象
1、几何信息
ID3DXBaseMesh接口
包含一个顶点缓存
和一个索引缓存
- 1、
顶点缓存
:用于存储网格顶点 - 2、
索引缓存
:决定顶点应以何种组合方式构成网格的三角形单元
ID3DXMesh接口
仅支持将索引化的三角形单元列表
作为其基本类型
ID3DXMesh接口
中用于获取几何信息
的几种方法:
- 1、
DWORD GetFVF()
:返回一个描述顶点格式的数值 - 2、
DWORD GetNumVertices()
:返回顶点缓存中的顶点个数 - 3、
DWORD GetNumBytesPerVertex()
:返回每个顶点所占的字节数 - 4、
DWORD GetNumFaces()
:返回网格中三角形面片的个数
在对一些缓存进行读写操作之前,需要先进行一些锁定缓存
的操作。其中有很多细节
2、子集和属性缓存
一个网格由一个或多个子集组成。一个子集是网格中一组可用相同属性进行绘制的三角形单元
。这里的属性是指材质、文理和绘制状态等
为了区分不同的子集,我们为每个子集指定一个唯一的非负整数值
。网格中的每个三角形单元都被赋予了一个属性ID
,该ID指定了该三角形单元所属的子集
三角形单元的属性ID
被存储在网格的属性缓存(attribute buffer)
中,该属性缓存实际上是一个DWORD类型的数组
由于每个面片在属性缓存中都有对应项,所以属性缓存中元素的个数与网格中面片的个数完全相等
。而且属性缓存中的项与在索引缓存中定义的三角形单元是一一对应的,即属性缓存中的第i项对应于索引缓存中的第i个三角形
3、绘制
ID3DXMesh接口
提供了方法DrawSubset(DWORD AttribId)
用于绘制由参数指定的子集中的三角形单元。若要绘制这个网格,必须绘制该网格的所有子集。每个子集都有一个对应的材质和纹理,这样就可以用属性ID找到与子集相关的材质和纹理
4、网格优化
网格优化
:为了更高效地绘制一个网格,我们可对该网格中的顶点和索引进行重组
HRESULT ID3DXMesh::OptimizeInplace(
DWORD Flags, 标记所要实施的优化方案
const DWORD *pAdjacencyIn, 指向未经优化的网格的邻接数组的指针
DWORD *pAdjacencyOut, 经过优化后的网格的邻接数组的指针
DWORD *pFaceRemap, 该数组填充了网格面片的重绘信息
LPD3DXBUFFER *ppVertexRemap 包含了顶点重绘信息
);
方法Optimize
将输出调用了该方法的网格对象优化后的版本
,但是调用该方法的那个网格对象本身不会发生改变
5、属性表
如果在处理网格优化的时候使用了D3DXMESHOPT_ATTRSORT标记
,则构成该网格的三角形面片就会依据其属性进行排序
,这样属于特定子集的三角形面片就会被保存在顶点缓存或索引缓存中的一个连续存储空间内
上述使用的优化标记还将创建一个属性表
。该属性表是一个D3DXATTRIBUTERANGE类型的结构体数组
,属性表中的每一项都对应于网格中的一个子集,并指定了该子集中面片的几何信息被存储在顶点缓存或索引缓存的哪一个存储块中
typedef struct _D3DXATTRIBUTERANGE
{
DWORD AttribId;
DWORD FaceStart;
DWORD FaceCount;
DWORD VertexStart;
DWORD VertexCount;
} D3DXATTRIBUTERANGE;
属性表创建之后,只要通过一次快速查找,就能找打属于该子集的全部面片,这样就使子集的绘制可以高效地完成
。注意,没有属性表时,为了绘制某个子集,就只能对整个属性缓存进行若干次线性查找以确定每个属于该子集的面片在索引缓存中的位置
ID3DXMesh
中提供了相关的函数来获取网格的属性表和属性表中属性的个数
6、邻接信息
对于某些网格运算(如网格优化),需要知道对任意给定的三角形面片,哪些面片与其邻接。这些邻接信息都存储在网格的邻接数组(adjacency array)
中
在计算顶点法线的时候,需要用到网格的邻接信息
许多D3DX网格创建函数都能够输出邻接信息
7、克隆
得到一个网格的副本,可以使用不同的创建选项和灵活顶点格式
在计算网格的顶点法线的时候需要用到
8、创建网格(D3DXCreateMeshFVF)
创建网格的常用方法:
- 1、
D3DXCreateMeshFVF
: - 2、
D3DXCreateMesh
:
具体的区别在实际使用的时候再详细研究
在实际应用中,使用网格创建函数来创建复杂的网格是不现实的;网格一般都是由3D建模师来建造的