zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    从有序的数组中查找某个值
    OJ 21658::Monthly Expense(二分搜索+最小化最大值)
    OJ 21651::Cow Hurdles(佛罗一德的变式)
    Oj 24260: Lilypad Pond (神奇广搜题,状态搜索)
    MongoDB常用语句
    MongoDB可视化工具之mongoBooster
    MongoDB的安装,mongod和mongo的区别
    数组遍历及其他方法
    MongoDB的安装与卸载与再安装
    MongoDB下载安装步骤+文件解析
  • 原文地址:https://www.cnblogs.com/fangshenghui/p/1726285.html
Copyright © 2011-2022 走看看