home *** CD-ROM | disk | FTP | other *** search
/ Game Programming in C++ - Start to Finish / GameProgrammingS.iso / developer_install / ReplicaNetFreewareV5_4.exe / data1.cab / Program_Executable_Files / Common3DApp / Src / d3dfile.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-10-30  |  20.5 KB  |  710 lines

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