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;
    //}

  • 相关阅读:
    android 多线程
    Uva 10881 Piotr’s Ants 蚂蚁
    LA 3708 Graveyard 墓地雕塑 NEERC 2006
    UVa 11300 Spreading the Wealth 分金币
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    HDU 4162 Shape Number
    HDU 1869 六度分离
    HDU 1041 Computer Transformation
    利用可变参数函数清空多个数组
  • 原文地址:https://www.cnblogs.com/ketmales/p/2478043.html
Copyright © 2011-2022 走看看