home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Game Programming for Teens / VBGPFT.cdr / DirectX8 / dx8a_sdk.exe / samples / multimedia / common / src / d3dfile.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-04  |  20.2 KB  |  702 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.     // Compute normals in case the meshes have them
  202.     if( m_pSysMemMesh )
  203.         D3DXComputeNormals( m_pSysMemMesh );
  204.     if( m_pLocalMesh )
  205.         D3DXComputeNormals( m_pLocalMesh );
  206.  
  207.     return S_OK;
  208. }
  209.  
  210.  
  211.  
  212.  
  213. //-----------------------------------------------------------------------------
  214. // Name:
  215. // Desc:
  216. //-----------------------------------------------------------------------------
  217. HRESULT CD3DMesh::RestoreDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice )
  218. {
  219.     if( NULL == m_pSysMemMesh )
  220.         return E_FAIL;
  221.  
  222.     // Make a local memory version of the mesh. Note: because we are passing in
  223.     // no flags, the default behavior is to clone into local memory.
  224.     if( FAILED( m_pSysMemMesh->CloneMeshFVF( 0L, m_pSysMemMesh->GetFVF(),
  225.                                              pd3dDevice, &m_pLocalMesh ) ) )
  226.         return E_FAIL;
  227.  
  228.     return S_OK;
  229.  
  230. }
  231.  
  232.  
  233.  
  234.  
  235. //-----------------------------------------------------------------------------
  236. // Name:
  237. // Desc:
  238. //-----------------------------------------------------------------------------
  239. HRESULT CD3DMesh::InvalidateDeviceObjects()
  240. {
  241.     SAFE_RELEASE( m_pLocalMesh );
  242.  
  243.     return S_OK;
  244. }
  245.  
  246.  
  247.  
  248.  
  249. //-----------------------------------------------------------------------------
  250. // Name:
  251. // Desc:
  252. //-----------------------------------------------------------------------------
  253. HRESULT CD3DMesh::Destroy()
  254. {
  255.     InvalidateDeviceObjects();
  256.     for( UINT i=0; i<m_dwNumMaterials; i++ )
  257.         SAFE_RELEASE( m_pTextures[i] );
  258.     SAFE_DELETE_ARRAY( m_pTextures );
  259.     SAFE_DELETE_ARRAY( m_pMaterials );
  260.  
  261.     SAFE_RELEASE( m_pSysMemMesh );
  262.  
  263.     m_dwNumMaterials = 0L;
  264.  
  265.     return S_OK;
  266. }
  267.  
  268.  
  269.  
  270.  
  271. //-----------------------------------------------------------------------------
  272. // Name:
  273. // Desc:
  274. //-----------------------------------------------------------------------------
  275. HRESULT CD3DMesh::Render( LPDIRECT3DDEVICE8 pd3dDevice, BOOL bDrawOpaqueSubsets,
  276.                           BOOL bDrawAlphaSubsets )
  277. {
  278.     if( NULL == m_pLocalMesh )
  279.         return E_FAIL;
  280.  
  281.     // Frist, draw the subsets without alpha
  282.     if( bDrawOpaqueSubsets )
  283.     {
  284.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  285.         {
  286.             if( m_bUseMaterials )
  287.             {
  288.                 if( m_pMaterials[i].Diffuse.a < 1.0f )
  289.                     continue;
  290.                 pd3dDevice->SetMaterial( &m_pMaterials[i] );
  291.                 pd3dDevice->SetTexture( 0, m_pTextures[i] );
  292.             }
  293.             m_pLocalMesh->DrawSubset( i );
  294.         }
  295.     }
  296.  
  297.     // Then, draw the subsets with alpha
  298.     if( bDrawAlphaSubsets && m_bUseMaterials )
  299.     {
  300.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  301.         {
  302.             if( m_pMaterials[i].Diffuse.a == 1.0f )
  303.                 continue;
  304.  
  305.             // Set the material and texture
  306.             pd3dDevice->SetMaterial( &m_pMaterials[i] );
  307.             pd3dDevice->SetTexture( 0, m_pTextures[i] );
  308.             m_pLocalMesh->DrawSubset( i );
  309.         }
  310.     }
  311.  
  312.     return S_OK;
  313. }
  314.  
  315.  
  316.  
  317.  
  318. //-----------------------------------------------------------------------------
  319. // Name:
  320. // Desc:
  321. //-----------------------------------------------------------------------------
  322. CD3DFrame::CD3DFrame( TCHAR* strName )
  323. {
  324.     _tcscpy( m_strName, strName );
  325.     D3DXMatrixIdentity( &m_mat );
  326.     m_pMesh  = NULL;
  327.  
  328.     m_pChild = NULL;
  329.     m_pNext  = NULL;
  330. }
  331.  
  332.  
  333.  
  334.  
  335. //-----------------------------------------------------------------------------
  336. // Name:
  337. // Desc:
  338. //-----------------------------------------------------------------------------
  339. CD3DFrame::~CD3DFrame()
  340. {
  341.     SAFE_DELETE( m_pChild );
  342.     SAFE_DELETE( m_pNext );
  343. }
  344.  
  345.  
  346.  
  347.  
  348. //-----------------------------------------------------------------------------
  349. // Name:
  350. // Desc:
  351. //-----------------------------------------------------------------------------
  352. BOOL CD3DFrame::EnumMeshes( BOOL (*EnumMeshCB)(CD3DMesh*,VOID*),
  353.                             VOID* pContext )
  354. {
  355.     if( m_pMesh )
  356.         EnumMeshCB( m_pMesh, pContext );
  357.     if( m_pChild )
  358.         m_pChild->EnumMeshes( EnumMeshCB, pContext );
  359.     if( m_pNext )
  360.         m_pNext->EnumMeshes( EnumMeshCB, pContext );
  361.  
  362.     return TRUE;
  363. }
  364.  
  365.  
  366.  
  367.  
  368. //-----------------------------------------------------------------------------
  369. // Name:
  370. // Desc:
  371. //-----------------------------------------------------------------------------
  372. CD3DMesh* CD3DFrame::FindMesh( TCHAR* strMeshName )
  373. {
  374.     CD3DMesh* pMesh;
  375.  
  376.     if( m_pMesh )
  377.         if( !lstrcmpi( m_pMesh->m_strName, strMeshName ) )
  378.             return m_pMesh;
  379.  
  380.     if( m_pChild )
  381.         if( NULL != ( pMesh = m_pChild->FindMesh( strMeshName ) ) )
  382.             return pMesh;
  383.  
  384.     if( m_pNext )
  385.         if( NULL != ( pMesh = m_pNext->FindMesh( strMeshName ) ) )
  386.             return pMesh;
  387.  
  388.     return NULL;
  389. }
  390.  
  391.  
  392.  
  393.  
  394. //-----------------------------------------------------------------------------
  395. // Name:
  396. // Desc:
  397. //-----------------------------------------------------------------------------
  398. CD3DFrame* CD3DFrame::FindFrame( TCHAR* strFrameName )
  399. {
  400.     CD3DFrame* pFrame;
  401.  
  402.     if( !lstrcmpi( m_strName, strFrameName ) )
  403.         return this;
  404.  
  405.     if( m_pChild )
  406.         if( NULL != ( pFrame = m_pChild->FindFrame( strFrameName ) ) )
  407.             return pFrame;
  408.  
  409.     if( m_pNext )
  410.         if( NULL != ( pFrame = m_pNext->FindFrame( strFrameName ) ) )
  411.             return pFrame;
  412.  
  413.     return NULL;
  414. }
  415.  
  416.  
  417.  
  418.  
  419. //-----------------------------------------------------------------------------
  420. // Name:
  421. // Desc:
  422. //-----------------------------------------------------------------------------
  423. HRESULT CD3DFrame::Destroy()
  424. {
  425.     if( m_pMesh )  m_pMesh->Destroy();
  426.     if( m_pChild ) m_pChild->Destroy();
  427.     if( m_pNext )  m_pNext->Destroy();
  428.  
  429.     SAFE_DELETE( m_pMesh );
  430.     SAFE_DELETE( m_pNext );
  431.     SAFE_DELETE( m_pChild );
  432.  
  433.     return S_OK;
  434. }
  435.  
  436.  
  437.  
  438.  
  439. //-----------------------------------------------------------------------------
  440. // Name:
  441. // Desc:
  442. //-----------------------------------------------------------------------------
  443. HRESULT CD3DFrame::RestoreDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice )
  444. {
  445.     if( m_pMesh )  m_pMesh->RestoreDeviceObjects( pd3dDevice );
  446.     if( m_pChild ) m_pChild->RestoreDeviceObjects( pd3dDevice );
  447.     if( m_pNext )  m_pNext->RestoreDeviceObjects( pd3dDevice );
  448.     return S_OK;
  449. }
  450.  
  451.  
  452.  
  453.  
  454. //-----------------------------------------------------------------------------
  455. // Name:
  456. // Desc:
  457. //-----------------------------------------------------------------------------
  458. HRESULT CD3DFrame::InvalidateDeviceObjects()
  459. {
  460.     if( m_pMesh )  m_pMesh->InvalidateDeviceObjects();
  461.     if( m_pChild ) m_pChild->InvalidateDeviceObjects();
  462.     if( m_pNext )  m_pNext->InvalidateDeviceObjects();
  463.     return S_OK;
  464. }
  465.  
  466.  
  467.  
  468.  
  469. //-----------------------------------------------------------------------------
  470. // Name:
  471. // Desc:
  472. //-----------------------------------------------------------------------------
  473. HRESULT CD3DFrame::Render( LPDIRECT3DDEVICE8 pd3dDevice, BOOL bDrawOpaqueSubsets,
  474.                            BOOL bDrawAlphaSubsets )
  475. {
  476.     D3DXMATRIX matSavedWorld, matWorld;
  477.     pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
  478.     D3DXMatrixMultiply( &matWorld, &m_mat, &matSavedWorld );
  479.     pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  480.  
  481.     if( m_pMesh )
  482.         m_pMesh->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets );
  483.  
  484.     if( m_pChild )
  485.         m_pChild->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets );
  486.  
  487.     pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
  488.  
  489.     if( m_pNext )
  490.         m_pNext->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets );
  491.  
  492.     return S_OK;
  493. }
  494.  
  495.  
  496.  
  497.  
  498. //-----------------------------------------------------------------------------
  499. // Name:
  500. // Desc:
  501. //-----------------------------------------------------------------------------
  502. HRESULT CD3DFile::LoadFrame( LPDIRECT3DDEVICE8 pd3dDevice,
  503.                              LPDIRECTXFILEDATA pFileData,
  504.                              CD3DFrame* pParentFrame )
  505. {
  506.     LPDIRECTXFILEDATA   pChildData = NULL;
  507.     LPDIRECTXFILEOBJECT pChildObj = NULL;
  508.     const GUID* pGUID;
  509.     DWORD       cbSize;
  510.     CD3DFrame*  pCurrentFrame;
  511.     HRESULT     hr;
  512.  
  513.     // Get the type of the object
  514.     if( FAILED( hr = pFileData->GetType( &pGUID ) ) )
  515.         return hr;
  516.  
  517.     if( *pGUID == TID_D3DRMMesh )
  518.     {
  519.         hr = LoadMesh( pd3dDevice, pFileData, pParentFrame );
  520.         if( FAILED(hr) )
  521.             return hr;
  522.     }
  523.     if( *pGUID == TID_D3DRMFrameTransformMatrix )
  524.     {
  525.         D3DXMATRIX* pmatMatrix;
  526.         hr = pFileData->GetData( NULL, &cbSize, (VOID**)&pmatMatrix );
  527.         if( FAILED(hr) )
  528.             return hr;
  529.  
  530.         // Update the parent's matrix with the new one
  531.         pParentFrame->SetMatrix( pmatMatrix );
  532.     }
  533.     if( *pGUID == TID_D3DRMFrame )
  534.     {
  535.         // Get the frame name
  536.         CHAR  strAnsiName[512] = "";
  537.         TCHAR strName[MAX_PATH];
  538.         DWORD dwNameLength;
  539.         pFileData->GetName( NULL, &dwNameLength );
  540.         if( dwNameLength > 0 )
  541.             pFileData->GetName( strAnsiName, &dwNameLength );
  542.         DXUtil_ConvertAnsiStringToGeneric( strName, strAnsiName );
  543.  
  544.         // Create the frame
  545.         pCurrentFrame = new CD3DFrame( strName );
  546.  
  547.         pCurrentFrame->m_pNext = pParentFrame->m_pChild;
  548.         pParentFrame->m_pChild = pCurrentFrame;
  549.  
  550.         // Enumerate child objects
  551.         while( SUCCEEDED( pFileData->GetNextObject( &pChildObj ) ) )
  552.         {
  553.             // Query the child for its FileData
  554.             hr = pChildObj->QueryInterface( IID_IDirectXFileData,
  555.                                             (VOID**)&pChildData );
  556.             if( SUCCEEDED(hr) )
  557.             {
  558.                 hr = LoadFrame( pd3dDevice, pChildData, pCurrentFrame );
  559.                 pChildData->Release();
  560.             }
  561.  
  562.             pChildObj->Release();
  563.  
  564.             if( FAILED(hr) )
  565.                 return hr;
  566.         }
  567.     }
  568.  
  569.     return S_OK;
  570. }
  571.  
  572.  
  573.  
  574.  
  575. //-----------------------------------------------------------------------------
  576. // Name:
  577. // Desc:
  578. //-----------------------------------------------------------------------------
  579. HRESULT CD3DFile::LoadMesh( LPDIRECT3DDEVICE8 pd3dDevice,
  580.                             LPDIRECTXFILEDATA pFileData,
  581.                             CD3DFrame* pParentFrame )
  582. {
  583.     // Currently only allowing one mesh per frame
  584.     if( pParentFrame->m_pMesh )
  585.         return E_FAIL;
  586.  
  587.     // Get the mesh name
  588.     CHAR  strAnsiName[512];
  589.     TCHAR strName[MAX_PATH];
  590.     DWORD dwNameLength;
  591.     pFileData->GetName( NULL, &dwNameLength );
  592.     if( dwNameLength > 0 )
  593.         pFileData->GetName( strAnsiName, &dwNameLength );
  594.     DXUtil_ConvertAnsiStringToGeneric( strName, strAnsiName );
  595.  
  596.     // Create the mesh
  597.     pParentFrame->m_pMesh = new CD3DMesh( strName );
  598.     pParentFrame->m_pMesh->Create( pd3dDevice, pFileData );
  599.  
  600.     return S_OK;
  601. }
  602.  
  603.  
  604.  
  605.  
  606. //-----------------------------------------------------------------------------
  607. // Name:
  608. // Desc:
  609. //-----------------------------------------------------------------------------
  610. HRESULT CD3DFile::Create( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strFilename )
  611. {
  612.     LPDIRECTXFILE           pDXFile   = NULL;
  613.     LPDIRECTXFILEENUMOBJECT pEnumObj  = NULL;
  614.     LPDIRECTXFILEDATA       pFileData = NULL;
  615.     HRESULT hr;
  616.  
  617.     // Create a x file object
  618.     if( FAILED( hr = DirectXFileCreate( &pDXFile ) ) )
  619.         return E_FAIL;
  620.  
  621.     // Register templates for d3drm and patch extensions.
  622.     if( FAILED( hr = pDXFile->RegisterTemplates( (VOID*)D3DRM_XTEMPLATES,
  623.                                                  D3DRM_XTEMPLATE_BYTES ) ) )
  624.     {
  625.         pDXFile->Release();
  626.         return E_FAIL;
  627.     }
  628.  
  629.     // Find the path to the file, and convert it to ANSI (for the D3DXOF API)
  630.     TCHAR strPath[MAX_PATH];
  631.     CHAR  strPathANSI[MAX_PATH];
  632.     DXUtil_FindMediaFile( strPath, strFilename );
  633.     DXUtil_ConvertGenericStringToAnsi( strPathANSI, strPath );
  634.     
  635.     // Create enum object
  636.     hr = pDXFile->CreateEnumObject( (VOID*)strPathANSI, DXFILELOAD_FROMFILE, 
  637.                                     &pEnumObj );
  638.     if( FAILED(hr) )
  639.     {
  640.         pDXFile->Release();
  641.         return hr;
  642.     }
  643.  
  644.     // Enumerate top level objects (which are always frames)
  645.     while( SUCCEEDED( pEnumObj->GetNextDataObject( &pFileData ) ) )
  646.     {
  647.         hr = LoadFrame( pd3dDevice, pFileData, this );
  648.         pFileData->Release();
  649.         if( FAILED(hr) )
  650.         {
  651.             pEnumObj->Release();
  652.             pDXFile->Release();
  653.             return E_FAIL;
  654.         }
  655.     }
  656.  
  657.     SAFE_RELEASE( pFileData );
  658.     SAFE_RELEASE( pEnumObj );
  659.     SAFE_RELEASE( pDXFile );
  660.  
  661.     return S_OK;
  662. }
  663.  
  664.  
  665.  
  666.  
  667. //-----------------------------------------------------------------------------
  668. // Name:
  669. // Desc:
  670. //-----------------------------------------------------------------------------
  671. HRESULT CD3DFile::Render( LPDIRECT3DDEVICE8 pd3dDevice )
  672. {
  673.     // Set up the world transformation
  674.     D3DXMATRIX matSavedWorld, matWorld;
  675.     pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
  676.     D3DXMatrixMultiply( &matWorld, &matSavedWorld, &m_mat );
  677.     pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  678.  
  679.     // Render opaque subsets in the meshes
  680.     if( m_pChild )
  681.         m_pChild->Render( pd3dDevice, TRUE, FALSE );
  682.  
  683.     // Enable alpha blending
  684.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  685.     pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
  686.     pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  687.  
  688.     // Render alpha subsets in the meshes
  689.     if( m_pChild )
  690.         m_pChild->Render( pd3dDevice, FALSE, TRUE );
  691.  
  692.     // Restore state
  693.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  694.     pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
  695.  
  696.     return S_OK;
  697. }
  698.  
  699.  
  700.  
  701.  
  702.