• <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>
            隨筆 - 505  文章 - 1034  trackbacks - 0
            <2007年4月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345


            子曾經曰過:編程無他,唯手熟爾!

            常用鏈接

            留言簿(94)

            隨筆分類(649)

            隨筆檔案(505)

            相冊

            BCB

            Crytek

            • crymod
            • Crytek's Offical Modding Portal

            Game Industry

            OGRE

            other

            Programmers

            Qt

            WOW Stuff

            搜索

            •  

            積分與排名

            • 積分 - 911344
            • 排名 - 14

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜






            HLSLSkinMesh.fx

            //=========================================================
            // Desc: 效果源代碼
            //=========================================================


            //---------------------------------------------------------
            // 全局變量
            //---------------------------------------------------------
            float4 lightDir = {0.0f0.0f-1.0f1.0f};
            float4 lightDiffuse 
            = {0.6f0.6f0.6f1.0f}; 
            float4 MaterialAmbient 
            = {0.1f0.1f0.1f1.0f};
            float4 MaterialDiffuse 
            = {0.8f0.8f0.8f1.0f};

            static const int MAX_MATRICES = 26;
            float4x3    mWorldMatrixArray[MAX_MATRICES];  
            //骨骼調色板矩陣 
            int         CurNumBones = 2;    //當前骨骼數量
            float4x4    mProj;

            //----------------------------------------------------------
            // 頂點渲染器輸入和輸出結構
            //----------------------------------------------------------
            struct VS_INPUT
            {
                float4  Pos           : POSITION;
                float4  BlendWeights  : BLENDWEIGHT;
                float4  BlendIndices  : BLENDINDICES;
                float3  Normal        : NORMAL;
                float3  Tex0          : TEXCOORD0;
            };

            struct VS_OUTPUT
            {
                float4  Pos     : POSITION;
                float4  Diffuse : COLOR;
                float2  Tex0    : TEXCOORD0;
            };


            //---------------------------------------------------------
            // 子函數, 計算光照系數
            //---------------------------------------------------------
            float3 Diffuse(float3 Normal)
            {
                
            float CosTheta;
                CosTheta 
            = max(0.0f, dot(Normal, lightDir.xyz));
                
            return (CosTheta);
            }

            //---------------------------------------------------------
            // 子函數, 完成頂點處理
            //---------------------------------------------------------
            VS_OUTPUT VShade(VS_INPUT i, uniform int NumBones)
            {
                VS_OUTPUT   o;
                float3      Pos 
            = 0.0f;
                float3      Normal 
            = 0.0f;
                
            float       sumWeight  = 0.0f;
                
            float       LastWeight = 0.0f;
                 
                
            //為Geforce3類型的顯卡所做的補償
                int4 IndexVector = D3DCOLORtoUBYTE4(i.BlendIndices);
                
                
            //將骨骼權重向量和骨骼索引向量變換至數組
                float BlendWeightsArray[4= (float[4])i.BlendWeights;
                
            int   IndexArray[4]        = (int[4])IndexVector;

                
            //計算前NumBones-1個骨骼對于該頂點位置及法向量的影響
                for (int iBone = 0; iBone < NumBones-1; iBone++)
                {
                    sumWeight 
            = sumWeight + BlendWeightsArray[iBone];
                    
                    Pos 
            += mul(i.Pos, mWorldMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];
                    Normal 
            += mul(i.Normal, mWorldMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];
                }
                LastWeight 
            = 1.0f - sumWeight; 

                
            //計算最后一個骨骼對于頂點位置及法向量的影響
                Pos += (mul(i.Pos, mWorldMatrixArray[IndexArray[NumBones-1]]) * LastWeight);
                Normal 
            += (mul(i.Normal, mWorldMatrixArray[IndexArray[NumBones-1]]) * LastWeight); 
                
                o.Pos 
            = mul(float4(Pos.xyz, 1.0f), mProj);
                Normal 
            = normalize(Normal);

                
            //計算光照
                o.Diffuse.xyz = MaterialAmbient.xyz + Diffuse(Normal) * MaterialDiffuse.xyz;
                o.Diffuse.w 
            = 1.0f;

                
            //輸出紋理坐標
                o.Tex0  = i.Tex0.xy;

                
            return o;
            }


            //---------------------------------------------------------
            // 頂點渲染器
            //---------------------------------------------------------
            VertexShader vsArray[4= {
                                        compile vs_1_1 VShade(
            1), 
                                        compile vs_1_1 VShade(
            2),
                                        compile vs_1_1 VShade(
            3),
                                        compile vs_1_1 VShade(
            4)
                                      };


            //---------------------------------------------------------
            // 技術與通道
            //---------------------------------------------------------
            technique t0
            {
                pass p0
                {
                    VertexShader 
            = (vsArray[CurNumBones]);
                }
            }






            //=============================================================================
            // Desc: 主程序源文件
            //=============================================================================
            #include "dxstdafx.h"
            #include 
            "resource.h"
            #pragma warning(disable: 
            4995)

            //-----------------------------------------------------------------------------
            // Desc: 繼承自DXDXFRAME結構的結構
            //-----------------------------------------------------------------------------
            struct D3DXFRAME_DERIVED: public D3DXFRAME
            {
                D3DXMATRIXA16        CombinedTransformationMatrix;
            };


            //-----------------------------------------------------------------------------
            // Desc: 繼承自D3DXMESHCONTAINER結構的結構
            //-----------------------------------------------------------------------------
            struct D3DXMESHCONTAINER_DERIVED: public D3DXMESHCONTAINER
            {
                LPDIRECT3DTEXTURE9
            *  ppTextures;            //紋理數組
                LPD3DXMESH           pOrigMesh;             //原網格
                DWORD                NumAttributeGroups;    //骨骼數量
                DWORD                NumInfl;               //每個頂點最多可以影響多少骨骼
                LPD3DXBUFFER         pBoneCombinationBuf;   //骨骼結合表
                D3DXMATRIX**         ppBoneMatrixPtrs;      //存放骨骼的組合變換矩陣
                D3DXMATRIX*          pBoneOffsetMatrices;   //存放骨骼的初始變換矩陣
                DWORD                NumPaletteEntries;     //有多少骨骼可以使用(上限)
                bool                 UseSoftwareVP;         //標識是否使用軟件頂點處理
            };


            //-----------------------------------------------------------------------------
            // Desc: 該類用來從.X文件加載框架層次和網格模型數據
            //-----------------------------------------------------------------------------
            class CAllocateHierarchy: public ID3DXAllocateHierarchy
            {
            private:
                HRESULT GenerateSkinnedMesh(IDirect3DDevice9 
            *pd3dDevice, D3DXMESHCONTAINER_DERIVED *pMeshContainer);
                HRESULT AllocateName( LPCSTR Name, LPSTR 
            *pNewName );
                
            void    RemovePathFromFileName(LPSTR fullPath, LPWSTR fileName);

            public:
                STDMETHOD(CreateFrame)(THIS_ LPCSTR Name, LPD3DXFRAME 
            *ppNewFrame);
                STDMETHOD(CreateMeshContainer)(THIS_ 
                    LPCSTR Name, 
                    CONST D3DXMESHDATA 
            *pMeshData,
                    CONST D3DXMATERIAL 
            *pMaterials, 
                    CONST D3DXEFFECTINSTANCE 
            *pEffectInstances, 
                    DWORD NumMaterials, 
                    CONST DWORD 
            *pAdjacency, 
                    LPD3DXSKININFO pSkinInfo, 
                    LPD3DXMESHCONTAINER 
            *ppNewMeshContainer);
                STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree);
                STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerBase);

                CAllocateHierarchy() {}
            };


            //-----------------------------------------------------------------------------
            // 全局變量
            //-----------------------------------------------------------------------------
            ID3DXFont*                 g_pFont = NULL;          //ID3DXFont字體對象
            ID3DXSprite*               g_pTextSprite = NULL;    //ID3DXSprite文本精靈對象
            bool                       g_bShowHelp = true;      //標識是否顯示簡單說明文本

            CDXUTDialogResourceManager g_DialogResourceManager; 
            //對話框資源管理器
            CD3DSettingsDlg            g_SettingsDlg;           //Direct3D設備設置對話框
            CDXUTDialog                g_HUD;                   //對話框
            CDXUTDialog                g_SampleUI;              //對話框

            ID3DXEffect
            *              g_pEffect = NULL;
            LPD3DXFRAME               g_pFrameRoot 
            = NULL;
            ID3DXAnimationController
            * g_pAnimController = NULL;
            D3DXMATRIXA16
            *            g_pBoneMatrices = NULL;
            UINT                      g_NumBoneMatricesMax 
            = 0;
            D3DXMATRIXA16             g_matWorld;
            D3DXMATRIXA16             g_matView;
            D3DXMATRIXA16             g_matProj;


            //-----------------------------------------------------------------------------
            // 控件ID
            //-----------------------------------------------------------------------------
            #define IDC_TOGGLEFULLSCREEN      1
            #define IDC_TOGGLEREF             2
            #define IDC_CHANGEDEVICE          3


            //-----------------------------------------------------------------------------
            // Desc: 函數聲明
            //------------------------------------------------------------------------------
            bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
            bool    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );
            HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9
            * pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
            HRESULT CALLBACK OnResetDevice( IDirect3DDevice9
            * pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
            void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
            void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
            LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
            bool* pbNoFurtherProcessing, void* pUserContext );
            void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
            void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );
            void    CALLBACK OnLostDevice( void* pUserContext );
            void    CALLBACK OnDestroyDevice( void* pUserContext );

            void    InitApp();
            void    RenderText();

            void    DrawMeshContainer( IDirect3DDevice9 *pd3dDevice, LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase );
            void    DrawFrame( IDirect3DDevice9 *pd3dDevice, LPD3DXFRAME pFrame );
            HRESULT SetupBoneMatrixPointersOnMesh( LPD3DXMESHCONTAINER pMeshContainer );
            HRESULT SetupBoneMatrixPointers( LPD3DXFRAME pFrame );
            void    UpdateFrameMatrices( LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix );


            //-----------------------------------------------------------------------------
            // Desc: 
            //-----------------------------------------------------------------------------
            HRESULT CAllocateHierarchy::AllocateName( LPCSTR Name, LPSTR *pNewName )
            {
                UINT cbLength;

                
            if( Name != NULL )
                {
                    cbLength 
            = (UINT)strlen(Name) + 1;
                    
            *pNewName = new CHAR[cbLength];
                    
            if (*pNewName == NULL)
                        
            return E_OUTOFMEMORY;
                    memcpy( 
            *pNewName, Name, cbLength*sizeof(CHAR) );
                }
                
            else
                {
                    
            *pNewName = NULL;
                }

                
            return S_OK;
            }


            //-----------------------------------------------------------------------------
            // Desc: 從絕對路徑中提取文件名
            //-----------------------------------------------------------------------------
            void CAllocateHierarchy::RemovePathFromFileName(LPSTR fullPath, LPWSTR fileName)
            {
                
            //先將fullPath的類型變換為LPWSTR
                WCHAR wszBuf[MAX_PATH];
                MultiByteToWideChar( CP_ACP, 
            0, fullPath, -1, wszBuf, MAX_PATH );
                wszBuf[MAX_PATH
            -1= L'\0';

                WCHAR
            * wszFullPath = wszBuf;

                
            //從絕對路徑中提取文件名
                LPWSTR pch=wcsrchr(wszFullPath,'\\');
                
            if (pch)
                    lstrcpy(fileName, 
            ++pch);
                
            else
                    lstrcpy(fileName, wszFullPath);
            }



            //-----------------------------------------------------------------------------
            // Desc: 創建框架, 僅僅是分配內存和初始化,還沒有對其成員賦予合適的值
            //-----------------------------------------------------------------------------
            HRESULT CAllocateHierarchy::CreateFrame( LPCSTR Name, LPD3DXFRAME *ppNewFrame )
            {
                HRESULT hr 
            = S_OK;
                D3DXFRAME_DERIVED 
            *pFrame;
                
                
            *ppNewFrame = NULL;
                
                pFrame 
            = new D3DXFRAME_DERIVED;  //創建框架結構對象
                if (pFrame == NULL) 
                {
                    
            return E_OUTOFMEMORY;
                }
                
                
            //為框架指定名稱
                hr = AllocateName(Name, (LPSTR*)&pFrame->Name);
                
            if (FAILED(hr))
                {
                    delete pFrame;
                    
            return hr;
                }
                
                
            //初始化D3DXFRAME_DERIVED結構其它成員變量
                D3DXMatrixIdentity(&pFrame->TransformationMatrix);
                D3DXMatrixIdentity(
            &pFrame->CombinedTransformationMatrix);
                
                pFrame
            ->pMeshContainer = NULL;
                pFrame
            ->pFrameSibling = NULL;
                pFrame
            ->pFrameFirstChild = NULL;
                
                
            *ppNewFrame = pFrame;
                pFrame 
            = NULL;

                
            return hr;
            }


            //-----------------------------------------------------------------------------
            // Desc: 在這里是調用了成員函數 GenerateSkinnedMesh(pMeshContainer);
            //       是在這里加載了蒙皮信息
            //-----------------------------------------------------------------------------
            HRESULT CAllocateHierarchy::CreateMeshContainer( LPCSTR Name, 
                                                             CONST D3DXMESHDATA 
            *pMeshData,
                                                             CONST D3DXMATERIAL 
            *pMaterials, 
                                                             CONST D3DXEFFECTINSTANCE 
            *pEffectInstances, 
                                                             DWORD NumMaterials, 
                                                             CONST DWORD 
            *pAdjacency, 
                                                             LPD3DXSKININFO pSkinInfo, 
                                                             LPD3DXMESHCONTAINER 
            *ppNewMeshContainer) 
            {
                HRESULT hr;
                D3DXMESHCONTAINER_DERIVED 
            *pMeshContainer = NULL;
                UINT NumFaces;       
            //網格中的面數,在填充網格容器結構的鄰接信息成員時使用
                UINT iMaterial;      //紋理操作時的循環變量
                UINT cBones;         //當前網格模型骨骼總數
                LPDIRECT3DDEVICE9 pd3dDevice = NULL;
                LPD3DXMESH pMesh    
            = NULL;
                
            *ppNewMeshContainer = NULL;

                
            if (pMeshData->Type != D3DXMESHTYPE_MESH)
                {
                    
            return E_FAIL;
                }

                pMesh 
            = pMeshData->pMesh;
                
                
            if (pMesh->GetFVF() == 0)
                {
                    
            return E_FAIL;
                }

                
            //為網格容器分配內存
                pMeshContainer = new D3DXMESHCONTAINER_DERIVED;
                
            if (pMeshContainer == NULL)
                {
                    
            return E_OUTOFMEMORY;
                }
                memset(pMeshContainer, 
            0sizeof(D3DXMESHCONTAINER_DERIVED));

                
            //填充網格容器結構D3DXMESHCONTAINER_DERIVED的成員

                
            //為網格指定名稱
                hr = AllocateName(Name, &pMeshContainer->Name);
                
            if (FAILED(hr))
                {
                    DestroyMeshContainer(pMeshContainer);
                    
            return hr;
                }      
                
                pMesh
            ->GetDevice(&pd3dDevice);
                NumFaces 
            = pMesh->GetNumFaces();

                
            //確保網格頂點包含法線
                if (!(pMesh->GetFVF() & D3DFVF_NORMAL))
                {
                    pMeshContainer
            ->MeshData.Type = D3DXMESHTYPE_MESH;
                    hr 
            = pMesh->CloneMeshFVF( pMesh->GetOptions(), 
                                              pMesh
            ->GetFVF() | D3DFVF_NORMAL, 
                                              pd3dDevice, 
                                              
            &pMeshContainer->MeshData.pMesh );
                    
            if (FAILED(hr))
                    {
                        SAFE_RELEASE(pd3dDevice);
                        DestroyMeshContainer(pMeshContainer);
                        
            return hr;
                    }

                    pMesh 
            = pMeshContainer->MeshData.pMesh;
                    D3DXComputeNormals( pMesh, NULL );
                }
                
            else 
                {
                    pMeshContainer
            ->MeshData.pMesh = pMesh;
                    pMeshContainer
            ->MeshData.Type = D3DXMESHTYPE_MESH;
                    pMesh
            ->AddRef();
                }

                
            //為網格模型準備材質和紋理
                pMeshContainer->NumMaterials = max(1, NumMaterials); 
                pMeshContainer
            ->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials];
                pMeshContainer
            ->ppTextures = new LPDIRECT3DTEXTURE9[pMeshContainer->NumMaterials];
                pMeshContainer
            ->pAdjacency = new DWORD[NumFaces*3];
                
            if ((pMeshContainer->pAdjacency == NULL) || (pMeshContainer->pMaterials == NULL)
                    
            || (pMeshContainer->ppTextures == NULL))
                {
                    hr 
            = E_OUTOFMEMORY;
                    SAFE_RELEASE(pd3dDevice);
                    DestroyMeshContainer(pMeshContainer);
                    
            return hr;
                }

                memcpy(pMeshContainer
            ->pAdjacency, pAdjacency, sizeof(DWORD) * NumFaces*3);
                memset(pMeshContainer
            ->ppTextures, 0sizeof(LPDIRECT3DTEXTURE9) * pMeshContainer->NumMaterials);

                
            if (NumMaterials > 0)            
                {
                    
            //復制材質屬性, 設置材質環境光屬性
                    memcpy(pMeshContainer->pMaterials, pMaterials, sizeof(D3DXMATERIAL) * NumMaterials); 
                    pMeshContainer
            ->pMaterials->MatD3D.Ambient = pMeshContainer->pMaterials->MatD3D.Diffuse;

                    
            for (iMaterial = 0; iMaterial < NumMaterials; iMaterial++)
                    {
                        
            if (pMeshContainer->pMaterials[iMaterial].pTextureFilename != NULL)
                        {
                            WCHAR strTexturePath[MAX_PATH];
                            WCHAR wszBuf[MAX_PATH];
                            
            //從紋理文件路徑提取紋理文件名
                            RemovePathFromFileName(pMeshContainer->pMaterials[iMaterial].pTextureFilename, wszBuf);
                            
            //根據紋理文件名從事先指定的路徑查找紋理文件
                            DXUTFindDXSDKMediaFileCch( strTexturePath, MAX_PATH, wszBuf );
                            
            if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexturePath,
                                                                    
            &pMeshContainer->ppTextures[iMaterial] ) ) )
                                pMeshContainer
            ->ppTextures[iMaterial] = NULL;

                            pMeshContainer
            ->pMaterials[iMaterial].pTextureFilename = NULL;
                        }
                    }
                }
                
            else 
                {
                    pMeshContainer
            ->pMaterials[0].pTextureFilename = NULL;
                    memset(
            &pMeshContainer->pMaterials[0].MatD3D, 0sizeof(D3DMATERIAL9));
                    pMeshContainer
            ->pMaterials[0].MatD3D.Diffuse.r = 0.5f;
                    pMeshContainer
            ->pMaterials[0].MatD3D.Diffuse.g = 0.5f;
                    pMeshContainer
            ->pMaterials[0].MatD3D.Diffuse.b = 0.5f;
                    pMeshContainer
            ->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Diffuse;
                }

                 
            //如果當前網格包含蒙皮信息
                if (pSkinInfo != NULL)
                {
                    
            //加載蒙皮網格信息
                    pMeshContainer->pSkinInfo = pSkinInfo; 
                    pSkinInfo
            ->AddRef();

                    
            //保留原網格信息
                    pMeshContainer->pOrigMesh = pMesh;
                    pMesh
            ->AddRef();

                    
            //獲取骨骼數量
                    cBones = pSkinInfo->GetNumBones();

                    
            //為每塊骨骼分配保存初始變換矩陣的內存空間
                    pMeshContainer->pBoneOffsetMatrices = new D3DXMATRIX[cBones];
                    
            if (pMeshContainer->pBoneOffsetMatrices == NULL) 
                    {
                        hr 
            = E_OUTOFMEMORY;
                        DestroyMeshContainer(pMeshContainer);
                        
            return hr;
                    }

                    
            //保存每塊骨骼的初始變換矩陣
                    for (UINT iBone = 0; iBone < cBones; iBone++)
                    {
                        pMeshContainer
            ->pBoneOffsetMatrices[iBone] = *(pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(iBone));
                    }

                    
            //生成蒙皮網格模型
                    hr = GenerateSkinnedMesh(pd3dDevice, pMeshContainer); 
                    
            if (FAILED(hr))
                    {
                        DestroyMeshContainer(pMeshContainer);
                        
            return hr;
                    }
                }

                
            *ppNewMeshContainer = pMeshContainer;
                pMeshContainer 
            = NULL;
                SAFE_RELEASE(pd3dDevice);
                
            return hr;
            }


            //-----------------------------------------------------------------------------
            //Desc: 生成蒙皮網格模型(含有每個頂點的混合權重、索引和一個骨骼組合表)
            //-----------------------------------------------------------------------------
            HRESULT CAllocateHierarchy::GenerateSkinnedMesh( IDirect3DDevice9 *pd3dDevice, 
                                                            D3DXMESHCONTAINER_DERIVED 
            *pMeshContainer )
            {
                HRESULT hr 
            = S_OK;
                
            if( pMeshContainer->pSkinInfo == NULL )
                    
            return hr;

                SAFE_RELEASE( pMeshContainer
            ->MeshData.pMesh );
                SAFE_RELEASE( pMeshContainer
            ->pBoneCombinationBuf );

                
            //獲取當前設備的能力
                D3DCAPS9 d3dCaps;
                pd3dDevice
            ->GetDeviceCaps( &d3dCaps );

                pMeshContainer
            ->NumPaletteEntries = min(26, pMeshContainer->pSkinInfo->GetNumBones());
                DWORD Flags 
            = D3DXMESHOPT_VERTEXCACHE;

                
            if (d3dCaps.VertexShaderVersion >= D3DVS_VERSION(11))
                {
                    pMeshContainer
            ->UseSoftwareVP = false;
                    Flags 
            |= D3DXMESH_MANAGED;
                }
                
            else
                {
                    pMeshContainer
            ->UseSoftwareVP = true;
                    Flags 
            |= D3DXMESH_SYSTEMMEM;
                }

                SAFE_RELEASE(pMeshContainer
            ->MeshData.pMesh);

                hr 
            = pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh 
                                                                          ( pMeshContainer
            ->pOrigMesh,
                                                                            Flags, 
                                                                            pMeshContainer
            ->NumPaletteEntries, 
                                                                            pMeshContainer
            ->pAdjacency, 
                                                                            NULL, NULL, NULL,             
                                                                            
            &pMeshContainer->NumInfl,
                                                                            
            &pMeshContainer->NumAttributeGroups, 
                                                                            
            &pMeshContainer->pBoneCombinationBuf, 
                                                                            
            &pMeshContainer->MeshData.pMesh);
                
            if (FAILED(hr))
                    
            return hr;

                
            // FVF has to match our declarator. Vertex shaders are not as forgiving as FF pipeline
                DWORD NewFVF = (pMeshContainer->MeshData.pMesh->GetFVF() & D3DFVF_POSITION_MASK) | D3DFVF_NORMAL | D3DFVF_TEX1 | D3DFVF_LASTBETA_UBYTE4;
                
            if (NewFVF != pMeshContainer->MeshData.pMesh->GetFVF())
                {
                    LPD3DXMESH pMesh;
                    hr 
            = pMeshContainer->MeshData.pMesh->CloneMeshFVF(pMeshContainer->MeshData.pMesh->GetOptions(), NewFVF, pd3dDevice, &pMesh);
                    
            if (!FAILED(hr))
                    {
                        pMeshContainer
            ->MeshData.pMesh->Release();
                        pMeshContainer
            ->MeshData.pMesh = pMesh;
                        pMesh 
            = NULL;
                    }
                }

                D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE];
                LPD3DVERTEXELEMENT9 pDeclCur;
                hr 
            = pMeshContainer->MeshData.pMesh->GetDeclaration(pDecl);
                
            if (FAILED(hr))
                    
            return hr;

                pDeclCur 
            = pDecl;
                
            while (pDeclCur->Stream != 0xff)
                {
                    
            if ((pDeclCur->Usage == D3DDECLUSAGE_BLENDINDICES) && (pDeclCur->UsageIndex == 0))
                        pDeclCur
            ->Type = D3DDECLTYPE_D3DCOLOR;
                    pDeclCur
            ++;
                }

                hr 
            = pMeshContainer->MeshData.pMesh->UpdateSemantics(pDecl);
                
            if (FAILED(hr))
                    
            return hr;

                
            // allocate a buffer for bone matrices,
                if( g_NumBoneMatricesMax < pMeshContainer->pSkinInfo->GetNumBones() )
                {
                    g_NumBoneMatricesMax 
            = pMeshContainer->pSkinInfo->GetNumBones();

                    
            // Allocate space for blend matrices
                    delete[] g_pBoneMatrices; 
                    g_pBoneMatrices  
            = new D3DXMATRIXA16[g_NumBoneMatricesMax];
                    
            if( g_pBoneMatrices == NULL )
                    {
                        hr 
            = E_OUTOFMEMORY;
                        
            return hr;
                    }
                }

                
            return hr;
            }


            //-----------------------------------------------------------------------------
            // Desc: 釋放框架
            //-----------------------------------------------------------------------------
            HRESULT CAllocateHierarchy::DestroyFrame(LPD3DXFRAME pFrameToFree) 
            {
                
            if(pFrameToFree != NULL)
                {
                    SAFE_DELETE_ARRAY( pFrameToFree
            ->Name );
                    SAFE_DELETE( pFrameToFree );
                }
                
            return S_OK; 
            }


            //-----------------------------------------------------------------------------
            // Desc: 釋放網格容器
            //-----------------------------------------------------------------------------
            HRESULT CAllocateHierarchy::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase)
            {
                
            if(pMeshContainerBase == NULL)
                    
            return S_OK;

                UINT iMaterial;
                
            // 先轉為擴展型以免內存泄漏
                D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;
                
                SAFE_DELETE_ARRAY( pMeshContainer
            ->Name );
                SAFE_DELETE_ARRAY( pMeshContainer
            ->pAdjacency );
                SAFE_DELETE_ARRAY( pMeshContainer
            ->pMaterials );
                SAFE_DELETE_ARRAY( pMeshContainer
            ->pBoneOffsetMatrices );
                
                
            if (pMeshContainer->ppTextures != NULL)
                {
                    
            for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)
                    {
                        SAFE_RELEASE( pMeshContainer
            ->ppTextures[iMaterial] );
                    }
                }
                SAFE_DELETE_ARRAY( pMeshContainer
            ->ppTextures );

                SAFE_DELETE_ARRAY( pMeshContainer
            ->ppBoneMatrixPtrs );
                SAFE_RELEASE( pMeshContainer
            ->pBoneCombinationBuf );
                SAFE_RELEASE( pMeshContainer
            ->MeshData.pMesh );
                SAFE_RELEASE( pMeshContainer
            ->pSkinInfo );
                SAFE_RELEASE( pMeshContainer
            ->pOrigMesh );
                SAFE_DELETE( pMeshContainer );
                
            return S_OK;
            }


            //-----------------------------------------------------------------------------
            // Desc: 入口函數
            //-----------------------------------------------------------------------------
            INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
            {
                
            //為Debug配置啟用運行時內存檢查功能
            #if defined(DEBUG) | defined(_DEBUG)
                _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF 
            | _CRTDBG_LEAK_CHECK_DF );
            #endif

                
            //設置回調函數
                DXUTSetCallbackDeviceCreated( OnCreateDevice );
                DXUTSetCallbackDeviceReset( OnResetDevice );
                DXUTSetCallbackDeviceLost( OnLostDevice );
                DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
                DXUTSetCallbackMsgProc( MsgProc );
                DXUTSetCallbackKeyboard( KeyboardProc );
                DXUTSetCallbackFrameRender( OnFrameRender );
                DXUTSetCallbackFrameMove( OnFrameMove );

                
            //應用程序相關的初始化
                InitApp();

                
            //初始化DXUT, 創建窗口, 創建Direct3D設備對象
                DXUTInit( truetruetrue );
                DXUTSetCursorSettings( 
            truetrue );
                DXUTCreateWindow( L
            "HLSLSkinMesh" );
                DXUTCreateDevice( D3DADAPTER_DEFAULT, 
            true640480
                    IsDeviceAcceptable, ModifyDeviceSettings );

                
            //進入消息循環和場景渲染
                DXUTMainLoop();

                
            //在此進行應用程序相關的清除工作
                delete[] g_pBoneMatrices;

                
            return DXUTGetExitCode();
            }


            //-----------------------------------------------------------------------------
            // Desc: 應用程序相關初始化
            //-----------------------------------------------------------------------------
            void InitApp()
            {
                
            //初始化對話框
                g_SettingsDlg.Init( &g_DialogResourceManager );
                g_HUD.Init( 
            &g_DialogResourceManager );
                g_SampleUI.Init( 
            &g_DialogResourceManager );

                
            //為g_HUD對話框設置消息處理函數,添加控件
                g_HUD.SetCallback( OnGUIEvent ); int iY = 10
                g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L
            "Toggle full screen"35, iY, 12522 );
                g_HUD.AddButton( IDC_TOGGLEREF, L
            "Toggle REF (F3)"35, iY += 2412522 );
                g_HUD.AddButton( IDC_CHANGEDEVICE, L
            "Change device (F2)"35, iY += 2412522, VK_F2 );
            }


            //-----------------------------------------------------------------------------
            // Desc: 設備能力檢查
            //-----------------------------------------------------------------------------
            bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
                                              D3DFORMAT BackBufferFormat, 
            bool bWindowed, 
                                              
            void* pUserContext )
            {
                
            //檢查后臺緩沖區格式是否支持Alpha混合等操作(post pixel blending operations)
                IDirect3D9* pD3D = DXUTGetD3DObject(); 
                
            if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
                                AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
                                D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
                    
            return false;

                
            //檢查當前設備支持頂點渲染器版本是否符合要求
                if( pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
                    
            return FALSE;

                
            return true;
            }


            //-----------------------------------------------------------------------------
            // Desc: 修改Direct3D渲染設備設置
            //-----------------------------------------------------------------------------
            bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, 
                                                
            const D3DCAPS9* pCaps, void* pUserContext )
            {
                
            //如果不支持硬件頂點處理則使用軟件頂點處理
                if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0)
                {
                    pDeviceSettings
            ->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
                }

                
            //如果使用純硬件頂點處理模式則改為混合頂點處理模式
                if( pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING )
                    pDeviceSettings
            ->BehaviorFlags = D3DCREATE_MIXED_VERTEXPROCESSING;
                
                
            //調試頂點渲染器需要參考設備或軟件頂點處理
            #ifdef DEBUG_VS
                
            if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
                {
                    pDeviceSettings
            ->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
                    pDeviceSettings
            ->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
                    pDeviceSettings
            ->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
                }
            #endif

                
            //調試像素渲染器需要參考設備
            #ifdef DEBUG_PS
                pDeviceSettings
            ->DeviceType = D3DDEVTYPE_REF;
            #endif

                
            //如果使用參考設備,則彈出警告對話框
                static bool s_bFirstTime = true;
                
            if( s_bFirstTime )
                {
                    s_bFirstTime 
            = false;
                    
            if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
                        DXUTDisplaySwitchingToREFWarning();
                }

                
            return true;
            }


            //-----------------------------------------------------------------------------
            // Desc: 在此創建管理內存資源對象
            //-----------------------------------------------------------------------------
            HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, 
                                            
            const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
                                            
            void* pUserContext )
            {
                HRESULT hr;

                V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );
                V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );
                
                
            //創建字體
                V_RETURN( D3DXCreateFont( pd3dDevice, 150, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, 
                                     OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH 
            | FF_DONTCARE, 
                                     L
            "Arial"&g_pFont ) );

                
            //創建效果
                DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
                #ifdef DEBUG_VS
                    dwShaderFlags 
            |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
                
            #endif
                #ifdef DEBUG_PS
                    dwShaderFlags 
            |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
                
            #endif
                V_RETURN(D3DXCreateEffectFromFile( pd3dDevice, L
            "HLSLSkinMesh.fx", NULL, NULL, 
                                                   dwShaderFlags, NULL, 
            &g_pEffect, NULL ));

                
            //創建網格模型
                CAllocateHierarchy Alloc;
                V_RETURN(D3DXLoadMeshHierarchyFromX( L
            "tiny.x", D3DXMESH_MANAGED, pd3dDevice,
                                                     
            &Alloc, NULL, &g_pFrameRoot, &g_pAnimController ));
                
                SetupBoneMatrixPointers( g_pFrameRoot );

                
            return S_OK;
            }


            //-----------------------------------------------------------------------------
            // Desc: 在此創建默認內存類型資源對象
            //-----------------------------------------------------------------------------
            HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                            
            const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
                                            
            void* pUserContext )
            {
                HRESULT hr;

                V_RETURN( g_DialogResourceManager.OnResetDevice() );
                V_RETURN( g_SettingsDlg.OnResetDevice() );

                
            //設置對話框位置和尺寸
                g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-1700 );
                g_HUD.SetSize( 
            170170 );
                g_SampleUI.SetLocation( pBackBufferSurfaceDesc
            ->Width-170
                                        pBackBufferSurfaceDesc
            ->Height-350 );
                g_SampleUI.SetSize( 
            170300 );

                
            //恢復字體
                if( g_pFont )
                    V_RETURN( g_pFont
            ->OnResetDevice() );
               
                
            //創建ID3DXSprite接口對象
                V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );

                
            //恢復效果對象
                if( g_pEffect )
                    V_RETURN( g_pEffect
            ->OnResetDevice() );

                
            //構造世界矩陣
                D3DXMatrixTranslation( &g_matWorld, 030-100 );

                
            //構造觀察矩陣
                D3DXVECTOR3 vEye( 00-1000 );
                D3DXVECTOR3 vAt( 
            000 );
                D3DXVECTOR3 vUp( 
            010 );
                D3DXMatrixLookAtLH( 
            &g_matView, &vEye, &vAt, &vUp);

                
            //構造投影矩陣
                D3DXMATRIXA16 matProj;
                
            float fAspectRatio = (float)pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height;
                D3DXMatrixPerspectiveFovLH( 
            &matProj, D3DX_PI/4, fAspectRatio, 1.0f2000.0f );;

                
            //為效果設置影矩陣
                V( g_pEffect->SetMatrix( "mProj"&matProj ) );

                
            //為效果設置燈光方向
                D3DXVECTOR4 vLightDir( 0.0f1.0f-1.0f0.0f );
                D3DXVec4Normalize( 
            &vLightDir, &vLightDir );
                V( g_pEffect
            ->SetVector( "lightDir"&vLightDir) );


                
            return S_OK;
            }


            //-----------------------------------------------------------------------------
            // Desc: 更新場景
            //-----------------------------------------------------------------------------
            void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, 
                                       
            float fElapsedTime, void* pUserContext )
            {
            }

            //------------------------------------------------------------------------------
            // Desc: 渲染網格模型
            //------------------------------------------------------------------------------
            void DrawMeshContainer( IDirect3DDevice9 *pd3dDevice, 
                                   LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase )
            {
                HRESULT hr;
                D3DXMESHCONTAINER_DERIVED 
            *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;
                D3DXFRAME_DERIVED 
            *pFrame = (D3DXFRAME_DERIVED*)pFrameBase;
                UINT iMaterial;
                UINT iAttrib;
                LPD3DXBONECOMBINATION pBoneComb;

                UINT iMatrixIndex;
                UINT iPaletteEntry;
                D3DXMATRIXA16 matTemp;
                D3DCAPS9 d3dCaps;
                pd3dDevice
            ->GetDeviceCaps( &d3dCaps );

                
            //檢查是否是蒙皮網格模型
                if (pMeshContainer->pSkinInfo != NULL)
                {
                        
            if (pMeshContainer->UseSoftwareVP)
                        {
                            V( pd3dDevice
            ->SetSoftwareVertexProcessing(TRUE) );
                        }

                        pBoneComb 
            = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->pBoneCombinationBuf->GetBufferPointer());
                        
            for (iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++)
                        { 
                            
            for (iPaletteEntry = 0; iPaletteEntry < pMeshContainer->NumPaletteEntries; ++iPaletteEntry)
                            {
                                iMatrixIndex 
            = pBoneComb[iAttrib].BoneId[iPaletteEntry];
                                
            if (iMatrixIndex != UINT_MAX)
                                {
                                    D3DXMatrixMultiply(
            &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex], pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex]);
                                    D3DXMatrixMultiply(
            &g_pBoneMatrices[iPaletteEntry], &matTemp, &g_matView);
                                }
                            }
                            V( g_pEffect
            ->SetMatrixArray( "mWorldMatrixArray", g_pBoneMatrices, pMeshContainer->NumPaletteEntries) );

                            D3DXCOLOR color1(pMeshContainer
            ->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D.Ambient);
                            D3DXCOLOR color2(
            0.250.250.251.0);
                            D3DXCOLOR ambEmm;
                            D3DXColorModulate(
            &ambEmm, &color1, &color2);
                            ambEmm 
            += D3DXCOLOR(pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D.Emissive);

                            
            //設置材質屬性
                            V( g_pEffect->SetVector("MaterialDiffuse", (D3DXVECTOR4*)&(pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D.Diffuse)) );
                            V( g_pEffect
            ->SetVector("MaterialAmbient", (D3DXVECTOR4*)&ambEmm) );

                            
            ///設置紋理
                            V( pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] ) );

                            
            //設置當前骨骼數量
                            V( g_pEffect->SetInt( "CurNumBones", pMeshContainer->NumInfl -1) );

                            
            //使用效果渲染網格
                            UINT numPasses;
                            V( g_pEffect
            ->Begin( &numPasses, D3DXFX_DONOTSAVESTATE ) );
                            
            for( UINT iPass = 0; iPass < numPasses; iPass++ )
                            {
                                V( g_pEffect
            ->BeginPass( iPass ) );
                                V( pMeshContainer
            ->MeshData.pMesh->DrawSubset( iAttrib ) );
                                V( g_pEffect
            ->EndPass() );
                            }
                            V( g_pEffect
            ->End() );

                            V( pd3dDevice
            ->SetVertexShader(NULL) );
                        }
                        
            if (pMeshContainer->UseSoftwareVP)
                        {
                            V( pd3dDevice
            ->SetSoftwareVertexProcessing(FALSE) );
                        }
                   

                }
                
            else
                {
                    V( pd3dDevice
            ->SetTransform(D3DTS_WORLD, &pFrame->CombinedTransformationMatrix) );

                    
            for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)
                    {
                        V( pd3dDevice
            ->SetMaterial( &pMeshContainer->pMaterials[iMaterial].MatD3D ) );
                        V( pd3dDevice
            ->SetTexture( 0, pMeshContainer->ppTextures[iMaterial] ) );
                        V( pMeshContainer
            ->MeshData.pMesh->DrawSubset(iMaterial) );
                    }
                }
            }


            //--------------------------------------------------------------------------------------
            // 渲染框架
            //--------------------------------------------------------------------------------------
            void DrawFrame( IDirect3DDevice9 *pd3dDevice, LPD3DXFRAME pFrame )
            {
                LPD3DXMESHCONTAINER pMeshContainer;

                pMeshContainer 
            = pFrame->pMeshContainer;
                
            while (pMeshContainer != NULL)
                {
                    DrawMeshContainer( pd3dDevice, pMeshContainer, pFrame );

                    pMeshContainer 
            = pMeshContainer->pNextMeshContainer;
                }

                
            if (pFrame->pFrameSibling != NULL)
                {
                    DrawFrame( pd3dDevice, pFrame
            ->pFrameSibling);
                }

                
            if (pFrame->pFrameFirstChild != NULL)
                {
                    DrawFrame( pd3dDevice, pFrame
            ->pFrameFirstChild );
                }
            }


            //-----------------------------------------------------------------------------
            // Desc: 渲染場景
            //-----------------------------------------------------------------------------
            void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, 
                                        
            float fElapsedTime, void* pUserContext )
            {
                HRESULT hr;
              
                
            //如果正在利用Direct3D設備設置對話框進行設置, 則不渲染場景
                if( g_SettingsDlg.IsActive() )
                {
                    g_SettingsDlg.OnRender( fElapsedTime );
                    
            return;
                }

                
            //清除后臺顏色緩沖區和深度緩沖區
                V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
                                     D3DCOLOR_ARGB(
            04550170), 1.0f0) );

                
            //渲染場景
                if( SUCCEEDED( pd3dDevice->BeginScene() ) )
                {
                    
            //渲染網格模型
                    if( g_pAnimController != NULL )
                        g_pAnimController
            ->AdvanceTime( fElapsedTime, NULL );
                    UpdateFrameMatrices( g_pFrameRoot, 
            &g_matWorld );
                    DrawFrame( pd3dDevice, g_pFrameRoot );

                    
            //渲染文本和控件
                    DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); 
                    RenderText();
                    V( g_HUD.OnRender( fElapsedTime ) );
                    V( g_SampleUI.OnRender( fElapsedTime ) );
                    DXUT_EndPerfEvent();

                    V( pd3dDevice
            ->EndScene() );
                }
            }


            //-----------------------------------------------------------------------------
            // Desc: 渲染文本
            //-----------------------------------------------------------------------------
            void RenderText()
            {
                CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 
            15 );

                
            //顯示當前Direct3D設備狀態和渲染幀速率
                txtHelper.Begin();
                txtHelper.SetInsertionPos( 
            55 );
                txtHelper.SetForegroundColor( D3DXCOLOR( 
            1.0f1.0f0.0f1.0f ) );
                txtHelper.DrawTextLine( DXUTGetFrameStats(
            true) );
                txtHelper.DrawTextLine( DXUTGetDeviceStats() );

                
            //顯示其他簡要信息
                txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f1.0f1.0f1.0f ) );
                txtHelper.DrawTextLine( L
            "通過HLSL編程實現蒙皮骨骼動畫" );
                
                
            //顯示簡單幫助文本
                const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
                
            if( g_bShowHelp )
                {
                    txtHelper.SetInsertionPos( 
            10, pd3dsdBackBuffer->Height-15*6 );
                    txtHelper.SetForegroundColor( D3DXCOLOR( 
            1.0f0.75f0.0f1.0f ) );
                    txtHelper.DrawTextLine( L
            "Controls (F1 to hide):" );

                    txtHelper.SetInsertionPos( 
            40, pd3dsdBackBuffer->Height-15*5 );
                    txtHelper.DrawTextLine( L
            "Quit: ESC" );
                }
                
            else
                {
                    txtHelper.SetInsertionPos( 
            10, pd3dsdBackBuffer->Height-15*2 );
                    txtHelper.SetForegroundColor( D3DXCOLOR( 
            1.0f1.0f1.0f1.0f ) );
                    txtHelper.DrawTextLine( L
            "Press F1 for help" );
                }
                txtHelper.End();
            }


            //-----------------------------------------------------------------------------
            // Desc: 消息處理
            //-----------------------------------------------------------------------------
            LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                                     
            bool* pbNoFurtherProcessing, void* pUserContext )
            {
                
            *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
                
            if*pbNoFurtherProcessing )
                    
            return 0;

                
            if( g_SettingsDlg.IsActive() )
                {
                    g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
                    
            return 0;
                }

                
            *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
                
            if*pbNoFurtherProcessing )
                    
            return 0;
               
                
            *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
                
            if*pbNoFurtherProcessing )
                    
            return 0;

                
            return 0;
            }


            //-----------------------------------------------------------------------------
            // Desc: 鍵盤消息處理
            //-----------------------------------------------------------------------------
            void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
            {
                
            if( bKeyDown )
                {
                    
            switch( nChar )
                    {
                        
            case VK_F1: g_bShowHelp = !g_bShowHelp; break;
                    }
                }
            }


            //-----------------------------------------------------------------------------
            // Desc: 處理各種控件消息
            //-----------------------------------------------------------------------------
            void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, 
                                     
            void* pUserContext )
            {
                
            switch( nControlID )
                {
                    
            case IDC_TOGGLEFULLSCREEN:
                        DXUTToggleFullScreen(); 
                        
            break;

                    
            case IDC_TOGGLEREF:
                        DXUTToggleREF(); 
                        
            break;

                    
            case IDC_CHANGEDEVICE:
                        g_SettingsDlg.SetActive( 
            !g_SettingsDlg.IsActive() ); 
                        
            break;
                }
            }


            //-----------------------------------------------------------------------------
            // Desc: 釋放在OnResetDevice()中創建的資源
            //-----------------------------------------------------------------------------
            void CALLBACK OnLostDevice( void* pUserContext )
            {
                g_DialogResourceManager.OnLostDevice();
                g_SettingsDlg.OnLostDevice();
                
            if( g_pFont )
                    g_pFont
            ->OnLostDevice();
                SAFE_RELEASE( g_pTextSprite );

                
            if( g_pEffect )
                    g_pEffect
            ->OnLostDevice();
            }


            //------------------------------------------------------------------------------
            // Desc: 釋放在OnCreateDevice()中創建的資源
            //------------------------------------------------------------------------------
            void CALLBACK OnDestroyDevice( void* pUserContext )
            {
                g_DialogResourceManager.OnDestroyDevice();
                g_SettingsDlg.OnDestroyDevice();
                SAFE_RELEASE( g_pFont );

                SAFE_RELEASE( g_pEffect );
                CAllocateHierarchy Alloc;
                D3DXFrameDestroy( g_pFrameRoot, 
            &Alloc );
                SAFE_RELEASE( g_pAnimController );
            }



            //--------------------------------------------------------------------------------------
            // Desc: 設置骨骼矩陣
            //--------------------------------------------------------------------------------------
            HRESULT SetupBoneMatrixPointersOnMesh( LPD3DXMESHCONTAINER pMeshContainerBase )
            {
                UINT iBone, cBones;
                D3DXFRAME_DERIVED 
            *pFrame;

                D3DXMESHCONTAINER_DERIVED 
            *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;

                
            //設置骨骼矩陣
                if (pMeshContainer->pSkinInfo != NULL)
                {
                    cBones 
            = pMeshContainer->pSkinInfo->GetNumBones();

                    pMeshContainer
            ->ppBoneMatrixPtrs = new D3DXMATRIX*[cBones];
                    
            if (pMeshContainer->ppBoneMatrixPtrs == NULL)
                        
            return E_OUTOFMEMORY;

                    
            for (iBone = 0; iBone < cBones; iBone++)
                    {
                        pFrame 
            = (D3DXFRAME_DERIVED*)D3DXFrameFind( g_pFrameRoot, 
                                                         pMeshContainer
            ->pSkinInfo->GetBoneName(iBone) );
                        
            if (pFrame == NULL)
                            
            return E_FAIL;

                        pMeshContainer
            ->ppBoneMatrixPtrs[iBone] = &pFrame->CombinedTransformationMatrix;
                    }
                }

                
            return S_OK;
            }


            //--------------------------------------------------------------------------------------
            // Desc: 設置骨骼矩陣指針
            //--------------------------------------------------------------------------------------
            HRESULT SetupBoneMatrixPointers( LPD3DXFRAME pFrame )
            {
                HRESULT hr;

                
            if (pFrame->pMeshContainer != NULL)
                {
                    hr 
            = SetupBoneMatrixPointersOnMesh(pFrame->pMeshContainer);
                    
            if (FAILED(hr))
                        
            return hr;
                }

                
            if (pFrame->pFrameSibling != NULL)
                {
                    hr 
            = SetupBoneMatrixPointers(pFrame->pFrameSibling);
                    
            if (FAILED(hr))
                        
            return hr;
                }

                
            if (pFrame->pFrameFirstChild != NULL)
                {
                    hr 
            = SetupBoneMatrixPointers(pFrame->pFrameFirstChild);
                    
            if (FAILED(hr))
                        
            return hr;
                }

                
            return S_OK;
            }




            //--------------------------------------------------------------------------------------
            // update the frame matrices
            //--------------------------------------------------------------------------------------
            void UpdateFrameMatrices( LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix )
            {
                D3DXFRAME_DERIVED 
            *pFrame = (D3DXFRAME_DERIVED*)pFrameBase;

                
            if (pParentMatrix != NULL)
                    D3DXMatrixMultiply(
            &pFrame->CombinedTransformationMatrix, &pFrame->TransformationMatrix, pParentMatrix);
                
            else
                    pFrame
            ->CombinedTransformationMatrix = pFrame->TransformationMatrix;

                
            if (pFrame->pFrameSibling != NULL)
                {
                    UpdateFrameMatrices(pFrame
            ->pFrameSibling, pParentMatrix);
                }

                
            if (pFrame->pFrameFirstChild != NULL)
                {
                    UpdateFrameMatrices(pFrame
            ->pFrameFirstChild, &pFrame->CombinedTransformationMatrix);
                }
            }















            posted on 2008-04-16 11:01 七星重劍 閱讀(1304) 評論(0)  編輯 收藏 引用 所屬分類: Game Graphics
            久久久久久亚洲精品不卡| 久久亚洲高清综合| 精品人妻伦九区久久AAA片69| 欧美激情精品久久久久| 99久久精品国产高清一区二区| 国产精品99久久久精品无码| 中文精品99久久国产 | 久久乐国产综合亚洲精品| 色综合久久最新中文字幕| 大伊人青草狠狠久久| 久久99精品久久只有精品 | 伊人久久大香线蕉av一区| 亚洲精品成人久久久| 亚洲人成电影网站久久| 亚洲国产天堂久久综合| 2021国产精品午夜久久| 精品国产青草久久久久福利| 国内精品久久久久影院薰衣草| 久久久久久曰本AV免费免费| 亚洲中文久久精品无码ww16| 日韩精品久久久久久久电影蜜臀| 日本强好片久久久久久AAA | 久久99国产精品久久| 久久久久久久综合日本亚洲 | 久久综合一区二区无码| 性做久久久久久久久久久| 99久久国产精品免费一区二区| 一本色道久久88—综合亚洲精品| 久久久久99精品成人片试看| 免费观看成人久久网免费观看| 久久99精品久久久久久9蜜桃| 无码任你躁久久久久久老妇| 亚洲AV无码久久| 狠狠色综合久久久久尤物| 性做久久久久久久久浪潮| 久久精品午夜一区二区福利| 99久久精品国产一区二区三区| 亚洲国产精品综合久久网络| 精品少妇人妻av无码久久| 国产精品美女久久久久av爽 | 色综合久久久久综合体桃花网|