d3dfile.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:26k
源码类别:

游戏

开发平台:

Visual C++

  1. //-----------------------------------------------------------------------------
  2. // File: D3DFile.cpp
  3. //
  4. // Desc: Support code for loading DirectX .X files.
  5. //
  6. // Copyright (c) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #include "dxstdafx.h"
  9. #include <dxfile.h>
  10. #include <rmxfguid.h>
  11. #include <rmxftmpl.h>
  12. #include "D3DFile.h"
  13. //-----------------------------------------------------------------------------
  14. // Name:
  15. // Desc:
  16. //-----------------------------------------------------------------------------
  17. CD3DMesh::CD3DMesh( LPCTSTR strName )
  18. {
  19.     _tcsncpy( m_strName, strName, sizeof(m_strName) / sizeof(TCHAR) );
  20.     m_strName[sizeof(m_strName) / sizeof(TCHAR) - 1] = _T('');
  21.     m_pSysMemMesh        = NULL;
  22.     m_pLocalMesh         = NULL;
  23.     m_dwNumMaterials     = 0L;
  24.     m_pMaterials         = NULL;
  25.     m_pTextures          = NULL;
  26.     m_bUseMaterials      = TRUE;
  27. }
  28. //-----------------------------------------------------------------------------
  29. // Name:
  30. // Desc:
  31. //-----------------------------------------------------------------------------
  32. CD3DMesh::~CD3DMesh()
  33. {
  34.     Destroy();
  35. }
  36. //-----------------------------------------------------------------------------
  37. // Name:
  38. // Desc:
  39. //-----------------------------------------------------------------------------
  40. HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCTSTR strFilename )
  41. {
  42.     TCHAR        strPath[MAX_PATH];
  43.     LPD3DXBUFFER pAdjacencyBuffer = NULL;
  44.     LPD3DXBUFFER pMtrlBuffer = NULL;
  45.     HRESULT      hr;
  46.     // Find the path for the file, and convert it to ANSI (for the D3DX API)
  47.     DXUtil_FindMediaFileCb( strPath, sizeof(strPath), strFilename );
  48.     // Load the mesh
  49.     if( FAILED( hr = D3DXLoadMeshFromX( strPath, D3DXMESH_SYSTEMMEM, pd3dDevice, 
  50.                                         &pAdjacencyBuffer, &pMtrlBuffer, NULL,
  51.                                         &m_dwNumMaterials, &m_pSysMemMesh ) ) )
  52.     {
  53.         return hr;
  54.     }
  55.     // Optimize the mesh for performance
  56.     if( FAILED( hr = m_pSysMemMesh->OptimizeInplace(
  57.                         D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
  58.                         (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
  59.     {
  60.         SAFE_RELEASE( pAdjacencyBuffer );
  61.         SAFE_RELEASE( pMtrlBuffer );
  62.         return hr;
  63.     }
  64.     // Get material info for the mesh
  65.     // Get the array of materials out of the buffer
  66.     if( pMtrlBuffer && m_dwNumMaterials > 0 )
  67.     {
  68.         // Allocate memory for the materials and textures
  69.         D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();
  70.         m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials];
  71.         if( m_pMaterials == NULL )
  72.         {
  73.             hr = E_OUTOFMEMORY;
  74.             goto LEnd;
  75.         }
  76.         m_pTextures  = new LPDIRECT3DTEXTURE9[m_dwNumMaterials];
  77.         if( m_pTextures == NULL )
  78.         {
  79.             hr = E_OUTOFMEMORY;
  80.             goto LEnd;
  81.         }
  82.         // Copy each material and create its texture
  83.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  84.         {
  85.             // Copy the material
  86.             m_pMaterials[i]         = d3dxMtrls[i].MatD3D;
  87.             m_pTextures[i]          = NULL;
  88.             // Create a texture
  89.             if( d3dxMtrls[i].pTextureFilename )
  90.             {
  91.                 TCHAR strTexture[MAX_PATH];
  92.                 TCHAR strTextureTemp[MAX_PATH];
  93.                 DXUtil_ConvertAnsiStringToGenericCb( strTextureTemp, d3dxMtrls[i].pTextureFilename, sizeof(strTextureTemp) );
  94.                 DXUtil_FindMediaFileCb( strTexture, sizeof(strTexture), strTextureTemp );
  95.                 if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, 
  96.                                                        &m_pTextures[i] ) ) )
  97.                     m_pTextures[i] = NULL;
  98.             }
  99.         }
  100.     }
  101.     hr = S_OK;
  102. LEnd:
  103.     SAFE_RELEASE( pAdjacencyBuffer );
  104.     SAFE_RELEASE( pMtrlBuffer );
  105.     return hr;
  106. }
  107. //-----------------------------------------------------------------------------
  108. // Name:
  109. // Desc:
  110. //-----------------------------------------------------------------------------
  111. HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice,
  112.                           LPDIRECTXFILEDATA pFileData )
  113. {
  114.     LPD3DXBUFFER pMtrlBuffer = NULL;
  115.     LPD3DXBUFFER pAdjacencyBuffer = NULL;
  116.     HRESULT      hr;
  117.     // Load the mesh from the DXFILEDATA object
  118.     if( FAILED( hr = D3DXLoadMeshFromXof( pFileData, D3DXMESH_SYSTEMMEM, pd3dDevice,
  119.                                           &pAdjacencyBuffer, &pMtrlBuffer, NULL,
  120.                                           &m_dwNumMaterials, &m_pSysMemMesh ) ) )
  121.     {
  122.         return hr;
  123.     }
  124.     // Optimize the mesh for performance
  125.     if( FAILED( hr = m_pSysMemMesh->OptimizeInplace(
  126.                         D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
  127.                         (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
  128.     {
  129.         SAFE_RELEASE( pAdjacencyBuffer );
  130.         SAFE_RELEASE( pMtrlBuffer );
  131.         return hr;
  132.     }
  133.     // Get material info for the mesh
  134.     // Get the array of materials out of the buffer
  135.     if( pMtrlBuffer && m_dwNumMaterials > 0 )
  136.     {
  137.         // Allocate memory for the materials and textures
  138.         D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();
  139.         m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials];
  140.         if( m_pMaterials == NULL )
  141.         {
  142.             hr = E_OUTOFMEMORY;
  143.             goto LEnd;
  144.         }
  145.         m_pTextures  = new LPDIRECT3DTEXTURE9[m_dwNumMaterials];
  146.         if( m_pTextures == NULL )
  147.         {
  148.             hr = E_OUTOFMEMORY;
  149.             goto LEnd;
  150.         }
  151.         // Copy each material and create its texture
  152.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  153.         {
  154.             // Copy the material
  155.             m_pMaterials[i]         = d3dxMtrls[i].MatD3D;
  156.             m_pTextures[i]          = NULL;
  157.             // Create a texture
  158.             if( d3dxMtrls[i].pTextureFilename )
  159.             {
  160.                 TCHAR strTexture[MAX_PATH];
  161.                 TCHAR strTextureTemp[MAX_PATH];
  162.                 DXUtil_ConvertAnsiStringToGenericCb( strTextureTemp, d3dxMtrls[i].pTextureFilename, sizeof(strTextureTemp) );
  163.                 DXUtil_FindMediaFileCb( strTexture, sizeof(strTexture), strTextureTemp );
  164.                 if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, 
  165.                                                        &m_pTextures[i] ) ) )
  166.                     m_pTextures[i] = NULL;
  167.             }
  168.         }
  169.     }
  170.     hr = S_OK;
  171. LEnd:
  172.     SAFE_RELEASE( pAdjacencyBuffer );
  173.     SAFE_RELEASE( pMtrlBuffer );
  174.     return hr;
  175. }
  176. //-----------------------------------------------------------------------------
  177. // Name:
  178. // Desc:
  179. //-----------------------------------------------------------------------------
  180. HRESULT CD3DMesh::SetFVF( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwFVF )
  181. {
  182.     LPD3DXMESH pTempSysMemMesh = NULL;
  183.     LPD3DXMESH pTempLocalMesh  = NULL;
  184.     if( m_pSysMemMesh )
  185.     {
  186.         if( FAILED( m_pSysMemMesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM, dwFVF,
  187.                                                  pd3dDevice, &pTempSysMemMesh ) ) )
  188.             return E_FAIL;
  189.     }
  190.     if( m_pLocalMesh )
  191.     {
  192.         if( FAILED( m_pLocalMesh->CloneMeshFVF( 0L, dwFVF, pd3dDevice,
  193.                                                 &pTempLocalMesh ) ) )
  194.         {
  195.             SAFE_RELEASE( pTempSysMemMesh );
  196.             return E_FAIL;
  197.         }
  198.     }
  199.     SAFE_RELEASE( m_pSysMemMesh );
  200.     SAFE_RELEASE( m_pLocalMesh );
  201.     if( pTempSysMemMesh ) m_pSysMemMesh = pTempSysMemMesh;
  202.     if( pTempLocalMesh )  m_pLocalMesh  = pTempLocalMesh;
  203.     // Compute normals in case the meshes have them
  204.     if( m_pSysMemMesh )
  205.         D3DXComputeNormals( m_pSysMemMesh, NULL );
  206.     if( m_pLocalMesh )
  207.         D3DXComputeNormals( m_pLocalMesh, NULL );
  208.     return S_OK;
  209. }
  210. //-----------------------------------------------------------------------------
  211. // Name: CD3DMesh::SetVertexDecl
  212. // Desc: Convert the mesh to the format specified by the given vertex
  213. //       declarations.
  214. //-----------------------------------------------------------------------------
  215. HRESULT CD3DMesh::SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, D3DVERTEXELEMENT9 *pDecl )
  216. {
  217.     LPD3DXMESH pTempSysMemMesh = NULL;
  218.     LPD3DXMESH pTempLocalMesh  = NULL;
  219.     if( m_pSysMemMesh )
  220.     {
  221.         if( FAILED( m_pSysMemMesh->CloneMesh( D3DXMESH_SYSTEMMEM, pDecl,
  222.                                               pd3dDevice, &pTempSysMemMesh ) ) )
  223.             return E_FAIL;
  224.     }
  225.     if( m_pLocalMesh )
  226.     {
  227.         if( FAILED( m_pLocalMesh->CloneMesh( 0L, pDecl, pd3dDevice,
  228.                                              &pTempLocalMesh ) ) )
  229.         {
  230.             SAFE_RELEASE( pTempSysMemMesh );
  231.             return E_FAIL;
  232.         }
  233.     }
  234.     SAFE_RELEASE( m_pSysMemMesh );
  235.     SAFE_RELEASE( m_pLocalMesh );
  236.     if( pTempSysMemMesh )
  237.     {
  238.         m_pSysMemMesh = pTempSysMemMesh;
  239.         // Compute normals in case the meshes have them
  240.         D3DXComputeNormals( m_pSysMemMesh, NULL );
  241.     }
  242.     if( pTempLocalMesh )
  243.     {
  244.         m_pLocalMesh = pTempLocalMesh;
  245.         // Compute normals in case the meshes have them
  246.         D3DXComputeNormals( m_pLocalMesh, NULL );
  247.     }
  248.     return S_OK;
  249. }
  250. //-----------------------------------------------------------------------------
  251. // Name:
  252. // Desc:
  253. //-----------------------------------------------------------------------------
  254. HRESULT CD3DMesh::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )
  255. {
  256.     if( NULL == m_pSysMemMesh )
  257.         return E_FAIL;
  258.     // Make a local memory version of the mesh. Note: because we are passing in
  259.     // no flags, the default behavior is to clone into local memory.
  260.     if( FAILED( m_pSysMemMesh->CloneMeshFVF( D3DXMESH_MANAGED, m_pSysMemMesh->GetFVF(),
  261.                                              pd3dDevice, &m_pLocalMesh ) ) )
  262.         return E_FAIL;
  263.     return S_OK;
  264. }
  265. //-----------------------------------------------------------------------------
  266. // Name:
  267. // Desc:
  268. //-----------------------------------------------------------------------------
  269. HRESULT CD3DMesh::InvalidateDeviceObjects()
  270. {
  271.     SAFE_RELEASE( m_pLocalMesh );
  272.     return S_OK;
  273. }
  274. //-----------------------------------------------------------------------------
  275. // Name:
  276. // Desc:
  277. //-----------------------------------------------------------------------------
  278. HRESULT CD3DMesh::Destroy()
  279. {
  280.     InvalidateDeviceObjects();
  281.     for( UINT i=0; i<m_dwNumMaterials; i++ )
  282.         SAFE_RELEASE( m_pTextures[i] );
  283.     SAFE_DELETE_ARRAY( m_pTextures );
  284.     SAFE_DELETE_ARRAY( m_pMaterials );
  285.     SAFE_RELEASE( m_pSysMemMesh );
  286.     m_dwNumMaterials = 0L;
  287.     return S_OK;
  288. }
  289. //-----------------------------------------------------------------------------
  290. // Name:
  291. // Desc:
  292. //-----------------------------------------------------------------------------
  293. HRESULT CD3DMesh::Render( LPDIRECT3DDEVICE9 pd3dDevice, bool bDrawOpaqueSubsets,
  294.                           bool bDrawAlphaSubsets )
  295. {
  296.     if( NULL == m_pLocalMesh )
  297.         return E_FAIL;
  298.     // Frist, draw the subsets without alpha
  299.     if( bDrawOpaqueSubsets )
  300.     {
  301.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  302.         {
  303.             if( m_bUseMaterials )
  304.             {
  305.                 if( m_pMaterials[i].Diffuse.a < 1.0f )
  306.                     continue;
  307.                 pd3dDevice->SetMaterial( &m_pMaterials[i] );
  308.                 pd3dDevice->SetTexture( 0, m_pTextures[i] );
  309.             }
  310.             m_pLocalMesh->DrawSubset( i );
  311.         }
  312.     }
  313.     // Then, draw the subsets with alpha
  314.     if( bDrawAlphaSubsets && m_bUseMaterials )
  315.     {
  316.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  317.         {
  318.             if( m_pMaterials[i].Diffuse.a == 1.0f )
  319.                 continue;
  320.             // Set the material and texture
  321.             pd3dDevice->SetMaterial( &m_pMaterials[i] );
  322.             pd3dDevice->SetTexture( 0, m_pTextures[i] );
  323.             m_pLocalMesh->DrawSubset( i );
  324.         }
  325.     }
  326.     return S_OK;
  327. }
  328. //-----------------------------------------------------------------------------
  329. // Name:
  330. // Desc:
  331. //-----------------------------------------------------------------------------
  332. CD3DFrame::CD3DFrame( LPCTSTR strName )
  333. {
  334.     _tcsncpy( m_strName, strName, sizeof(m_strName) / sizeof(TCHAR) );
  335.     m_strName[sizeof(m_strName) / sizeof(TCHAR) - 1] = _T('');
  336.     D3DXMatrixIdentity( &m_mat );
  337.     m_pMesh  = NULL;
  338.     m_pChild = NULL;
  339.     m_pNext  = NULL;
  340. }
  341. //-----------------------------------------------------------------------------
  342. // Name:
  343. // Desc:
  344. //-----------------------------------------------------------------------------
  345. CD3DFrame::~CD3DFrame()
  346. {
  347.     SAFE_DELETE( m_pChild );
  348.     SAFE_DELETE( m_pNext );
  349. }
  350. //-----------------------------------------------------------------------------
  351. // Name:
  352. // Desc:
  353. //-----------------------------------------------------------------------------
  354. bool CD3DFrame::EnumMeshes( bool (*EnumMeshCB)(CD3DMesh*,void*),
  355.                             void* pContext )
  356. {
  357.     if( m_pMesh )
  358.         EnumMeshCB( m_pMesh, pContext );
  359.     if( m_pChild )
  360.         m_pChild->EnumMeshes( EnumMeshCB, pContext );
  361.     if( m_pNext )
  362.         m_pNext->EnumMeshes( EnumMeshCB, pContext );
  363.     return TRUE;
  364. }
  365. //-----------------------------------------------------------------------------
  366. // Name:
  367. // Desc:
  368. //-----------------------------------------------------------------------------
  369. CD3DMesh* CD3DFrame::FindMesh( LPCTSTR strMeshName )
  370. {
  371.     CD3DMesh* pMesh;
  372.     if( m_pMesh )
  373.         if( !lstrcmpi( m_pMesh->m_strName, strMeshName ) )
  374.             return m_pMesh;
  375.     if( m_pChild )
  376.         if( NULL != ( pMesh = m_pChild->FindMesh( strMeshName ) ) )
  377.             return pMesh;
  378.     if( m_pNext )
  379.         if( NULL != ( pMesh = m_pNext->FindMesh( strMeshName ) ) )
  380.             return pMesh;
  381.     return NULL;
  382. }
  383. //-----------------------------------------------------------------------------
  384. // Name:
  385. // Desc:
  386. //-----------------------------------------------------------------------------
  387. CD3DFrame* CD3DFrame::FindFrame( LPCTSTR strFrameName )
  388. {
  389.     CD3DFrame* pFrame;
  390.     if( !lstrcmpi( m_strName, strFrameName ) )
  391.         return this;
  392.     if( m_pChild )
  393.         if( NULL != ( pFrame = m_pChild->FindFrame( strFrameName ) ) )
  394.             return pFrame;
  395.     if( m_pNext )
  396.         if( NULL != ( pFrame = m_pNext->FindFrame( strFrameName ) ) )
  397.             return pFrame;
  398.     return NULL;
  399. }
  400. //-----------------------------------------------------------------------------
  401. // Name:
  402. // Desc:
  403. //-----------------------------------------------------------------------------
  404. HRESULT CD3DFrame::Destroy()
  405. {
  406.     if( m_pMesh )  m_pMesh->Destroy();
  407.     if( m_pChild ) m_pChild->Destroy();
  408.     if( m_pNext )  m_pNext->Destroy();
  409.     SAFE_DELETE( m_pMesh );
  410.     SAFE_DELETE( m_pNext );
  411.     SAFE_DELETE( m_pChild );
  412.     return S_OK;
  413. }
  414. //-----------------------------------------------------------------------------
  415. // Name:
  416. // Desc:
  417. //-----------------------------------------------------------------------------
  418. HRESULT CD3DFrame::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )
  419. {
  420.     if( m_pMesh )  m_pMesh->RestoreDeviceObjects( pd3dDevice );
  421.     if( m_pChild ) m_pChild->RestoreDeviceObjects( pd3dDevice );
  422.     if( m_pNext )  m_pNext->RestoreDeviceObjects( pd3dDevice );
  423.     return S_OK;
  424. }
  425. //-----------------------------------------------------------------------------
  426. // Name:
  427. // Desc:
  428. //-----------------------------------------------------------------------------
  429. HRESULT CD3DFrame::InvalidateDeviceObjects()
  430. {
  431.     if( m_pMesh )  m_pMesh->InvalidateDeviceObjects();
  432.     if( m_pChild ) m_pChild->InvalidateDeviceObjects();
  433.     if( m_pNext )  m_pNext->InvalidateDeviceObjects();
  434.     return S_OK;
  435. }
  436. //-----------------------------------------------------------------------------
  437. // Name:
  438. // Desc:
  439. //-----------------------------------------------------------------------------
  440. HRESULT CD3DFrame::Render( LPDIRECT3DDEVICE9 pd3dDevice, bool bDrawOpaqueSubsets,
  441.                            bool bDrawAlphaSubsets, D3DXMATRIX* pmatWorldMatrix )
  442. {
  443.     // For pure devices, specify the world transform. If the world transform is not
  444.     // specified on pure devices, this function will fail.
  445.     D3DXMATRIXA16 matSavedWorld, matWorld;
  446.     if ( NULL == pmatWorldMatrix )
  447.         pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
  448.     else
  449.         matSavedWorld = *pmatWorldMatrix;
  450.     D3DXMatrixMultiply( &matWorld, &m_mat, &matSavedWorld );
  451.     pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  452.     if( m_pMesh )
  453.         m_pMesh->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets );
  454.     if( m_pChild )
  455.         m_pChild->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matWorld );
  456.     pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
  457.     if( m_pNext )
  458.         m_pNext->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matSavedWorld );
  459.     return S_OK;
  460. }
  461. //-----------------------------------------------------------------------------
  462. // Name:
  463. // Desc:
  464. //-----------------------------------------------------------------------------
  465. HRESULT CD3DFile::LoadFrame( LPDIRECT3DDEVICE9 pd3dDevice,
  466.                              LPDIRECTXFILEDATA pFileData,
  467.                              CD3DFrame* pParentFrame )
  468. {
  469.     LPDIRECTXFILEDATA   pChildData = NULL;
  470.     LPDIRECTXFILEOBJECT pChildObj = NULL;
  471.     const GUID* pGUID;
  472.     DWORD       cbSize;
  473.     CD3DFrame*  pCurrentFrame;
  474.     HRESULT     hr;
  475.     // Get the type of the object
  476.     if( FAILED( hr = pFileData->GetType( &pGUID ) ) )
  477.         return hr;
  478.     if( *pGUID == TID_D3DRMMesh )
  479.     {
  480.         hr = LoadMesh( pd3dDevice, pFileData, pParentFrame );
  481.         if( FAILED(hr) )
  482.             return hr;
  483.     }
  484.     if( *pGUID == TID_D3DRMFrameTransformMatrix )
  485.     {
  486.         D3DXMATRIX* pmatMatrix;
  487.         hr = pFileData->GetData( NULL, &cbSize, (void**)&pmatMatrix );
  488.         if( FAILED(hr) )
  489.             return hr;
  490.         // Update the parent's matrix with the new one
  491.         pParentFrame->SetMatrix( pmatMatrix );
  492.     }
  493.     if( *pGUID == TID_D3DRMFrame )
  494.     {
  495.         // Get the frame name
  496.         CHAR  strAnsiName[512] = "";
  497.         TCHAR strName[512];
  498.         DWORD dwNameLength = 512;
  499.         if( FAILED( hr = pFileData->GetName( strAnsiName, &dwNameLength ) ) )
  500.             return hr;
  501.         DXUtil_ConvertAnsiStringToGenericCb( strName, strAnsiName, sizeof(strName) );
  502.         // Create the frame
  503.         pCurrentFrame = new CD3DFrame( strName );
  504.         if( pCurrentFrame == NULL )
  505.             return E_OUTOFMEMORY;
  506.         pCurrentFrame->m_pNext = pParentFrame->m_pChild;
  507.         pParentFrame->m_pChild = pCurrentFrame;
  508.         // Enumerate child objects
  509.         while( SUCCEEDED( pFileData->GetNextObject( &pChildObj ) ) )
  510.         {
  511.             // Query the child for its FileData
  512.             hr = pChildObj->QueryInterface( IID_IDirectXFileData,
  513.                                             (void**)&pChildData );
  514.             if( SUCCEEDED(hr) )
  515.             {
  516.                 hr = LoadFrame( pd3dDevice, pChildData, pCurrentFrame );
  517.                 pChildData->Release();
  518.             }
  519.             pChildObj->Release();
  520.             if( FAILED(hr) )
  521.                 return hr;
  522.         }
  523.     }
  524.     return S_OK;
  525. }
  526. //-----------------------------------------------------------------------------
  527. // Name:
  528. // Desc:
  529. //-----------------------------------------------------------------------------
  530. HRESULT CD3DFile::LoadMesh( LPDIRECT3DDEVICE9 pd3dDevice,
  531.                             LPDIRECTXFILEDATA pFileData,
  532.                             CD3DFrame* pParentFrame )
  533. {
  534.     // Currently only allowing one mesh per frame
  535.     if( pParentFrame->m_pMesh )
  536.         return E_FAIL;
  537.     // Get the mesh name
  538.     CHAR  strAnsiName[512] = {0};
  539.     TCHAR strName[512];
  540.     DWORD dwNameLength = 512;
  541.     HRESULT hr;
  542.     if( FAILED( hr = pFileData->GetName( strAnsiName, &dwNameLength ) ) )
  543.         return hr;
  544.     DXUtil_ConvertAnsiStringToGenericCb( strName, strAnsiName, sizeof(strName) );
  545.     // Create the mesh
  546.     pParentFrame->m_pMesh = new CD3DMesh( strName );
  547.     if( pParentFrame->m_pMesh == NULL )
  548.         return E_OUTOFMEMORY;
  549.     pParentFrame->m_pMesh->Create( pd3dDevice, pFileData );
  550.     return S_OK;
  551. }
  552. //-----------------------------------------------------------------------------
  553. // Name:
  554. // Desc:
  555. //-----------------------------------------------------------------------------
  556. HRESULT CD3DFile::CreateFromResource( LPDIRECT3DDEVICE9 pd3dDevice, LPCTSTR strResource, LPCTSTR strType )
  557. {
  558.     LPDIRECTXFILE           pDXFile   = NULL;
  559.     LPDIRECTXFILEENUMOBJECT pEnumObj  = NULL;
  560.     LPDIRECTXFILEDATA       pFileData = NULL;
  561.     HRESULT hr;
  562.     // Create a x file object
  563.     if( FAILED( hr = DirectXFileCreate( &pDXFile ) ) )
  564.         return E_FAIL;
  565.     // Register templates for d3drm and patch extensions.
  566.     if( FAILED( hr = pDXFile->RegisterTemplates( (void*)D3DRM_XTEMPLATES,
  567.                                                  D3DRM_XTEMPLATE_BYTES ) ) )
  568.     {
  569.         pDXFile->Release();
  570.         return E_FAIL;
  571.     }
  572.     
  573.     CHAR strTypeAnsi[MAX_PATH];
  574.     DXUtil_ConvertGenericStringToAnsiCb( strTypeAnsi, strType, sizeof(strTypeAnsi) );
  575.     DXFILELOADRESOURCE dxlr;
  576.     dxlr.hModule = NULL;
  577.     dxlr.lpName = strResource;
  578.     dxlr.lpType = (TCHAR*) strTypeAnsi;
  579.     // Create enum object
  580.     hr = pDXFile->CreateEnumObject( (void*)&dxlr, DXFILELOAD_FROMRESOURCE, 
  581.                                     &pEnumObj );
  582.     if( FAILED(hr) )
  583.     {
  584.         pDXFile->Release();
  585.         return hr;
  586.     }
  587.     // Enumerate top level objects (which are always frames)
  588.     while( SUCCEEDED( pEnumObj->GetNextDataObject( &pFileData ) ) )
  589.     {
  590.         hr = LoadFrame( pd3dDevice, pFileData, this );
  591.         pFileData->Release();
  592.         if( FAILED(hr) )
  593.         {
  594.             pEnumObj->Release();
  595.             pDXFile->Release();
  596.             return E_FAIL;
  597.         }
  598.     }
  599.     SAFE_RELEASE( pFileData );
  600.     SAFE_RELEASE( pEnumObj );
  601.     SAFE_RELEASE( pDXFile );
  602.     return S_OK;
  603. }
  604. //-----------------------------------------------------------------------------
  605. // Name:
  606. // Desc:
  607. //-----------------------------------------------------------------------------
  608. HRESULT CD3DFile::Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCTSTR strFilename )
  609. {
  610.     LPDIRECTXFILE           pDXFile   = NULL;
  611.     LPDIRECTXFILEENUMOBJECT pEnumObj  = NULL;
  612.     LPDIRECTXFILEDATA       pFileData = NULL;
  613.     HRESULT hr;
  614.     // Create a x file object
  615.     if( FAILED( hr = DirectXFileCreate( &pDXFile ) ) )
  616.         return E_FAIL;
  617.     // Register templates for d3drm and patch extensions.
  618.     if( FAILED( hr = pDXFile->RegisterTemplates( (void*)D3DRM_XTEMPLATES,
  619.                                                  D3DRM_XTEMPLATE_BYTES ) ) )
  620.     {
  621.         pDXFile->Release();
  622.         return E_FAIL;
  623.     }
  624.     // Find the path to the file, and convert it to ANSI (for the D3DXOF API)
  625.     TCHAR strPath[MAX_PATH];
  626.     CHAR  strPathANSI[MAX_PATH];
  627.     DXUtil_FindMediaFileCb( strPath, sizeof(strPath), strFilename );
  628.     DXUtil_ConvertGenericStringToAnsiCb( strPathANSI, strPath, sizeof(strPathANSI) );
  629.     
  630.     // Create enum object
  631.     hr = pDXFile->CreateEnumObject( (void*)strPathANSI, DXFILELOAD_FROMFILE, 
  632.                                     &pEnumObj );
  633.     if( FAILED(hr) )
  634.     {
  635.         pDXFile->Release();
  636.         return hr;
  637.     }
  638.     // Enumerate top level objects (which are always frames)
  639.     while( SUCCEEDED( pEnumObj->GetNextDataObject( &pFileData ) ) )
  640.     {
  641.         hr = LoadFrame( pd3dDevice, pFileData, this );
  642.         pFileData->Release();
  643.         if( FAILED(hr) )
  644.         {
  645.             pEnumObj->Release();
  646.             pDXFile->Release();
  647.             return E_FAIL;
  648.         }
  649.     }
  650.     SAFE_RELEASE( pFileData );
  651.     SAFE_RELEASE( pEnumObj );
  652.     SAFE_RELEASE( pDXFile );
  653.     return S_OK;
  654. }
  655. //-----------------------------------------------------------------------------
  656. // Name:
  657. // Desc:
  658. //-----------------------------------------------------------------------------
  659. HRESULT CD3DFile::Render( LPDIRECT3DDEVICE9 pd3dDevice, D3DXMATRIX* pmatWorldMatrix )
  660. {
  661.     // For pure devices, specify the world transform. If the world transform is not
  662.     // specified on pure devices, this function will fail.
  663.     // Set up the world transformation
  664.     D3DXMATRIX matSavedWorld, matWorld;
  665.     if ( NULL == pmatWorldMatrix )
  666.         pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
  667.     else
  668.         matSavedWorld = *pmatWorldMatrix;
  669.     D3DXMatrixMultiply( &matWorld, &matSavedWorld, &m_mat );
  670.     pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  671.     // Render opaque subsets in the meshes
  672.     if( m_pChild )
  673.         m_pChild->Render( pd3dDevice, TRUE, FALSE, &matWorld );
  674.     // Enable alpha blending
  675.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  676.     pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
  677.     pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  678.     // Render alpha subsets in the meshes
  679.     if( m_pChild )
  680.         m_pChild->Render( pd3dDevice, FALSE, TRUE, &matWorld );
  681.     // Restore state
  682.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  683.     pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
  684.     return S_OK;
  685. }