• <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)鏈接

            搜索

            最新評論

            欧美日韩精品久久久久 | 精品久久久久中文字幕日本| 国产精品成人久久久| 国内精品人妻无码久久久影院导航| 成人综合久久精品色婷婷| 无码人妻久久一区二区三区免费丨 | 日韩精品国产自在久久现线拍| a级毛片无码兔费真人久久| 热综合一本伊人久久精品| 久久国产亚洲精品无码| 精品视频久久久久| 久久久精品人妻一区二区三区蜜桃| 国产精品久久久久一区二区三区| 一本久久a久久精品亚洲| 欧美久久久久久精选9999| 国产婷婷成人久久Av免费高清| 久久AAAA片一区二区| 97久久精品国产精品青草| 亚洲人成电影网站久久| 亚洲国产精品久久久久网站| 亚洲va久久久噜噜噜久久天堂| 久久久久国产精品嫩草影院| 国内精品久久九九国产精品| 午夜天堂精品久久久久| 中文字幕无码久久久| 久久成人18免费网站| 国产精品美女久久久久网| 久久偷看各类wc女厕嘘嘘| 久久99久久99精品免视看动漫 | 久久精品一区二区三区AV| 久久99精品久久久久久9蜜桃| 国产精品禁18久久久夂久| 国产成人精品综合久久久久| 一本久道久久综合狠狠躁AV| 久久男人AV资源网站| 亚洲国产成人精品女人久久久 | 青春久久| 久久中文字幕视频、最近更新| 久久不见久久见免费影院www日本| 爱做久久久久久| 亚洲国产精品婷婷久久|