• <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源碼分析 ---- 類CDXUTMeshFrame

            類CDXUTMeshFrame封裝了CDXUTMesh,與CDXUTMesh不同的是,類CDXUTMeshFrame可以包含框架層次結(jié)構(gòu),適用于更復(fù)雜的網(wǎng)格模型,框架層次正是骨骼動(dòng)畫所必須的。

            首先來(lái)看看它的定義:

            //-----------------------------------------------------------------------------
            // Name: class CDXUTMeshFrame
            // Desc: Class for loading and rendering file-based meshes
            //-----------------------------------------------------------------------------
            class CDXUTMeshFrame
            {
            public:
                WCHAR            m_strName[
            512];     // 框架名稱
                D3DXMATRIX        m_mat;               // 框架變換矩陣(相對(duì)于網(wǎng)格模型的原點(diǎn))
                CDXUTMesh*        m_pMesh;           // 指向CDXUTMesh對(duì)象

                CDXUTMeshFrame
            * m_pNext;         // 指向下一個(gè)框架對(duì)象
                CDXUTMeshFrame* m_pChild;         // 指向子框架對(duì)象

            public:
                
            // Matrix access
                void        SetMatrix( D3DXMATRIX* pmat ) { m_mat = *pmat; }
                D3DXMATRIX
            * GetMatrix()                   { return &m_mat; }

                CDXUTMesh
            *         FindMesh( LPCWSTR strMeshName );
                CDXUTMeshFrame
            *  FindFrame( LPCWSTR strFrameName );

                
            bool EnumMeshes( bool (*EnumMeshCB)(CDXUTMesh*void*), void* pContext );

                HRESULT Destroy();
                HRESULT RestoreDeviceObjects(LPDIRECT3DDEVICE9 pd3dDevice);
                HRESULT InvalidateDeviceObjects();

                HRESULT Render( LPDIRECT3DDEVICE9 pd3dDevice, 
                                
            bool bDrawOpaqueSubsets = true,
                                
            bool bDrawAlphaSubsets = true,
                                D3DXMATRIX
            * pmatWorldMatrix = NULL);

                CDXUTMeshFrame( LPCWSTR strName 
            = L"CDXUTMeshFile_Frame" );
                
            virtual ~CDXUTMeshFrame();
            };

             

            構(gòu)造函數(shù)和析構(gòu)函數(shù)只是負(fù)責(zé)初始化數(shù)據(jù)和釋放分配的資源:

            CDXUTMeshFrame::CDXUTMeshFrame( LPCWSTR strName )
            {
            StringCchCopy(m_strName, 512, strName);
                D3DXMatrixIdentity(&m_mat);
                m_pMesh  = NULL;
            m_pChild = NULL;
            m_pNext = NULL;
            }
            CDXUTMeshFrame::~CDXUTMeshFrame()
            {
            SAFE_DELETE( m_pChild );
            SAFE_DELETE( m_pNext );
            }

             

            FindMesh()和FindFrame()是兩個(gè)遞歸查找函數(shù),根據(jù)輸入的網(wǎng)格名稱和框架名稱查找對(duì)應(yīng)的網(wǎng)格和框架:

            CDXUTMesh* CDXUTMeshFrame::FindMesh( LPCWSTR strMeshName )
            {
            CDXUTMesh* pMesh;
                if( m_pMesh )
            if( !lstrcmpi(m_pMesh->m_strName, strMeshName) )
            return m_pMesh;
                if( m_pChild )
            if( NULL != ( pMesh = m_pChild->FindMesh(strMeshName) ) )
            return pMesh;
                if( m_pNext )
            if( NULL != ( pMesh = m_pNext->FindMesh(strMeshName) ) )
            return pMesh;
                return NULL;
            }
            CDXUTMeshFrame* CDXUTMeshFrame::FindFrame( LPCWSTR strFrameName )
            {
            CDXUTMeshFrame* pFrame;
                if( !lstrcmpi(m_strName, strFrameName) )
            return this;
                if( m_pChild )
            if( NULL != ( pFrame = m_pChild->FindFrame(strFrameName) ) )
            return pFrame;
                if( m_pNext )
            if( NULL != ( pFrame = m_pNext->FindFrame(strFrameName) ) )
            return pFrame;
                return NULL;
            }

             

            lstrcmpi()在比較兩個(gè)字符串時(shí)忽略大小寫:

            The lstrcmpi function compares two character strings. The comparison is not case sensitive.

            To perform a comparison that is case sensitive, use the lstrcmp function.

            Syntax

            int lstrcmpi(      

                LPCTSTR lpString1,
                LPCTSTR lpString2
            );

            Parameters

            lpString1
            [in] Pointer to the first null-terminated string to be compared.
            lpString2
            [in] Pointer to the second null-terminated string to be compared.

            Return Value

            If the string pointed to by lpString1 is less than the string pointed to by lpString2, the return value is negative. If the string pointed to by lpString1 is greater than the string pointed to by lpString2, the return value is positive. If the strings are equal, the return value is zero.

            Remarks

            The lstrcmpi function compares two strings by checking the first characters against each other, the second characters against each other, and so on until it finds an inequality or reaches the ends of the strings.

            Note that the lpString1 and lpString2 parameters must be null terminated, otherwise the string comparison can be incorrect.

            The function returns the difference of the values of the first unequal characters it encounters. For example, lstrcmpi determines that "abcz" is greater than "abcdefg" and returns the difference of z and d.

            The language (user locale) selected by the user at setup time, or through Control Panel, determines which string is greater (or whether the strings are the same). If no language (user locale) is selected, the system performs the comparison by using default values.

            For some locales, the lstrcmpi function may be insufficient. If this occurs, use CompareString to ensure proper comparison. For example, in Japan call with the NORM_IGNORECASE, NORM_IGNOREKANATYPE, and NORM_IGNOREWIDTH values to achieve the most appropriate non-exact string comparison. The NORM_IGNOREKANATYPE and NORM_IGNOREWIDTH values are ignored in non-Asian locales, so you can set these values for all locales and be guaranteed to have a culturally correct "insensitive" sorting regardless of the locale. Note that specifying these values slows performance, so use them only when necessary.

            With a double-byte character set (DBCS) version of the system, this function can compare two DBCS strings.

            The lstrcmpi function uses a word sort, rather than a string sort. A word sort treats hyphens and apostrophes differently than it treats other symbols that are not alphanumeric, in order to ensure that words such as "coop" and "co-op" stay together within a sorted list. For a detailed discussion of word sorts and string sorts, see the Remarks section for the CompareString function.

             

            EnumMeshes()是一個(gè)遞歸枚舉函數(shù),對(duì)所有框架的所有網(wǎng)格遞歸調(diào)用傳遞進(jìn)來(lái)的函數(shù):

            bool CDXUTMeshFrame::EnumMeshes( bool (*EnumMeshCB)(CDXUTMesh*, void*), void* pContext )
            {
            if( m_pMesh )
            EnumMeshCB( m_pMesh, pContext );
                if( m_pChild )
            m_pChild->EnumMeshes( EnumMeshCB, pContext );
                if( m_pNext )
            m_pNext->EnumMeshes( EnumMeshCB, pContext );
                return TRUE;
            }
             

            Destroy()、RestoreDeviceObjects()、InvalidateDeviceObjects()分別當(dāng)摧毀網(wǎng)格框架、設(shè)備恢復(fù)、設(shè)備丟失時(shí)調(diào)用,需要注意的是該類的析構(gòu)函數(shù)并沒(méi)有釋放分配的資源,只是刪除了鏈表指針,必須顯式調(diào)用Destroy()來(lái)釋放資源:

            HRESULT CDXUTMeshFrame::Destroy()
            {
            if( m_pMesh ) m_pMesh->Destroy();
            if( m_pChild ) m_pChild->Destroy();
            if( m_pNext ) m_pNext->Destroy();
                SAFE_DELETE( m_pMesh );
            SAFE_DELETE( m_pNext );
            SAFE_DELETE( m_pChild );
                return S_OK;
            }
            HRESULT CDXUTMeshFrame::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )
            {
            if( m_pMesh ) m_pMesh->RestoreDeviceObjects( pd3dDevice );
            if( m_pChild ) m_pChild->RestoreDeviceObjects( pd3dDevice );
            if( m_pNext ) m_pNext->RestoreDeviceObjects( pd3dDevice );
                return S_OK;
            }
            HRESULT CDXUTMeshFrame::InvalidateDeviceObjects()
            {
            if( m_pMesh ) m_pMesh->InvalidateDeviceObjects();
            if( m_pChild ) m_pChild->InvalidateDeviceObjects();
            if( m_pNext ) m_pNext->InvalidateDeviceObjects();
                return S_OK;
            }

             

            Render()負(fù)責(zé)網(wǎng)格框架的繪制,它只是調(diào)用CDXUTMesh::Render()來(lái)負(fù)責(zé)網(wǎng)格的繪制,由于框架的層次包含關(guān)系,所以該函數(shù)也是一個(gè)遞歸函數(shù)。需要注意的是該函數(shù)包含的最后一個(gè)參數(shù),它允許用戶指定世界坐標(biāo)變換矩陣,如果該參數(shù)為NULL,則從設(shè)備獲取已設(shè)置好的世界坐標(biāo)矩陣,注意如果是虛擬設(shè)備,必須設(shè)置該矩陣,不能為NULL。

            HRESULT CDXUTMeshFrame::Render( LPDIRECT3DDEVICE9 pd3dDevice, 
            bool bDrawOpaqueSubsets, bool bDrawAlphaSubsets,
            D3DXMATRIX* pmatWorldMatrix )
            {
            // For pure devices, specify the world transform.
            // If the world transform is not specified on pure devices, this function will fail.
                D3DXMATRIX matSavedWorld, matWorld;
                if (NULL == pmatWorldMatrix)
            pd3dDevice->GetTransform(D3DTS_WORLD, &matSavedWorld);
            else
            matSavedWorld = *pmatWorldMatrix;
                D3DXMatrixMultiply(&matWorld, &m_mat, &matSavedWorld);
            pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
                if( m_pMesh )
            m_pMesh->Render(pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets);
                if( m_pChild )
            m_pChild->Render(pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matWorld);
                pd3dDevice->SetTransform(D3DTS_WORLD, &matSavedWorld);
                if( m_pNext )
            m_pNext->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matSavedWorld );
                return S_OK;
            }

            代碼中需要注意的一點(diǎn)是,調(diào)用Render()繪制兄弟框架時(shí)傳遞的世界坐標(biāo)矩陣是matSavedWorld,而繪制子框架時(shí)傳遞的世界坐標(biāo)矩陣是matWorld。


            posted on 2008-06-01 07:50 lovedday 閱讀(1062) 評(píng)論(0)  編輯 收藏 引用 所屬分類: ■ DXUT Research

            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

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

            搜索

            最新評(píng)論

            无码人妻精品一区二区三区久久| 人妻精品久久无码区| 狠狠色婷婷久久一区二区三区| 久久国产精品无码一区二区三区 | 久久久久亚洲?V成人无码| 欧美精品一区二区久久| 亚洲人成电影网站久久| 久久精品国产精品青草app| 欧美粉嫩小泬久久久久久久 | 中文字幕成人精品久久不卡| 一本色道久久综合| 国产精品久久久久久搜索| 午夜精品久久久久久影视777| 人妻精品久久久久中文字幕69| 狠狠色综合网站久久久久久久| 久久国产欧美日韩精品免费| 一级做a爰片久久毛片16| 一本综合久久国产二区| 91亚洲国产成人久久精品网址| A级毛片无码久久精品免费| 99久久精品国产一区二区蜜芽| 国内精品综合久久久40p| 欧洲性大片xxxxx久久久| 国产精品久久久久天天影视 | 无码日韩人妻精品久久蜜桃 | 996久久国产精品线观看| 一本色道久久99一综合| 四虎国产精品免费久久| 国产激情久久久久影院小草| 国产日产久久高清欧美一区| 国内精品久久久久久99| 青青草原精品99久久精品66| 99久久精品免费看国产一区二区三区 | 国产精品久久久久国产A级| 国产成人精品久久| 欧美日韩精品久久久免费观看| 欧美精品福利视频一区二区三区久久久精品 | 国产精品一区二区久久精品无码 | 精品久久久久中文字幕一区| 日本久久久精品中文字幕| 日本免费一区二区久久人人澡|