• <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>

            天行健 君子當(dāng)自強而不息

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

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

            這個類的定義和實現(xiàn)分別位于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();
            };

             

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

            第一類是構(gòu)造和析構(gòu)函數(shù),函數(shù)CDXUTMesh()和~CDXUTMesh()分別是該類的構(gòu)造函數(shù)和析構(gòu)函數(shù),其作用分別是進行一些初始化工作以及在類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();
            }

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

            LPD3DXMESH GetMesh() { return m_pMesh; }

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

            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;
            }

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

            來看第一個Create()函數(shù)的實現(xiàn):

            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;
            }

             

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

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

                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;
            }

            接著調(diào)用OptimizeInplace()對網(wǎng)格模型進行優(yōu)化,該函數(shù)調(diào)用時第一個參數(shù)的含義如下:

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

            D3DXMESHOPT_ATTRSORT — 根據(jù)屬性給三角形排序并調(diào)整屬性表,這將使DrawSubset執(zhí)行更有效。

            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;
            }

            接下來,函數(shù)將模型文件所在的路徑存儲在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';

            接下來,函數(shù)調(diào)用CreateMaterials()創(chuàng)建存儲材質(zhì)和紋理的內(nèi)存,并釋放鄰接信息緩存和材質(zhì)緩存。

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

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

                // 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 閱讀(1246) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評論

            97超级碰碰碰碰久久久久| 嫩草影院久久国产精品| 久久婷婷五月综合97色直播| 女人高潮久久久叫人喷水| 99久久这里只精品国产免费| 久久久久亚洲AV无码永不| 国产A级毛片久久久精品毛片| 色综合久久天天综线观看| 狠狠88综合久久久久综合网| 久久精品国产99久久香蕉| 久久久久99精品成人片直播| 亚洲国产精品一区二区久久| 久久久久久精品无码人妻| 99热精品久久只有精品| 亚洲乱码中文字幕久久孕妇黑人| 2020最新久久久视精品爱| 人妻精品久久无码专区精东影业| 久久99精品国产麻豆蜜芽| 久久久久无码精品国产| 久久无码专区国产精品发布| 久久精品无码一区二区三区免费| avtt天堂网久久精品| 欧美日韩精品久久久久| 亚洲а∨天堂久久精品9966| 99久久久久| 91精品国产91久久久久久| AV无码久久久久不卡蜜桃| 久久亚洲精品人成综合网| 99久久精品免费看国产一区二区三区 | 亚洲色欲久久久综合网| 久久精品中文字幕第23页| 国产精品va久久久久久久| 青青草国产成人久久91网| avtt天堂网久久精品| 精品久久久久久成人AV| 亚洲av日韩精品久久久久久a| 中文国产成人精品久久亚洲精品AⅤ无码精品| 狠狠色丁香久久婷婷综| 国产A级毛片久久久精品毛片| 国产精品欧美久久久久天天影视| 国产精品一区二区久久精品无码 |