• <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)自強(qiáng)而不息

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

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

            這個(gè)類的定義和實(shí)現(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ù),其作用分別是進(jìn)行一些初始化工作以及在類CDXUTMesh的對(duì)象被銷毀時(shí)完成最后的銷毀工作。

            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ù),它僅包含一個(gè)函數(shù)GetMesh(),實(shí)現(xiàn)也非常簡(jiǎn)單,即返回類CDXUTMesh的成員變量m_pMesh。

            LPD3DXMESH GetMesh() { return m_pMesh; }

            第三類是設(shè)備恢復(fù)和丟失時(shí)所采取的操作函數(shù),這里所包含的兩個(gè)成員函數(shù)RestoreDeviceObjects()和InvalidateDeviceObjects()分別是在設(shè)備恢復(fù)和丟失時(shí)調(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個(gè)創(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()用來(lái)在程序退出時(shí)銷毀指定的資源。

            來(lái)看第一個(gè)Create()函數(shù)的實(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()通過(guò)文件名查找文件所在的路徑,接著調(diào)用D3DXLoadMeshFromXW()從文件中加載網(wǎng)格模型。

            DXUTFindDXSDKMediaFileCch()的實(shí)現(xiàn)分析請(qǐng)參閱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()對(duì)網(wǎng)格模型進(jìn)行優(yōu)化,該函數(shù)調(diào)用時(shí)第一個(gè)參數(shù)的含義如下:

            D3DXMESHOPT_COMPACT — 從mesh中移除沒有用的頂點(diǎn)和索引項(xiàng)。

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

            D3DXMESHOPT_VERTEXCACHE — 增加頂點(diǎn)緩存的命中率。

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

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

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

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

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

                // 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) 評(píng)論(0)  編輯 收藏 引用


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


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

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

            搜索

            最新評(píng)論

            色综合久久久久| 色综合久久无码中文字幕| 久久综合亚洲色HEZYO社区| 精品久久久久久国产三级| 久久人人超碰精品CAOPOREN | 国产精品99久久久久久人| 91久久香蕉国产熟女线看| 久久亚洲sm情趣捆绑调教| 欧美噜噜久久久XXX| 久久一区二区免费播放| 久久亚洲AV成人出白浆无码国产| 久久综合综合久久狠狠狠97色88 | 精品久久久久国产免费| 久久精品国产日本波多野结衣| 久久久国产一区二区三区| 久久精品卫校国产小美女| 久久青青草原精品影院| 久久精品中文字幕一区| 久久久久人妻精品一区三寸蜜桃| 久久久无码人妻精品无码| 2020久久精品亚洲热综合一本| 中文字幕亚洲综合久久| 久久99精品国产麻豆| 77777亚洲午夜久久多人| 狠狠色综合久久久久尤物| 97超级碰碰碰久久久久| 亚洲AV日韩精品久久久久久久| 久久久久久国产精品美女| 91久久成人免费| 国产精品久久久久影院色| 久久久久久亚洲AV无码专区| 超级碰碰碰碰97久久久久| 久久久国产一区二区三区| 久久午夜无码鲁丝片午夜精品| 久久久久久狠狠丁香| 久久99国产精品99久久| 2020久久精品国产免费| 99久久免费国产特黄| 久久狠狠高潮亚洲精品| 国产精品视频久久久| 久久99精品久久久久久|