DirectX 90 3D 网格一

网格(一)

几何信息

ID3DXBaseMesh接口包含一个顶点缓存(用来存储网格顶点)和一个索引缓存(用来决定顶点怎样构成网格的三角形单元)。

HRESULT ID3DXMesh::GetVertexBuffer(LPDIRECT3DVERTEXBUFFER9* ppVB);

HRESULT ID3DXMesh::GetIndexBuffer(LPDIRECT3DINDEXBUFFER9* ppIB);

例子:

IDirect3DVertexBuffer9* vb = 0;

Mesh
->GetVertexBuffer( &vb );

IDirect3DIndexBuffer9
* ib = 0;

Mesh
->GetIndexBuffer( &ib );

锁定缓存 再进行读写操作

HRESULT ID3DXMesh::LockVertexBuffer(DWORD Flags, BYTE ** ppDate);

……

HRESULT ID3DXMesh::UnlockVertexBuffer();

HRESULT ID3DXMesh::LockIndexBuffer(DWORD Flags, BYTE ** ppDate);

……

HRESULT ID3DXMesh::UnlockIndexBuffer();

其中Flags 描述了如何进行锁定。

下面是另外一些与mesh几何结构有关的ID3DXMesh接口方法:

 DWORD GetFVF()               //返回顶点的格式

DWORD GetNumVertices()        // 返回顶点缓存中的顶点数

DWORD GetNumBytesPerVertex()  //返回一个顶点所占的字节数

DWORD GetNumFaces()          //返回在mesh中的面(三角形)数 

子集和属性缓存

一个网格(mesh)由一个或数个子集组成。一个子集(subset)是网格中一组可用相同属性渲染的一组三角形。这里的属性是指材质,纹理和渲染状态。

为了区分不同的子集, 每个子集指定一个唯一的非负整数值。 网格中的每个三角形单元都被赋予一个属性ID指定三角形势单元所属的子集。 这些三角殂单元的属性ID被存储在网格的属性缓存(attribute buffer)中该 属性能在上是一个DWORD的数组。属性缓存中元素的个数与风格中布片的个数相等。

邻接信息

之所要计算邻接信息是为了要优化属性表。

每个三角形面片都有3个条边 帮每个面片最多可有3 个邻接三角形,所以邻接数组的维数必须为ID2DXBaseMesh::GetNumFaces()*3, 网格中的每个三角形都有3个可能的邻接面片。 如果邻接数组中某一项等于ULONG MAX=4294967295,慢表明网格中某一特定边没有邻接面片。

许多 D3D网格创建函数都能够输出邻接信息, 也可使用如下方法

HRESULT ID3DXMesh::GenerateAdjacency(

         FLOAT fEpsilon,

         DWORD * pAdjacenc

)

说明一下

· fEpsilon 一个很小的正数(epsilon)值, 指定在某种距离度量下, 两个点接近到种程度方可认为这两点为同一点。

·pAdhacency 指向一个DOWRD类型的数组的指针, 该数组中存储了邻接信息

例如:

 

std::vector<DWORD> adjacencyBuffer(Mesh->GetNumFaces() * 3);

Mesh
->GenerateAdjacency(0.0f, &adjacencyBuffer[0]);

绘制

ID3DXMesh接口提供了DrawSubset(DWORD AttribId)方法来绘制AttribId指示的子集中的各个三角形。

例如,要绘制子集0中的所有三角形,我们将这样写:

Mesh->DrawSubset(0);

为了绘制整个mesh,我们必须绘制mesh的所有子集。这是非常方便的用0,1,2,…,n-1来标识子集,这里的n是子集的总数。且有一个相对应的材质和纹理数组,即子集i与材质和纹理数组的第i项对应。这就使我们能够简单的用循环来渲染mesh:

 

网格优化

为了更高效地绘制一个网格, 我们可对该 风格中的顶点和索引进行重组。这个过程称为网格优化(Optimizing)。用直南的方法来完成优化。

HRESULT ID3DXMesh::OptimizeInplace(

       DWORD Flags,

       CONST DWORD* pAdjacencyIn,

       DWORD* pAdjacencyOut,

       DWORD* pFaceRemap,

       LPD3DXBUFFER* ppVertexRemap

);

