新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     >>计算机科学论坛<<     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → 网格模型高级技术(2) 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 26855 个阅读者浏览上一篇主题  刷新本主题   平板显示贴子 浏览下一篇主题
     * 贴子主题: 网格模型高级技术(2) 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 网格模型高级技术(2)

    层次细节网格模型(progress mesh)是一种特殊的网格模型,它的顶点数据以树状形式组织,可以随意增加或降低模型的复杂程度,从而比普通的网格模型具有更大的灵活性,层次细节网格模型对于层次细节场景的渲染非常理想。当模型距离观察者较远时可以降低模型的复杂程度,提高渲染速度。而当模型距离观察者较近时可以使用复杂的模型,从而提高视觉效果。Direct3D用ID3DXPMesh来表示层次细节网格模型对象,而不是ID3DXMesh。

    层次细节网格模型是根据原始普通网格模型生成的,在生成层次细节网格模型之前,首先需要对原始网格模型进行相关处理,包括整理、顶点融合、检查3个步骤。

    在调用函数D3DXLoadMeshFromX()生成网格模型后,调用Direct3D功能函数D3DXCleanMesh()对初始网格模型进行整理,其声明如下:

    Cleans a mesh, preparing it for simplification.

    HRESULT D3DXCleanMesh(  D3DXCLEANTYPE CleanType,  LPD3DXMESH pMeshIn,  CONST DWORD * pAdjacencyIn,  LPD3DXMESH * ppMeshOut,  DWORD * pAdjacencyOut,  LPD3DXBUFFER * ppErrorsAndWarnings);
    Parameters
    CleanType
    [in] Vertex operations to perform in preparation for mesh cleaning.
    pMeshIn
    [in] Pointer to an ID3DXMesh interface, representing the mesh to be cleaned.
    pAdjacencyIn
    [in] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the mesh to be cleaned.
    ppMeshOut
    [out] Address of a pointer to an ID3DXMesh interface, representing the returned cleaned mesh. The same mesh is returned that was passed in if no cleaning was necessary.
    pAdjacencyOut
    [out] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the output mesh.
    ppErrorsAndWarnings
    [out] Returns a buffer containing a string of errors and warnings, which explain the problems found in the mesh.
    Return Values
    If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following: D3DERR_INVALIDCALL, E_OUTOFMEMORY.

    Remarks
    This function cleans a mesh using the cleaning method and options specified in the CleanType parameter. See the D3DXCLEANTYPE enumeration for a description of the available options.

    枚举常量D3DXCLEANTYPE的定义如下:

    Defines operations to perform on vertices in preparation for mesh cleaning.

    typedef enum D3DXCLEANTYPE{    D3DXCLEAN_BACKFACING = 1,    D3DXCLEAN_BOWTIES = 2,    D3DXCLEAN_SKINNING = D3DXCLEAN_BACKFACING,    D3DXCLEAN_OPTIMIZATION = D3DXCLEAN_BACKFACING,    D3DXCLEAN_SIMPLIFICATION = D3DXCLEAN_BACKFACING | D3DXCLEAN_BOWTIES,} D3DXCLEANTYPE, *LPD3DXCLEANTYPE;
    Constants
    D3DXCLEAN_BACKFACING
    Merge triangles that share the same vertex indices but have face normals pointing in opposite directions (back-facing triangles). Unless the triangles are not split by adding a replicated vertex, mesh adjacency data from the two triangles may conflict.
    D3DXCLEAN_BOWTIES
    If a vertex is the apex of two triangle fans (a bowtie) and mesh operations will affect one of the fans, then split the shared vertex into two new vertices. Bowties can cause problems for operations such as mesh simplification that remove vertices, because removing one vertex affects two distinct sets of triangles.
    D3DXCLEAN_SKINNING
    Use this flag to prevent infinite loops during skinning setup mesh operations.
    D3DXCLEAN_OPTIMIZATION
    Use this flag to prevent infinite loops during mesh optimization operations.
    D3DXCLEAN_SIMPLIFICATION
    Use this flag to prevent infinite loops during mesh simplification operations.
    通常选择D3DXCLEAN_SIMPLIFICATION,这样既可以将共享相同顶点且面法向量不在同一方向的三角形进行合并,同时还可以避免在简化网格的操作中陷入死循环。

    在整理好网格模型后,调用函数D3DXWeldVertices()将网格模型中属性相同的重复顶点溶合到一起,从而简化网格模型,其声明如下:

    Welds together replicated vertices that have equal attributes. This method uses specified epsilon values for equality comparisons.

    HRESULT D3DXWeldVertices(  LPD3DXMESH pMesh,  DWORD Flags,  CONST D3DXWeldEpsilons * pEpsilons,  CONST DWORD * pAdjacencyIn,  DWORD * pAdjacencyOut,  DWORD * pFaceRemap,  LPD3DXBUFFER * ppVertexRemap);
    Parameters
    pMesh
    [in] Pointer to an ID3DXMesh object, the mesh from which to weld vertices.
    Flags
    [in] Combination of one or more flags from D3DXWeldEpsilonsFLAGS.
    pEpsilons
    [in] Pointer to a D3DXWeldEpsilons structure, specifying the epsilon values to be used for this method. Use NULL to initialize all structure members to a default value of 1.0e-6f.
    pAdjacencyIn
    [in] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the source mesh. If the edge has no adjacent faces, the value is 0xffffffff. If this parameter is set to NULL, ID3DXBaseMesh::GenerateAdjacency will be called to create logical adjacency information.
    pAdjacencyOut
    [in, out] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the optimized mesh. If the edge has no adjacent faces, the value is 0xffffffff.
    pFaceRemap
    [out] An array of DWORDs, one per face, that identifies the original mesh face that corresponds to each face in the welded mesh.
    ppVertexRemap
    [out] Address of a pointer to an ID3DXBuffer interface, which contains a DWORD for each vertex that specifies how the new vertices map to the old vertices. This remap is useful if you need to alter external data based on the new vertex mapping.
    Return Values
    If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following: D3DERR_INVALIDCALL, E_OUTOFMEMORY.

    Remarks
    This function uses supplied adjacency information to determine the points that are replicated. Vertices are merged based on an epsilon comparison. Vertices with equal position must already have been calculated and represented by point-representative data.

    This function combines logically-welded vertices that have similar components, such as normals or texture coordinates within pEpsilons.

    The following example code calls this function with welding enabled. Vertices are compared using epsilon values for normal vector and vertex position. A pointer is returned to a face remapping array (pFaceRemap).

    TCHAR            strMediaPath[512];       // X-file path LPD3DXBUFFER     pAdjacencyBuffer = NULL; // adjacency data bufferLPD3DXBUFFER     pD3DXMtrlBuffer  = NULL; // material bufferLPD3DXMESH       pMesh            = NULL; // mesh objectDWORD            m_dwNumMaterials;        // number of materialsD3DXWELDEPSILONS Epsilons;                // structure with epsilon valuesDWORD            *pFaceRemap[65536];      // face remapping arrayDWORD            i;                       // internal variable        // Load the mesh from the specified file    hr = D3DXLoadMeshFromX ( strMediaPath,                         D3DXMESH_MANAGED,                         m_pd3dDevice,                         &pAdjacencyBuffer,                         &pD3DXMtrlBuffer,                         NULL,                         &m_dwNumMaterials,                         &pMesh ) )                                 if( FAILED( hr ) )       goto End;              // Go to error handling        // Set epsilon values    Epsilons.Normal = 0.001;    Epsilons.Position = 0.1;        // Weld the vertices    for( i=0; i < 65536; i++ )    {         pFaceRemap[i] = 0;     }        hr = D3DXWeldVertices ( pMesh,                            D3DXWELDEPSILONS_WELDPARTIALMATCHES,                            &Epsilons,                            (DWORD*)pAdjacencyBuffer->GetBufferPointer(),                            (DWORD*)pAdjacencyBuffer->GetBufferPointer(),                            (DWORD*)pFaceRemap,                            NULL )                                if( FAILED( hr ) )       goto End;              // Go to error handling
    D3DXWeldEpsilonsFLAGS的定义如下:

    Options for welding together vertices.

    typedef enum D3DXWeldEpsilonsFLAGS{    D3DXWeldEpsilons_WELDALL = 1,    D3DXWeldEpsilons_WELDPARTIALMATCHES = 2,    D3DXWeldEpsilons_DONOTREMOVEVERTICES = 4,    D3DXWeldEpsilons_DONOTSPLIT = 8,} D3DXWeldEpsilonsFLAGS, *LPD3DXWeldEpsilonsFLAGS;
    Constants
    D3DXWeldEpsilons_WELDALL
    Weld together all vertices that are at the same location. Using this flag avoids an epsilon comparison between vertex components.
    D3DXWeldEpsilons_WELDPARTIALMATCHES
    If a given vertex component is within epsilon, modify partially matched vertices so that both components are identical. If all components are equal, remove one of the vertices.
    D3DXWeldEpsilons_DONOTREMOVEVERTICES
    Instructs the weld to allow only modifications to vertices and not removal. This flag is valid only if D3DXWeldEpsilons_WELDPARTIALMATCHES is set. It is useful to modify vertices to be equal, but not to allow vertices to be removed.
    D3DXWeldEpsilons_DONOTSPLIT
    Instructs the weld not to split vertices that are in separate attribute groups. When the ID3DXMesh::Optimize, ID3DXPMesh::Optimize, or ID3DXPMesh::OptimizeBaseLOD methods are called with the D3DXMESHOPT_ATTRSORT flag, then the D3DXMESHOPT_DONOTSPLIT flag will also be set. Setting this flag can slow down software vertex processing.
    D3DXWeldEpsilons的定义如下:

    Specifies tolerance values for each vertex component when comparing vertices to determine if they are similar enough to be welded together.

    typedef struct D3DXWeldEpsilons {    FLOAT Position;    FLOAT BlendWeights;    FLOAT Normal;    FLOAT PSize;    FLOAT Specular;    FLOAT Diffuse;    FLOAT Texcoord[8];    FLOAT Tangent;    FLOAT Binormal;    FLOAT Tess Factor;} D3DXWeldEpsilons, *LPD3DXWeldEpsilons;
    Members
    Position
    Position
    BlendWeights
    Blend weight
    Normal
    Normal
    PSize
    Point size value
    Specular
    Specular lighting value
    Diffuse
    Diffuse lighting value
    Texcoord
    Eight texture coordinates
    Tangent
    Tangent
    Binormal
    Binormal
    Tess Factor
    Tessellation factor
    Remarks
    The LPD3DXWeldEpsilons type is defined as a pointer to the D3DXWeldEpsilons structure.

    typedef D3DXWELDEPSILONS *LPD3DXWELDEPSILONS;
    对原始网格模型进行整理、简化之后,还需要检查处理后的网格模型是否有效,检查工作由函数D3DXValidMesh()完成,其声明如下:

    Validates a mesh.

    HRESULT D3DXValidMesh(  LPD3DXMESH pMeshIn,  CONST DWORD * pAdjacency,  LPD3DXBUFFER * ppErrorsAndWarnings);
    Parameters
    pMeshIn
    [in] Pointer to an ID3DXMesh interface, representing the mesh to be tested.
    pAdjacency
    [in] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the mesh to be tested.
    ppErrorsAndWarnings
    [out] Returns a buffer containing a string of errors and warnings, which explain the problems found in the mesh.
    Return Values
    If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following: D3DXERR_INVALIDMESH, D3DERR_INVALIDCALL, E_OUTOFMEMORY.

    Remarks
    This method validates the mesh by checking for invalid indices. Error information is available from the debugger output.

    在上面的准备工作完成后,可以调用函数D3DXGeneratePMesh()根据初始网格模型生成层次细节网格模型,其声明如下:

    Generates a progressive mesh.

    HRESULT D3DXGeneratePMesh(  LPD3DXMESH pMesh,  CONST DWORD * pAdjacency,  CONST D3DXATTRIBUTEWEIGHTS * pVertexAttributeWeights,  CONST FLOAT * pVertexWeights,  DWORD MinValue,  DWORD Options,  LPD3DXPMESH * ppPMesh);
    Parameters
    pMesh
    [in] Pointer to an ID3DXMesh interface, representing the source mesh.
    pAdjacency
    [in] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the created progressive mesh.
    pVertexAttributeWeights
    [in] Pointer to a D3DXATTRIBUTEWEIGHTS structure, containing the weight for each vertex component. If this parameter is set to NULL, a default structure is used. See Remarks.
    pVertexWeights
    [in] Pointer to an array of vertex weights. If this parameter is set to NULL, all vertex weights are set to 1.0. Note that the higher the vertex weight for a given vertex, the less likely it is to be simplified away.
    MinValue
    [in] Number of vertices or faces, depending on the flag set in the Options parameter, by which to simplify the source mesh.
    Options
    [in] Specifies simplification options for the mesh. One flag from the D3DXMESHSIMP enumeration can be set.
    ppPMesh
    [out] Address of a pointer to an ID3DXPMesh interface, representing the created progressive mesh.
    Return Values
    If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following: D3DXERR_CANNOTATTRSORT, D3DERR_INVALIDCALL, E_OUTOFMEMORY.

    Remarks
    This function generates a mesh where the level of detail (LOD) can be adjusted from the current value to the MinValue.

    If the simplification process cannot reduce the mesh to MinValue, the call still succeeds because MinValue is a desired minimum, not an absolute minimum.

    If pVertexAttributeWeights is set to NULL, the following values are assigned to the default D3DXATTRIBUTEWEIGHTS structure.

    D3DXATTRIBUTEWEIGHTS AttributeWeights;    AttributeWeights.Position  = 1.0;AttributeWeights.Boundary =  1.0;AttributeWeights.Normal   =  1.0;AttributeWeights.Diffuse  =  0.0;AttributeWeights.Specular =  0.0;AttributeWeights.Tex[8]   =  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
    This default structure is what most applications should use because it considers only geometric and normal adjustment. Only in special cases will the other member fields need to be modified.

    D3DXMESHSIMP的定义如下:

    Specifies simplification options for a mesh.

    typedef enum D3DXMESHSIMP{    D3DXMESHSIMP_VERTEX = 1,    D3DXMESHSIMP_FACE = 2,} D3DXMESHSIMP, *LPD3DXMESHSIMP;
    Constants
    D3DXMESHSIMP_VERTEX
    The mesh will be simplified by the number of vertices specified in the MinValue parameter.
    D3DXMESHSIMP_FACE
    The mesh will be simplified by the number of faces specified in the MinValue parameter.
    参数MinValue设置的最小顶点数只是一个期望值,实际生成的层次细节网格模型的最小顶点数量可能大于设置的最小顶点数量。

    示例程序ProgressMesh的具体实现

    示例程序演示了层次细节网格模型的生成和渲染,其中加载原始网格模型、简化熔合原始网格并生成层次细节网格模型的代码如下:

    ID3DXBuffer* material_buffer;
    V_RETURN(D3DXLoadMeshFromXW(L"Dwarf.x", D3DXMESH_MANAGED, pd3dDevice, &g_adj_buffer, &material_buffer, NULL,       &g_num_materials, &g_mesh));
    D3DXMATERIAL* xmaterials = (D3DXMATERIAL*) material_buffer->GetBufferPointer();g_mesh_materials = new D3DMATERIAL9[g_num_materials];g_mesh_textures  = new IDirect3DTexture9*[g_num_materials];
    for(DWORD i = 0; i < g_num_materials; i++){ g_mesh_materials[i] = xmaterials[i].MatD3D; g_mesh_materials[i].Ambient = g_mesh_materials[i].Diffuse;
     WCHAR wfilename[256]; RemovePathFromFileName(xmaterials[i].pTextureFilename, wfilename);
     g_mesh_textures[i] = NULL;
     if(xmaterials[i].pTextureFilename != NULL && lstrlen(wfilename) > 0) {  V_RETURN(D3DXCreateTextureFromFileW(pd3dDevice, wfilename, &g_mesh_textures[i])); }}
    material_buffer->Release();
    ID3DXMesh* cleaned_mesh;DWORD* adj = (DWORD*) g_adj_buffer->GetBufferPointer();
    V_RETURN(D3DXCleanMesh(D3DXCLEAN_SIMPLIFICATION, g_mesh, adj, &cleaned_mesh, adj, NULL));release_com(g_mesh);
    g_mesh = cleaned_mesh;
    D3DXWELDEPSILONS weld_epsilons;ZeroMemory(&weld_epsilons, sizeof(D3DXWELDEPSILONS));V_RETURN(D3DXWeldVertices(g_mesh, D3DXWELDEPSILONS_WELDPARTIALMATCHES, &weld_epsilons, adj, adj, NULL, NULL));
    V_RETURN(D3DXValidMesh(g_mesh, adj, NULL));V_RETURN(D3DXGeneratePMesh(g_mesh, adj, NULL, NULL, 1, D3DXMESHSIMP_VERTEX, &g_progress_mesh));

    运行效果图:

    按此在新窗口浏览图片


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/12/18 9:46:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2026/3/6 14:33:01

    本主题贴数10,分页: [1]

     *树形目录 (最近20个回帖) 顶端 
    主题:  网格模型高级技术(2)(16162字) - 卷积内核,2008年12月18日
        回复:  好啊我收藏了啊(16字) - 秋十三,2009年1月2日
        回复:  好啊我收藏了啊(16字) - 秋十三,2009年1月2日
        回复:  类CDXUTMesh的详细说明请参阅[URL=http://ieee.org.cn/dispyyy..(15493字) - 卷积内核,2008年12月18日
        回复:  主程序:#include "dxstdafx.h"#include "resource.h..(17624字) - 卷积内核,2008年12月18日
        回复:  渐变(tweening)网格模型是Direct3D中实现模型动画最简单的方式和途径,它的原理也非常..(4292字) - 卷积内核,2008年12月18日
        回复:  主程序:#include "dxstdafx.h"#include "resource.h..(17177字) - 卷积内核,2008年12月18日
        回复:  增强网格模型是运行镶嵌技术将原始网格模型的三角形面进行细分,形成更加精细(三角形面更多)的网格模型..(3489字) - 卷积内核,2008年12月18日
            回复:  啥也不说了,眼泪哗哗的,太好了,学习的极好资料。(33字) - dungeonsnd,2009年3月10日
        回复:  主程序:#include "dxstdafx.h"#include "resource.h..(17235字) - 卷积内核,2008年12月18日

    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    199.219ms