zoukankan      html  css  js  c++  java
  • x文件处理的SkinnedMesh.h以及使用方法,从Direct3D sample改动得到

    //-------------------文件名为SkinnedMesh.h----------------------

    #ifndef __SkinnedMeshH__
    #define __SkinnedMeshH__

    #include <Windows.h>
    #include <MMSystem.h>
    #include <d3d9.h>
    #include <d3dx9.h>
    #pragma comment(lib, "d3d9.lib")
    #pragma comment(lib, "d3dx9.lib")
    #pragma comment(lib, "winmm.lib")
    #define V(x)           { hr = (x); }
    #define V_RETURN(x)    { hr = (x); if( FAILED(hr) ) { return hr; } }
    #define SAFE_DELETE(p)       { if (p) { delete (p);     (p)=NULL; } }
    #define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p);   (p)=NULL; } }
    #define SAFE_RELEASE(p)      { if (p) { (p)->Release(); (p)=NULL; } }
    struct D3DXFRAME_DERIVED : public D3DXFRAME
    {
     D3DXMATRIXA16 CombinedTransformationMatrix;
    };
    struct D3DXMESHCONTAINER_DERIVED : public D3DXMESHCONTAINER
    {
     LPDIRECT3DTEXTURE9* ppTextures;       // array of textures, entries are NULL if no texture specified   

     // SkinMesh info            
     LPD3DXMESH pOrigMesh;
     LPD3DXATTRIBUTERANGE pAttributeTable;
     DWORD NumAttributeGroups;
     DWORD NumInfl;
     LPD3DXBUFFER pBoneCombinationBuf;
     D3DXMATRIX** ppBoneMatrixPtrs;
     D3DXMATRIX* pBoneOffsetMatrices;
     DWORD NumPaletteEntries;
     bool UseSoftwareVP;
     DWORD iAttributeSW;     // used to denote the split between SW and HW if necessary for non-indexed skinning
    };
    class CAllocateHierarchy : public ID3DXAllocateHierarchy
    {
    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()
     {
     }
    };
    void DrawMeshContainer( IDirect3DDevice9* pd3dDevice, LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase );
    void DrawFrame( IDirect3DDevice9* pd3dDevice, LPD3DXFRAME pFrame );
    HRESULT SetupBoneMatrixPointersOnMesh( LPD3DXMESHCONTAINER pMeshContainer , LPD3DXFRAME pFrameRoot);
    HRESULT SetupBoneMatrixPointers( LPD3DXFRAME pFrame , LPD3DXFRAME pFrameRoot);
    void UpdateFrameMatrices( LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix );
    HRESULT GenerateSkinnedMesh( IDirect3DDevice9* pd3dDevice, D3DXMESHCONTAINER_DERIVED* pMeshContainer );
    void ReleaseAttributeTable( LPD3DXFRAME pFrameBase );
    HRESULT 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;
    }
    HRESULT CAllocateHierarchy::CreateFrame( LPCSTR Name, LPD3DXFRAME* ppNewFrame )
    {
     HRESULT hr = S_OK;
     D3DXFRAME_DERIVED* pFrame;
     *ppNewFrame = NULL;
     pFrame = new D3DXFRAME_DERIVED;
     if( pFrame == NULL )
     {
      hr = E_OUTOFMEMORY;
      goto e_Exit;
     }
     hr = AllocateName( Name, &pFrame->Name );
     if( FAILED( hr ) )
      goto e_Exit;
     D3DXMatrixIdentity( &pFrame->TransformationMatrix );
     D3DXMatrixIdentity( &pFrame->CombinedTransformationMatrix );
     pFrame->pMeshContainer = NULL;
     pFrame->pFrameSibling = NULL;
     pFrame->pFrameFirstChild = NULL;
     *ppNewFrame = pFrame;
     pFrame = NULL;
    e_Exit:
     delete pFrame;
     return hr;
    }
    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 iBone, cBones;
     LPDIRECT3DDEVICE9 pd3dDevice = NULL;
     LPD3DXMESH pMesh = NULL;
     *ppNewMeshContainer = NULL;
     if( pMeshData->Type != D3DXMESHTYPE_MESH )
     {
      hr = E_FAIL;
      goto e_Exit;
     }
     pMesh = pMeshData->pMesh;
     if( pMesh->GetFVF() == 0 )
     {
      hr = E_FAIL;
      goto e_Exit;
     }
     pMeshContainer = new D3DXMESHCONTAINER_DERIVED;
     if( pMeshContainer == NULL )
     {
      hr = E_OUTOFMEMORY;
      goto e_Exit;
     }
     memset( pMeshContainer, 0, sizeof( D3DXMESHCONTAINER_DERIVED ) );
     hr = AllocateName( Name, &pMeshContainer->Name );
     if( FAILED( hr ) )
      goto e_Exit;
     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 ) )
       goto e_Exit;
      pMesh = pMeshContainer->MeshData.pMesh;
      D3DXComputeNormals( pMesh, NULL );
     }
     else  // if no normals, just add a reference to the mesh for the mesh container
     {
      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 ) )
     {
      hr = E_OUTOFMEMORY;
      goto e_Exit;
     }
     memcpy( pMeshContainer->pAdjacency, pAdjacency, sizeof( DWORD ) * NumFaces*3 );
     memset( pMeshContainer->ppTextures, 0, sizeof( LPDIRECT3DTEXTURE9 ) * pMeshContainer->NumMaterials );
     if( NumMaterials > 0 )
     {
      memcpy( pMeshContainer->pMaterials, pMaterials, sizeof( D3DXMATERIAL ) * NumMaterials );

      for( iMaterial = 0; iMaterial < NumMaterials; iMaterial++ )
      {
       if( pMeshContainer->pMaterials[iMaterial].pTextureFilename != NULL )
       {
        if( FAILED( D3DXCreateTextureFromFileA( pd3dDevice, pMeshContainer->pMaterials[iMaterial].pTextureFilename,
         &pMeshContainer->ppTextures[iMaterial] ) ) )
         pMeshContainer->ppTextures[iMaterial] = NULL;
        pMeshContainer->pMaterials[iMaterial].pTextureFilename = NULL;
       }
      }
     }
     else // if no materials provided, use a default one
     {
      pMeshContainer->pMaterials[0].pTextureFilename = NULL;
      memset( &pMeshContainer->pMaterials[0].MatD3D, 0, sizeof( 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;
       goto e_Exit;
      }
      for( iBone = 0; iBone < cBones; iBone++ )
      {
       pMeshContainer->pBoneOffsetMatrices[iBone] = *( pMeshContainer->pSkinInfo->GetBoneOffsetMatrix( iBone ) );
      }
      hr = GenerateSkinnedMesh( pd3dDevice, pMeshContainer );
      if( FAILED( hr ) )
       goto e_Exit;
     }
     *ppNewMeshContainer = pMeshContainer;
     pMeshContainer = NULL;
    e_Exit:
     SAFE_RELEASE( pd3dDevice );
     if( pMeshContainer != NULL ) {
      DestroyMeshContainer( pMeshContainer );
     }
     return hr;
    }
    HRESULT CAllocateHierarchy::DestroyFrame( LPD3DXFRAME pFrameToFree )
    {
     SAFE_DELETE_ARRAY( pFrameToFree->Name );
     SAFE_DELETE( pFrameToFree );
     return S_OK;
    }
    HRESULT CAllocateHierarchy::DestroyMeshContainer( LPD3DXMESHCONTAINER pMeshContainerBase )
    {
     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;
    }
    HRESULT GenerateSkinnedMesh( IDirect3DDevice9* pd3dDevice, D3DXMESHCONTAINER_DERIVED* pMeshContainer )
    {
     HRESULT hr = S_OK;
     D3DCAPS9 d3dCaps;
     pd3dDevice->GetDeviceCaps( &d3dCaps );
     if( pMeshContainer->pSkinInfo == NULL )
      return hr;
     SAFE_RELEASE( pMeshContainer->MeshData.pMesh );
     SAFE_RELEASE( pMeshContainer->pBoneCombinationBuf );
     hr = pMeshContainer->pSkinInfo->ConvertToBlendedMesh
      (
      pMeshContainer->pOrigMesh,
      D3DXMESH_MANAGED | D3DXMESHOPT_VERTEXCACHE,
      pMeshContainer->pAdjacency,
      NULL, NULL, NULL,
      &pMeshContainer->NumInfl,
      &pMeshContainer->NumAttributeGroups,
      &pMeshContainer->pBoneCombinationBuf,
      &pMeshContainer->MeshData.pMesh
      );
     if( FAILED( hr ) )
      goto e_Exit;
     LPD3DXBONECOMBINATION rgBoneCombinations = reinterpret_cast<LPD3DXBONECOMBINATION>(
      pMeshContainer->pBoneCombinationBuf->GetBufferPointer() );
     for( pMeshContainer->iAttributeSW = 0; pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups;
      pMeshContainer->iAttributeSW++ )
     {
      DWORD cInfl = 0;
      for( DWORD iInfl = 0; iInfl < pMeshContainer->NumInfl; iInfl++ )
      {
       if( rgBoneCombinations[pMeshContainer->iAttributeSW].BoneId[iInfl] != UINT_MAX )
       {
        ++cInfl;
       }
      }
      if( cInfl > d3dCaps.MaxVertexBlendMatrices )
      {
       break;
      }
     }
     if( pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups )
     {
      LPD3DXMESH pMeshTmp;

      hr = pMeshContainer->MeshData.pMesh->CloneMeshFVF( D3DXMESH_SOFTWAREPROCESSING |
       pMeshContainer->MeshData.pMesh->GetOptions(),
       pMeshContainer->MeshData.pMesh->GetFVF(),
       pd3dDevice, &pMeshTmp );
      if( FAILED( hr ) )
      {
       goto e_Exit;
      }
      pMeshContainer->MeshData.pMesh->Release();
      pMeshContainer->MeshData.pMesh = pMeshTmp;
      pMeshTmp = NULL;
     }
    e_Exit:
     return hr;
    }
    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 NumBlend;
     UINT iAttrib;
     DWORD AttribIdPrev;
     LPD3DXBONECOMBINATION pBoneComb;
     UINT iMatrixIndex;
     D3DXMATRIXA16 matTemp;
     D3DCAPS9 d3dCaps;
     pd3dDevice->GetDeviceCaps( &d3dCaps );
     if( pMeshContainer->pSkinInfo != NULL )
     {
      AttribIdPrev = UNUSED32;
      pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>( pMeshContainer->pBoneCombinationBuf->GetBufferPointer
       () );
      for( iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++ )
      {
       NumBlend = 0;
       for( DWORD i = 0; i < pMeshContainer->NumInfl; ++i )
       {
        if( pBoneComb[iAttrib].BoneId[i] != UINT_MAX )
        {
         NumBlend = i;
        }
       }
       if( d3dCaps.MaxVertexBlendMatrices >= NumBlend + 1 )
       {
        for( DWORD i = 0; i < pMeshContainer->NumInfl; ++i )
        {
         iMatrixIndex = pBoneComb[iAttrib].BoneId[i];
         if( iMatrixIndex != UINT_MAX )
         {
          D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex],
           pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex] );
          V( pd3dDevice->SetTransform( D3DTS_WORLDMATRIX( i ), &matTemp ) );
         }
        }
        V( pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, NumBlend ) );
        if( ( AttribIdPrev != pBoneComb[iAttrib].AttribId ) || ( AttribIdPrev == UNUSED32 ) )
        {
         V( pd3dDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D )
          );
         V( pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] ) );
         AttribIdPrev = pBoneComb[iAttrib].AttribId;
        }
        V( pMeshContainer->MeshData.pMesh->DrawSubset( iAttrib ) );
       }
      }
      if( pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups )
      {
       AttribIdPrev = UNUSED32;
       V( pd3dDevice->SetSoftwareVertexProcessing( TRUE ) );
       for( iAttrib = pMeshContainer->iAttributeSW; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++ )
       {
        NumBlend = 0;
        for( DWORD i = 0; i < pMeshContainer->NumInfl; ++i )
        {
         if( pBoneComb[iAttrib].BoneId[i] != UINT_MAX )
         {
          NumBlend = i;
         }
        }
        if( d3dCaps.MaxVertexBlendMatrices < NumBlend + 1 )
        {
         for( DWORD i = 0; i < pMeshContainer->NumInfl; ++i )
         {
          iMatrixIndex = pBoneComb[iAttrib].BoneId[i];
          if( iMatrixIndex != UINT_MAX )
          {
           D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex],
            pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex] );
           V( pd3dDevice->SetTransform( D3DTS_WORLDMATRIX( i ), &matTemp ) );
          }
         }
         V( pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, NumBlend ) );
         if( ( AttribIdPrev != pBoneComb[iAttrib].AttribId ) || ( AttribIdPrev == UNUSED32 ) )
         {
          V( pd3dDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D
           ) );
          V( pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] ) );
          AttribIdPrev = pBoneComb[iAttrib].AttribId;
         }
         V( pMeshContainer->MeshData.pMesh->DrawSubset( iAttrib ) );
        }
       }
       V( pd3dDevice->SetSoftwareVertexProcessing( FALSE ) );
      }

      V( pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, 0 ) );
     }
     else  // standard mesh, just draw it after setting material properties
     {
      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 );
     }
    }
    HRESULT SetupBoneMatrixPointersOnMesh( LPD3DXMESHCONTAINER pMeshContainerBase , LPD3DXFRAME pFrameRoot)
    {
     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( pFrameRoot,
        pMeshContainer->pSkinInfo->GetBoneName( iBone ) );
       if( pFrame == NULL )
        return E_FAIL;
       pMeshContainer->ppBoneMatrixPtrs[iBone] = &pFrame->CombinedTransformationMatrix;
      }
     }
     return S_OK;
    }
    HRESULT SetupBoneMatrixPointers( LPD3DXFRAME pFrame , LPD3DXFRAME pFrameRoot)
    {
     HRESULT hr;
     if( pFrame->pMeshContainer != NULL )
     {
      hr = SetupBoneMatrixPointersOnMesh( pFrame->pMeshContainer , pFrameRoot);
      if( FAILED( hr ) )
       return hr;
     }
     if( pFrame->pFrameSibling != NULL )
     {
      hr = SetupBoneMatrixPointers( pFrame->pFrameSibling , pFrameRoot);
      if( FAILED( hr ) )
       return hr;
     }
     if( pFrame->pFrameFirstChild != NULL )
     {
      hr = SetupBoneMatrixPointers( pFrame->pFrameFirstChild , pFrameRoot);
      if( FAILED( hr ) )
       return hr;
     }
     return S_OK;
    }
    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 );
     }
    }
    void ReleaseAttributeTable( LPD3DXFRAME pFrameBase )
    {
     D3DXFRAME_DERIVED* pFrame = ( D3DXFRAME_DERIVED* )pFrameBase;
     D3DXMESHCONTAINER_DERIVED* pMeshContainer;
     pMeshContainer = ( D3DXMESHCONTAINER_DERIVED* )pFrame->pMeshContainer;
     while( pMeshContainer != NULL )
     {
      delete[] pMeshContainer->pAttributeTable;
      pMeshContainer = ( D3DXMESHCONTAINER_DERIVED* )pMeshContainer->pNextMeshContainer;
     }
     if( pFrame->pFrameSibling != NULL )
     {
      ReleaseAttributeTable( pFrame->pFrameSibling );
     }
     if( pFrame->pFrameFirstChild != NULL )
     {
      ReleaseAttributeTable( pFrame->pFrameFirstChild );
     }
    }

    #endif

    //----------------------------------------以下为使用方法举例------------------------------

    //#include "SkinnedMesh.h"
    //IDirect3DDevice9*           g_pDevice = NULL;
    //IDirect3D9*                 g_pD3d = NULL;
    //LPD3DXFRAME                 g_pFrameRoot1 = NULL;
    //ID3DXAnimationController*   g_pAnimController1 = NULL;
    //D3DXVECTOR3                 g_vObjectCenter1;        // Center of bounding sphere of object
    //FLOAT                       g_fObjectRadius1;        // Radius of bounding sphere of object
    //LPD3DXFRAME                 g_pFrameRoot2 = NULL;
    //ID3DXAnimationController*   g_pAnimController2 = NULL;
    //D3DXVECTOR3                 g_vObjectCenter2;        // Center of bounding sphere of object
    //FLOAT                       g_fObjectRadius2;        // Radius of bounding sphere of object
    //LPD3DXFRAME                 g_pFrameRoot3 = NULL;
    //ID3DXAnimationController*   g_pAnimController3 = NULL;
    //D3DXVECTOR3                 g_vObjectCenter3;        // Center of bounding sphere of object
    //FLOAT                       g_fObjectRadius3;        // Radius of bounding sphere of object
    //void Init()
    //{
    // CAllocateHierarchy Alloc;
    // D3DXLoadMeshHierarchyFromX( L"Mesh1.x", D3DXMESH_MANAGED, g_pDevice, //其中Mesh1.x、Mesh2.x、Mesh3为带蒙皮骨骼动画的x文件
    //  &Alloc, NULL, &g_pFrameRoot1, &g_pAnimController1 );
    // SetupBoneMatrixPointers( g_pFrameRoot1 , g_pFrameRoot1);
    // D3DXFrameCalculateBoundingSphere( g_pFrameRoot1, &g_vObjectCenter1, &g_fObjectRadius1 );
    // D3DXLoadMeshHierarchyFromX( L"Mesh2.x", D3DXMESH_MANAGED, g_pDevice,
    //  &Alloc, NULL, &g_pFrameRoot2, &g_pAnimController2 );
    // SetupBoneMatrixPointers( g_pFrameRoot2 , g_pFrameRoot2);
    // D3DXFrameCalculateBoundingSphere( g_pFrameRoot2, &g_vObjectCenter2, &g_fObjectRadius2 );
    // D3DXLoadMeshHierarchyFromX( L"Mesh3.x", D3DXMESH_MANAGED, g_pDevice,
    //  &Alloc, NULL, &g_pFrameRoot3, &g_pAnimController3 );
    // SetupBoneMatrixPointers( g_pFrameRoot3 , g_pFrameRoot3);
    // D3DXFrameCalculateBoundingSphere( g_pFrameRoot3, &g_vObjectCenter3, &g_fObjectRadius3 );
    //}
    //void Logic(float fElapsedTime)
    //{
    // g_pAnimController1->AdvanceTime(fElapsedTime, 0);
    // g_pAnimController2->AdvanceTime(fElapsedTime, 0);
    // g_pAnimController3->AdvanceTime(fElapsedTime, 0);
    // D3DXMATRIX matWorld;
    // D3DXMatrixIdentity(&matWorld);
    // matWorld._42 -= 100.0f;
    // matWorld._41 -= 100.0f;
    // UpdateFrameMatrices(g_pFrameRoot1, &matWorld);
    // matWorld._41 += 100.0f;
    // UpdateFrameMatrices(g_pFrameRoot2, &matWorld);
    // matWorld._41 += 100.0f;
    // UpdateFrameMatrices(g_pFrameRoot3, &matWorld);
    //}
    //void Render(float fElapsedTime)
    //{
    // g_pDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff707020, 1.0f, 0L );
    // g_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    // D3DLIGHT9 light;
    // ZeroMemory( &light, sizeof( D3DLIGHT9 ) );
    // light.Type = D3DLIGHT_DIRECTIONAL;
    // light.Diffuse.r = 1.0f;
    // light.Diffuse.g = 1.0f;
    // light.Diffuse.b = 1.0f;
    // light.Direction = D3DXVECTOR3(0.0f, -1.0f, 0.0f);
    // g_pDevice->SetLight(0, &light);
    // g_pDevice->LightEnable(0, TRUE);
    // light.Direction = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
    // g_pDevice->SetLight(1, &light);
    // g_pDevice->LightEnable(1, TRUE);
    // light.Direction = D3DXVECTOR3(-1.0f, 0.0f, 0.0f);
    // g_pDevice->SetLight(2, &light);
    // g_pDevice->LightEnable(2, TRUE);
    // light.Direction = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
    // g_pDevice->SetLight(3, &light);
    // g_pDevice->LightEnable(3, TRUE);
    // light.Direction = D3DXVECTOR3(0.0f, 0.0f, -1.0f);
    // g_pDevice->SetLight(4, &light);
    // g_pDevice->LightEnable(4, TRUE);
    // g_pDevice->BeginScene();
    // D3DXMATRIX matWorld;
    // D3DXMatrixIdentity(&matWorld);
    // g_pDevice->SetTransform(D3DTS_WORLD, &matWorld);
    // DrawFrame(g_pDevice, g_pFrameRoot1);
    // DrawFrame(g_pDevice, g_pFrameRoot2);
    // DrawFrame(g_pDevice, g_pFrameRoot3);
    // g_pDevice->EndScene();
    // g_pDevice->Present(0, 0, 0, 0);
    //}
    //LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    //{
    // if(uMsg == WM_KEYDOWN && wParam == VK_ESCAPE) PostQuitMessage(0);
    // return DefWindowProc(hWnd, uMsg, wParam, lParam);
    //}
    //INT WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE, LPWSTR, int )
    //{
    // WNDCLASS wc;
    // ZeroMemory(&wc, sizeof(WNDCLASS));
    // wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    // wc.hCursor = LoadCursor(0, IDC_ARROW);
    // wc.hIcon = LoadIcon(0, IDI_APPLICATION);
    // wc.hInstance = hInstance;
    // wc.lpfnWndProc = (WNDPROC)WndProc;
    // wc.lpszClassName = L"ClassName";
    // wc.style = CS_HREDRAW | CS_VREDRAW;
    // RegisterClassW(&wc);
    // D3DDISPLAYMODE d3ddm;
    // ZeroMemory(&d3ddm, sizeof(d3ddm));
    // g_pD3d = Direct3DCreate9(D3D_SDK_VERSION);
    // g_pD3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
    // HWND hWnd = CreateWindow(wc.lpszClassName, L"Application", WS_OVERLAPPED, 0, 0, 800, 600, 0, 0, hInstance, 0);
    // D3DCAPS9 caps;
    // g_pD3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
    // int vp = 0;
    // if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
    //  vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    // else
    //  vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    // D3DPRESENT_PARAMETERS d3dpp;
    // ZeroMemory(&d3dpp, sizeof(d3dpp));
    // d3dpp.BackBufferWidth            = d3ddm.Width;
    // d3dpp.BackBufferHeight           = d3ddm.Height;
    // d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
    // d3dpp.BackBufferCount            = 1;
    // d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
    // d3dpp.MultiSampleQuality         = 0;
    // d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;
    // d3dpp.hDeviceWindow              = hWnd;
    // d3dpp.Windowed                   = TRUE;
    // d3dpp.EnableAutoDepthStencil     = true;
    // d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
    // d3dpp.Flags                      = 0;
    // d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    // d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_ONE;
    // g_pD3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, vp, &d3dpp, &g_pDevice);
    // g_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    // g_pDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
    // D3DXMATRIX matWorld;
    // D3DXMatrixIdentity(&matWorld);
    // g_pDevice->SetTransform(D3DTS_WORLD, &matWorld);
    // D3DXMATRIX matView;
    // D3DXVECTOR3 vEyePos(0.0f, 0.0f, -400.0f);
    // D3DXVECTOR3 vLookAt(0.0f, 0.0f, 0.0f);
    // D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f);
    // D3DXMatrixLookAtLH(&matView, &vEyePos, &vLookAt, &vUp);
    // g_pDevice->SetTransform(D3DTS_VIEW, &matView);
    // D3DXMATRIX matProj;
    // D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI * 0.25f, 1366.0f/768.0f, 1.0f, 1000.0f);
    // g_pDevice->SetTransform(D3DTS_PROJECTION, &matProj);
    // g_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    // g_pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    // g_pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
    // Init();
    // ShowWindow(hWnd, SW_SHOW);
    // UpdateWindow(hWnd);
    // MSG msg;
    // ZeroMemory(&msg, sizeof(MSG));
    // while(msg.message != WM_QUIT)
    // {
    //  if(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
    //  {
    //   TranslateMessage(&msg);
    //   DispatchMessageA(&msg);
    //  }
    //  else
    //  {
    //   static float fLastTime = (float)timeGetTime();
    //   float fCurrentTime = (float)timeGetTime();
    //   float fElapsedTime = (fCurrentTime - fLastTime) * 0.001f;
    //   Logic(fElapsedTime);
    //   Render(fElapsedTime);
    //   fLastTime = fCurrentTime;
    //  }
    // }
    // ReleaseAttributeTable( g_pFrameRoot1 );
    // ReleaseAttributeTable( g_pFrameRoot2 );
    // ReleaseAttributeTable( g_pFrameRoot3 );
    //    return 0;
    //}

  • 相关阅读:
    移动开发学习touchmove
    webapp利用iscroll实现同时横滚|竖滚
    centos配置备忘(apachephpmysql)
    VMware ESXi 配置小结
    【C语言程序设计】C语言求自守数(详解版)
    世界500强企业面试题:猴子吃香蕉!这是人能想出来的答案?
    【C语言程序设计】C语言判断三角形的类型!
    拿什么来衡量程序员的生产力!代码量?开发速度?忙碌的状态?都不是!
    如果你拿到蚂蚁p7的offer,但是你正在国企拿着60+,你会如何选择?
    【C语言程序设计】汉诺塔问题,用C语言实现汉诺塔!
  • 原文地址:https://www.cnblogs.com/ketmales/p/2478043.html
Copyright © 2011-2022 走看看