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

            久久久久久久久久久久久久| 国产毛片欧美毛片久久久| 久久午夜无码鲁丝片| 中文字幕久久久久人妻| 久久男人Av资源网站无码软件| 久久久老熟女一区二区三区| 久久综合久久综合九色| 日韩一区二区久久久久久 | 中文字幕乱码人妻无码久久| 久久久久99精品成人片试看| 伊人热人久久中文字幕| 精品久久久中文字幕人妻| 91精品国产综合久久婷婷| 青青青青久久精品国产h久久精品五福影院1421| 热久久国产欧美一区二区精品| 久久久久亚洲av成人网人人软件| 丰满少妇高潮惨叫久久久| 亚洲性久久久影院| 久久r热这里有精品视频| 亚洲午夜福利精品久久| 久久精品国产99国产精品澳门| 伊人久久大香线蕉亚洲| 久久亚洲精品国产精品婷婷| 99久久国产综合精品五月天喷水| 亚洲精品无码久久久影院相关影片| 久久久久久国产精品免费免费| 国产精品久久精品| 99久久无色码中文字幕人妻| 要久久爱在线免费观看| 99热热久久这里只有精品68| 久久se精品一区二区| 精品久久一区二区三区| 国产婷婷成人久久Av免费高清| 精品国产乱码久久久久软件| A级毛片无码久久精品免费| 亚洲午夜无码久久久久小说| 久久强奷乱码老熟女网站| 国产精品99久久不卡| 9999国产精品欧美久久久久久 | 久久99国产精品久久久| 91精品国产91久久综合|