10.1 几何信息
[in] DWORD Flags,
[in] const DWORD *pAdjacencyIn,
[out] DWORD *pAdjacencyOut,
[out] DWORD *pFaceRemap,
[out] LPD3DXBUFFER *ppVertexRemap
ID3DXMesh接口对象包含了一个用于保存网格中顶点数据的顶点缓冲区,和一个用于记录三角形顶点在顶点缓冲区中索引信息的索引缓冲区。
可以通过下面方法获得指向这些缓冲区的指针
ID3DXMesh::GetVertexBuffer(LPDIRECT3DVERTEXBUFF9 *ppVB);
ID3DXMesh::GetIndexBuffer(LPDIRECT3DINDEXBUFFER9 *ppIB);
注意:对于ID3DXMesh接口来说,是否在网格中使用索引缓冲区来描述三角形,决定用户设置的图元类型
如果需要读写缓冲区需要先锁定缓冲区
可以用下面方法
ID3DXMesh::LockVertexBuffer(DWORD Flags , BYTE **ppData);
ID3DXMesh::LockIndexBuffer(DWORD Flags , BYTE **ppData);
ID3DXMesh::UnlockVertexBuffer();
ID3DXMesh::UnlockIndexBuffer();
10.2 网格子集(subset)和属性缓冲区
网格由一个或多个网格子集组成。网格子集是一个网格中可被按照同样属性进行渲染的三角形的集合,通过一个唯一正整数标识不同的子集,这个正整数是DWORD类型。
在网格中,每个三角形都有一个叫做
属性ID
的值,用于记录它所在的子集。
每个三角形对应的子集ID被存储在网格的属性缓冲区中,这个缓冲区是一个DWORD类型数组
获取属性缓冲区指针可以用以下函数
DWORD *buff=0;
Mesh->LockAttributeBuffer(lockingFlags,&buffer);
.....读或写操作
Mesh->UnlockAttributeBuffer();
10.3 网格渲染
网格渲染调用以下函数
Mesh->DrawSubset(0);
如果渲染整个网格的所有子集可以用循环
for(int i; i<numSubsets;i++)
{
Mesh->DrawSubset(i);
}
10.4 网格优化
网格优化是对网格的顶点和索引进行重新组织以便更有效地渲染网格,可以调用以下函数进行优化
HRESULT OptimizeInplace(
[in] DWORD Flags,
[in] const DWORD *pAdjacencyIn,
[out] DWORD *pAdjacencyOut,
[out] DWORD *pFaceRemap,
[out] LPD3DXBUFFER *ppVertexRemap
);
网格优化还可以用另外一个函数是Optimize,不同的是,OptimizeInplace是对网格本身进行优化,而Optimize是返回一个
新的经过优化的网格
HRESULT Optimize(
[in] DWORD Flags,
[in] const DWORD *pAdjacencyIn,
[in, out] DWORD *pAdjacencyOut,
[in, out] DWORD *pFaceRemap,
[out] LPD3DXBUFFER *ppVertexRemap,
[out] LPD3DXMESH *ppOptMesh
);
10.5 网格属性表
当使用D3DXMESHOPT_ATTRSORT标志对网格进行优化后,网格中的图元会被按照其属性重新划分到顶点缓存和索引缓存的连续储蓄块中。
重新牌系列几何图远时,指定D3DXMESHOPT_ATTRSORT标记的优化还会创建一份属性表(与属性缓冲区是两个概念)
有了属性表,网格就可以通过一个简单的查询属性表操作来渲染整个网格子集
以下是属性表结构体:
typedef struct D3DXATTRIBUTERANGE {
DWORD AttribId;
DWORD FaceStart;
DWORD FaceCount;
DWORD VertexStart;
DWORD VertexCount;
} D3DXATTRIBUTERANGE, *LPD3DXATTRIBUTERANGE;
通过以下函数访问网格属性表
HRESULT GetAttributeTable(
[in, out] D3DXATTRIBUTERANGE *pAttribTable,
[in, out] DWORD *pAttribTableSize
);
这个方法可用完成两个任务,第一个返回属性表中存储元素的数量,第二个通过一个D3DXATTRIBUTERANGE结构的数组来获得指定的属性数据
DWORD numSubset =0;
Mesh->GetAttributeTable(0,&numSubset);//获取属性表元素个数,将第一个设置为0
D3DXATTRIBUTERANGE table = new D3DXATTRIBUTERANGE[numSubset];
Mesh->GetAttributeTable(table,&numSubset);//知道元素个数后,获取当前属性表属性
同时可以直接用ID3DXMesh::SetAttributeTable方法来设置属性表。
D3DXATTRIBUTERANGE attributeTable[12];
Mesh->SetAttributeTable(attributeTable,12);
10.6 邻接信息
对于某些网格相关的操作(例如优化)必须知道给定三角形的邻接三角形。
网格中的邻接数组(Adjacency array)就是用来存储这些信息的,邻接数组是一个DWORD类型的数组。
当邻接数组元素为4294967295时(也就是-1),表示三角形当前边没有邻接三角形
由于三角形有3条边,所有邻接数组大小必须为网格中面数的三倍
下面函数可以获得邻接信息:
HRESULT GenerateAdjacency(
[in] FLOAT Epsilon,
[in] DWORD *pAdjacency
);
例:
DWORD adjacency[Mesh->GetNumFaces()*3];
Mesh->GenerateAdjacency(0.001f,adjacency);
10.7 网格的克隆(cloning)
有时候需要把一个网格的数据拷贝到另一个网格中去,这个工作可以通过ID3DXMesh::CloneMeshFVF
HRESULT CloneMeshFVF(
[in] DWORD Options,
[in] DWORD FVF,
[in] LPDIRECT3DDEVICE9 pDevice,
[out, retval] LPD3DXMESH *ppCloneMesh
);
10.8 网格的创建(D3DXCreateMeshFVF)
我们可以用D3DXCreateMeshFVF创建一个空的网格,然后指定面和顶点的数量,分配大小合适的顶点、索引、属性缓冲区。
一旦拥有已分配了缓冲区的网格,就可以手动添加网格中的各种数据。
我们可以通过两个函数进行创建空的网格
HRESULT D3DXCreateMeshFVF(
__in DWORD NumFaces,
__in DWORD NumVertices,
__in DWORD Options,
__in DWORD FVF,
__in LPDIRECT3DDEVICE9 pD3DDevice,
__out LPD3DXMESH *ppMesh
);
HRESULT D3DXCreateMesh(
__in DWORD NumFaces,
__in DWORD NumVertices,
__in DWORD Options,
__in const LPD3DVERTEXELEMENT9 *pDeclaration,
__in LPDIRECT3DDEVICE9 pD3DDevice,
__out LPD3DXMESH *ppMesh
);
注意:第2个函数不指定FVF,而是一个D3DVERTEXELEMENT9结构的数组
通过给定一个FVF,返回一个D3DVERTEXELEMENT9结构体
HRESULT D3DXDeclaratorFromFVF(
__in DWORD FVF,
__inout D3DVERTEXELEMENT9 Declaration
);
10.10 小结
一个网格包括了顶点、索引和属性缓冲区。顶点和索引缓冲区存放了网格的集合信息(顶点和三角形)。属性缓冲区为每个三角形保存了一个相应的元素,它指定了三角形所处的网格子集。
网格可以用optimizeInplace或Optimize方法来优化。优化可以令网格的渲染更有效,在优化网格时,如果指定了D3DXMESHOPT_ATTRSORT标志位,将生成一个属性表。如果有属性表,网格就可以通过一个简单的查询属性表操作来渲染整个网格子集
网格的邻接信息是一个DWORD数组,网格中的每个三角形在这个数组中都有对应了三个索引值,这三个索引值分别指定与这个三角形所邻接的三个三角形。
可以通过D3DXCreateMeshFVF方法来创建空网格,然后通过合适的锁定方法(LockVertexBuffer、LockIndexBuffer和LockAttributeBuffer)向网格中写入有效的数据
步骤:
1、创建一个空的网格
2、填充顶点缓冲区和索引缓冲区
3、创建属性缓冲区数组并且指定那些图元属于哪个子集
4、创建一个存放邻接信息的邻接数组
5、优化网格,如果使用D3DXMESHOPT_ATTRSORT,同时生成一个属性表