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

            天行健 君子當自強而不息

            DXUT源碼分析 ---- 類CDXUTMeshFrame

            類CDXUTMeshFrame封裝了CDXUTMesh,與CDXUTMesh不同的是,類CDXUTMeshFrame可以包含框架層次結構,適用于更復雜的網格模型,框架層次正是骨骼動畫所必須的。

            首先來看看它的定義:

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

                CDXUTMeshFrame
            * m_pNext;         // 指向下一個框架對象
                CDXUTMeshFrame* m_pChild;         // 指向子框架對象

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

             

            構造函數和析構函數只是負責初始化數據和釋放分配的資源:

            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()是兩個遞歸查找函數,根據輸入的網格名稱和框架名稱查找對應的網格和框架:

            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()在比較兩個字符串時忽略大小寫:

            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()是一個遞歸枚舉函數,對所有框架的所有網格遞歸調用傳遞進來的函數:

            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()分別當摧毀網格框架、設備恢復、設備丟失時調用,需要注意的是該類的析構函數并沒有釋放分配的資源,只是刪除了鏈表指針,必須顯式調用Destroy()來釋放資源:

            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()負責網格框架的繪制,它只是調用CDXUTMesh::Render()來負責網格的繪制,由于框架的層次包含關系,所以該函數也是一個遞歸函數。需要注意的是該函數包含的最后一個參數,它允許用戶指定世界坐標變換矩陣,如果該參數為NULL,則從設備獲取已設置好的世界坐標矩陣,注意如果是虛擬設備,必須設置該矩陣,不能為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;
            }

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


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

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            日韩亚洲国产综合久久久| 国产精品成人久久久| 99国产欧美精品久久久蜜芽| 色老头网站久久网| 国产成人久久精品一区二区三区| 久久福利青草精品资源站| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 久久久精品人妻无码专区不卡 | 久久香蕉国产线看观看乱码| 精品乱码久久久久久夜夜嗨| 2021国产精品久久精品| 精品久久久久久久久中文字幕| 久久久久亚洲AV综合波多野结衣| 奇米综合四色77777久久| 午夜不卡888久久| 国产午夜福利精品久久2021 | 亚洲人成无码www久久久| 久久久久人妻精品一区 | 无码人妻久久一区二区三区蜜桃| 久久精品中文騷妇女内射| 久久亚洲国产成人精品无码区| 99国产欧美久久久精品蜜芽| 亚洲精品无码久久千人斩| 老司机午夜网站国内精品久久久久久久久| 亚洲欧美成人综合久久久| 久久久久这里只有精品| 久久香蕉国产线看观看乱码| 国产精品九九九久久九九 | 国产亚洲精久久久久久无码AV| 久久午夜无码鲁丝片| 综合久久国产九一剧情麻豆| 香蕉久久久久久狠狠色| 欧美粉嫩小泬久久久久久久 | 漂亮人妻被中出中文字幕久久| 久久精品一区二区三区中文字幕| 国内精品伊人久久久久| 久久人人爽人人爽人人片av高请 | 中文字幕久久亚洲一区| 久久午夜福利电影| 青青草国产97免久久费观看| 久久久久亚洲av毛片大|