·Flags 表示执行什么类型的优化方法。它可以是下面的一个或几个的组合:

           ·D3DXMESHOPT_COMPACT 从网格中移除无用的顶点和索引项。

           · D3DXMESHOPT_ATTRSORT根据属性给三角形排序并调整属性表,这将使DrawSubset执行更有效。

           ·D3DXMESHOPT_VERTEXCACHE 增加顶点缓存的命中率。

           ·D3DXMESHOPT_STRIPREORDE重组顶点索引使三角带尽可能的长。

           ·D3DXMESHOPT_IGNOREVERTS只优化索引信息,忽略顶点信息。

注意:D3DXMESHOPT_VERTEXCACHE和 D3DXMESHOPT_STRIPREORDER不能同时使用。

·pAdjacencyIn  指向未优化的网格的邻接数组的指针。

·pAdjacencyOut 指向一个DWORD数组,该数组被用来填充优化好了的网格邻接信息。该数组的维数必须有ID3DXMesh::GetNumFaces() * 3个元素。可以将其设置为0。

·pFaceRemap 指向一个DWORD数组,该数组直译了网格面片的重绘信息。该数组的维数应为ID3DXMesh::GetNumFaces()。当一个网格被优化时,索引缓存的面可能被移动;也就是说,在pFaceRemap中的第i项表示第i个原始面被移动到的面索引值。如果不需要该信息,可以将其设置为0。

·ppVertexRemap 指向ID3DXMesh对象指针的地址,该对象中保存了顶点的重给信息。该缓存包含的顶点数应为ID3DXMesh::GetNumVertices()个顶点。当一个网格被优化后,顶点可能被移动。顶点绘制信息用来说明原来的顶点被移动到新位置;也就是说,在ppVertexRemap中的第i项表示原来的第i个顶点的新位置。如果不需要该信息,可以将其设置为0。

一个更简单的方法是Optimize方法,它输出一个优化的mesh,而不是在原来mesh的基础上进行优化:

HRESULT Optimize(
  DWORD Flags,
  CONST DWORD * pAdjacencyIn,
  DWORD * pAdjacencyOut,
  DWORD * pFaceRemap,
  LPD3DXBUFFER * ppVertexRemap,
  LPD3DXMESH * ppOptMesh
);

属性表(P162)

当一个mesh被使用D3DXMESHOPT_ATTRSORT参数来优化后,mesh的几何信息将按照属性进行排序,这样各个子集的顶点/索引将组成连续的块。

网格(D3DXCreateMeshFVF

HRESULT D3DXCreateMeshFVF(     

    DWORD NumFaces,

    DWORD NumVertices,

    DWORD Options,

    DWORD FVF,

    LPDIRECT3DDEVICE9 pDevice,

    LPD3DXMESH *ppMesh

);

·NumFaces 网格将具有的面片总数。 大于0

·NunVertices 网格将有的总数。 大于0

·Options创建网格时所使用的创建标记。

         ·D3DXMESH_32BIT  网格将使用32位索引。

         ·D3DXMESH_MANAGED 网格数据将被存储于托管池中

         ·D3DXMESH_WRITEONLY 指定网格为只读

         ·D3DMXESH_DYNAMIC 网格缓存将使用动态内存

·FVF 存储在该 网格中的顶点的灵活顶点格式

·pDevice 与该网格相关的设备指针

·ppMesh  所创建的网格对象的指针

例如:

//12个三角形和24个顶点

hr = D3DXCreateMeshFVF(12, 24, D3DXMESH_MANAGED, Vertex::FVF, Device, &Mesh);

for(int i = 0; i < numSubsets; i++)

{

Device
->SetMaterial( mtrls[i] );

Device
->SetTexture( 0, textures[i] );

Mesh
->DrawSubset(i);

}

 《DirectX 9.0 3D 游戏开发编程基础》笔记

江西理工大学 FangSH 2010-5-3

posted @ 2010-05-03 11:15  xyecho  阅读(...)  评论(... 编辑 收藏