• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當自強而不息

            DXUT源碼分析 ---- 類CDXUTMesh(1)

            類CDXUTMesh主要用于從一個指定的網格模型中加載數據、渲染模型以及銷毀網格模型,它將整個網格模型作為一個整體進行操作,沒有考慮網格模型內部的框架層次,對于不包含動畫信息的網格模型,使用該類是一個比較好的選擇。

            這個類的定義和實現分別位于DXUTMesh.h和DXUTMesh.cpp中,其定義如下:

            //-----------------------------------------------------------------------------
            // Name: class CDXUTMesh
            // Desc: Class for loading and rendering file-based meshes
            //-----------------------------------------------------------------------------
            class CDXUTMesh
            {
            public:
                WCHAR                            m_strName[
            512];
                LPD3DXMESH                        m_pMesh;   
            // Managed mesh
                
                
            // Cache of data in m_pMesh for easy access

                IDirect3DVertexBuffer9
            *            m_pVB;
                IDirect3DIndexBuffer9
            *            m_pIB;
                IDirect3DVertexDeclaration9
            *    m_pDecl;
                DWORD                           m_dwNumVertices;
                DWORD                           m_dwNumFaces;
                DWORD                           m_dwBytesPerVertex;

                DWORD                           m_dwNumMaterials; 
            // Materials for the mesh
                D3DMATERIAL9*                   m_pMaterials;
                CHAR                            (
            *m_strMaterials)[MAX_PATH];
                IDirect3DBaseTexture9
            **         m_pTextures;
                
            bool                            m_bUseMaterials;

            public:
                
            // Rendering
                HRESULT Render( LPDIRECT3DDEVICE9 pd3dDevice, 
                                
            bool bDrawOpaqueSubsets = true,
                                
            bool bDrawAlphaSubsets = true );

                HRESULT Render( ID3DXEffect 
            *pEffect,
                                D3DXHANDLE hTexture 
            = NULL,
                                D3DXHANDLE hDiffuse 
            = NULL,
                                D3DXHANDLE hAmbient 
            = NULL,
                                D3DXHANDLE hSpecular 
            = NULL,
                                D3DXHANDLE hEmissive 
            = NULL,
                                D3DXHANDLE hPower 
            = NULL,
                                
            bool bDrawOpaqueSubsets = true,
                                
            bool bDrawAlphaSubsets = true );

                
            // Mesh access
                LPD3DXMESH GetMesh() { return m_pMesh; }

                
            // Rendering options
                void    UseMeshMaterials( bool bFlag ) { m_bUseMaterials = bFlag; }
                HRESULT SetFVF( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwFVF );
                HRESULT SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, 
            const D3DVERTEXELEMENT9 *pDecl, 
                                       
            bool bAutoComputeNormals = truebool bAutoComputeTangents = true
                                       
            bool bSplitVertexForOptimalTangents = false );

                
            // Initializing
                HRESULT RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice );
                HRESULT InvalidateDeviceObjects();

                
            // Creation/destruction
                HRESULT Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename );
                HRESULT Create( LPDIRECT3DDEVICE9 pd3dDevice, LPD3DXFILEDATA pFileData );
                HRESULT Create(LPDIRECT3DDEVICE9 pd3dDevice, ID3DXMesh
            * pInMesh, D3DXMATERIAL* pd3dxMaterials, DWORD dwMaterials);

                HRESULT CreateMaterials(LPCWSTR strPath, IDirect3DDevice9 
            *pd3dDevice, 
                                        D3DXMATERIAL
            * d3dxMtrls, DWORD dwNumMaterials);
                HRESULT Destroy();

                CDXUTMesh( LPCWSTR strName 
            = L"CDXUTMeshFile_Mesh" );
                
            virtual ~CDXUTMesh();
            };

             

            該類中包含的成員函數按其作用可分為6類。

            第一類是構造和析構函數,函數CDXUTMesh()和~CDXUTMesh()分別是該類的構造函數和析構函數,其作用分別是進行一些初始化工作以及在類CDXUTMesh的對象被銷毀時完成最后的銷毀工作。

            CDXUTMesh::CDXUTMesh( LPCWSTR strName )
            {
            StringCchCopy( m_strName, 512, strName );
                m_pMesh              = NULL;
            m_pMaterials = NULL;
            m_pTextures = NULL;
            m_bUseMaterials = TRUE;
            m_pVB = NULL;
            m_pIB = NULL;
            m_pDecl = NULL;
            m_strMaterials = NULL;
            m_dwNumMaterials = 0;
            m_dwNumVertices = 0;
            m_dwNumFaces = 0;
            m_dwBytesPerVertex = 0;
            }
            CDXUTMesh::~CDXUTMesh()
            {
            Destroy();
            }

            第二類是獲取網格函數,它僅包含一個函數GetMesh(),實現也非常簡單,即返回類CDXUTMesh的成員變量m_pMesh。

            LPD3DXMESH GetMesh() { return m_pMesh; }

            第三類是設備恢復和丟失時所采取的操作函數,這里所包含的兩個成員函數RestoreDeviceObjects()和InvalidateDeviceObjects()分別是在設備恢復和丟失時調用,用于恢復和釋放相應的資源。

            HRESULT CDXUTMesh::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )
            {
            return S_OK;
            }
            HRESULT CDXUTMesh::InvalidateDeviceObjects()
            {
            SAFE_RELEASE( m_pIB );
            SAFE_RELEASE( m_pVB );
            SAFE_RELEASE( m_pDecl );
                return S_OK;
            }

            第四類是創建和銷毀函數,這里首先重載了3個創建網格模型函數Create(),它們依次用于從指定的.x文件創建網格模型,從接口ID3DXFileData創建網格模型,從輸入的網格模型中創建新的網格模型。函數CreateMaterials()用于創建網格模型中所需的材質和紋理。函數Destroy()用來在程序退出時銷毀指定的資源。

            來看第一個Create()函數的實現:

            HRESULT CDXUTMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename )
            {
                WCHAR        strPath[MAX_PATH];
                LPD3DXBUFFER pAdjacencyBuffer 
            = NULL;
                LPD3DXBUFFER pMtrlBuffer 
            = NULL;
                HRESULT      hr;

                
            // Cleanup previous mesh if any
                Destroy();

                
            // Find the path for the file, and convert it to ANSI (for the D3DX API)
                DXUTFindDXSDKMediaFileCch( strPath, sizeof(strPath) / sizeof(WCHAR), strFilename );

                
            // Load the mesh
                if(FAILED(hr = D3DXLoadMeshFromXW(strPath, D3DXMESH_MANAGED, pd3dDevice, &pAdjacencyBuffer, &pMtrlBuffer, NULL,
                                                  
            &m_dwNumMaterials, &m_pMesh)))
                {
                    
            return hr;
                }

                
            // Optimize the mesh for performance
                if( FAILED( hr = m_pMesh->OptimizeInplace(
                                    D3DXMESHOPT_COMPACT 
            | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
                                    (DWORD
            *) pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL)))
                {
                    SAFE_RELEASE( pAdjacencyBuffer );
                    SAFE_RELEASE( pMtrlBuffer );
                    
            return hr;
                }

                
            // Set strPath to the path of the mesh file

                WCHAR
            * pLastBSlash = wcsrchr( strPath, L'\\' );

                
            if( pLastBSlash )
                    
            *(pLastBSlash + 1= L'\0';
                
            else
                    
            *strPath = L'\0';

                D3DXMATERIAL
            * d3dxMtrls = (D3DXMATERIAL*) pMtrlBuffer->GetBufferPointer();
                hr 
            = CreateMaterials( strPath, pd3dDevice, d3dxMtrls, m_dwNumMaterials );

                SAFE_RELEASE( pAdjacencyBuffer );
                SAFE_RELEASE( pMtrlBuffer );

                
            // Extract data from m_pMesh for easy access

                D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];

                m_dwNumVertices    
            = m_pMesh->GetNumVertices();
                m_dwNumFaces       
            = m_pMesh->GetNumFaces();
                m_dwBytesPerVertex 
            = m_pMesh->GetNumBytesPerVertex();

                m_pMesh
            ->GetIndexBuffer( &m_pIB );
                m_pMesh
            ->GetVertexBuffer( &m_pVB );
                m_pMesh
            ->GetDeclaration( decl );

                pd3dDevice
            ->CreateVertexDeclaration( decl, &m_pDecl );

                
            return hr;
            }

             

            函數首先銷毀舊的資源,并調用DXUTFindDXSDKMediaFileCch()通過文件名查找文件所在的路徑,接著調用D3DXLoadMeshFromXW()從文件中加載網格模型。

            DXUTFindDXSDKMediaFileCch()的實現分析請參閱DXUT源碼分析 ---- 媒體文件查找函數

                WCHAR        strPath[MAX_PATH];
            LPD3DXBUFFER pAdjacencyBuffer = NULL;
            LPD3DXBUFFER pMtrlBuffer = NULL;
            HRESULT hr;
                // Cleanup previous mesh if any
            Destroy();
                // Find the path for the file, and convert it to ANSI (for the D3DX API)
            DXUTFindDXSDKMediaFileCch( strPath, sizeof(strPath) / sizeof(WCHAR), strFilename );
                // Load the mesh
            if(FAILED(hr = D3DXLoadMeshFromXW(strPath, D3DXMESH_MANAGED, pd3dDevice, &pAdjacencyBuffer, &pMtrlBuffer, NULL,
            &m_dwNumMaterials, &m_pMesh)))
            {
            return hr;
            }

            接著調用OptimizeInplace()對網格模型進行優化,該函數調用時第一個參數的含義如下:

            D3DXMESHOPT_COMPACT — 從mesh中移除沒有用的頂點和索引項。

            D3DXMESHOPT_ATTRSORT — 根據屬性給三角形排序并調整屬性表,這將使DrawSubset執行更有效。

            D3DXMESHOPT_VERTEXCACHE — 增加頂點緩存的命中率。

               // Optimize the mesh for performance
            if( FAILED( hr = m_pMesh->OptimizeInplace(
            D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
            (DWORD*) pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL)))
            {
            SAFE_RELEASE( pAdjacencyBuffer );
            SAFE_RELEASE( pMtrlBuffer );
            return hr;
            }

            接下來,函數將模型文件所在的路徑存儲在strPath,如果沒有路徑,則strPath置為NULL。

               // Set strPath to the path of the mesh file
                WCHAR* pLastBSlash = wcsrchr( strPath, L'\\' );
                if( pLastBSlash )
            *(pLastBSlash + 1) = L'\0';
            else
            *strPath = L'\0';

            接下來,函數調用CreateMaterials()創建存儲材質和紋理的內存,并釋放鄰接信息緩存和材質緩存。

                D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*) pMtrlBuffer->GetBufferPointer();
            hr = CreateMaterials( strPath, pd3dDevice, d3dxMtrls, m_dwNumMaterials );
                SAFE_RELEASE( pAdjacencyBuffer );
            SAFE_RELEASE( pMtrlBuffer );

            最后,函數獲取模型的頂點數,面數,每個頂點所占的字節大小,頂點索引緩存,頂點緩存,頂點聲明,以方便以后訪問。

                // Extract data from m_pMesh for easy access
                m_dwNumVertices    = m_pMesh->GetNumVertices();
            m_dwNumFaces = m_pMesh->GetNumFaces();
            m_dwBytesPerVertex = m_pMesh->GetNumBytesPerVertex();
                m_pMesh->GetIndexBuffer( &m_pIB );
            m_pMesh->GetVertexBuffer( &m_pVB );
            m_pMesh->GetDeclaration( decl );
                pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl );
                return hr;

            posted on 2008-05-31 08:58 lovedday 閱讀(1244) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            久久99精品国产麻豆宅宅| 亚洲国产高清精品线久久| 久久精品久久久久观看99水蜜桃| 无码乱码观看精品久久| 久久精品国产亚洲AV香蕉| 午夜久久久久久禁播电影| 日本免费久久久久久久网站 | 亚洲人成无码网站久久99热国产 | 国产精品久久久久久久久久影院| 国产欧美久久久精品影院| 久久亚洲日韩精品一区二区三区| 国内精品伊人久久久久| 欧美午夜精品久久久久久浪潮| 久久久亚洲AV波多野结衣| 94久久国产乱子伦精品免费| 伊人久久大香线焦AV综合影院| 久久亚洲国产中v天仙www| 久久综合亚洲色HEZYO社区| 久久久久四虎国产精品| 亚洲欧美日韩久久精品第一区| 狠狠久久综合伊人不卡| 99久久久国产精品免费无卡顿 | 精品午夜久久福利大片| 久久九九兔免费精品6| 国产精品免费久久久久电影网| 亚洲国产另类久久久精品小说| 久久久噜噜噜久久中文字幕色伊伊| 青青草原精品99久久精品66| 亚洲午夜精品久久久久久浪潮| 99久久国产综合精品网成人影院 | 99热精品久久只有精品| 91久久婷婷国产综合精品青草 | 美女写真久久影院| 77777亚洲午夜久久多喷| 蜜臀av性久久久久蜜臀aⅴ麻豆| 亚洲欧美日韩久久精品| 亚洲色欲久久久久综合网| 久久免费观看视频| 综合久久一区二区三区 | 久久久久久久久久久久久久| 久久伊人亚洲AV无码网站|