0001: //-----------------------------------------------------------------------------
0002: // File: D3DFile.cpp
0003: //
0004: // Desc: Support code for loading DirectX .X files.
0005: //-----------------------------------------------------------------------------
0006: #define STRICT
0007: #include <tchar.h>
0008: #include <stdio.h>
0009: #include <d3d8.h>
0010: #include <d3dx8.h>
0011: #include <dxfile.h>
0012: #include <rmxfguid.h>
0013: #include <rmxftmpl.h>
0014: #include "D3DFile.h"
0015: #include "DXUtil.h"
0016: 
0017: 
0018: 
0019: 
0020: //-----------------------------------------------------------------------------
0021: // Name:
0022: // Desc:
0023: //-----------------------------------------------------------------------------
0024: CD3DMesh::CD3DMesh( TCHAR* strName )
0025: {
0026:     _tcscpy( m_strName, strName );
0027:     m_pSysMemMesh        = NULL;
0028:     m_pLocalMesh         = NULL;
0029:     m_dwNumMaterials     = 0L;
0030:     m_pMaterials         = NULL;
0031:     m_pTextures          = NULL;
0032:     m_bUseMaterials      = TRUE;
0033: }
0034: 
0035: 
0036: 
0037: 
0038: //-----------------------------------------------------------------------------
0039: // Name:
0040: // Desc:
0041: //-----------------------------------------------------------------------------
0042: CD3DMesh::~CD3DMesh()
0043: {
0044:     Destroy();
0045: }
0046: 
0047: 
0048: 
0049: 
0050: //-----------------------------------------------------------------------------
0051: // Name:
0052: // Desc:
0053: //-----------------------------------------------------------------------------
0054: HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strFilename )
0055: {
0056:     TCHAR        strPath[MAX_PATH];
0057:     CHAR         strPathANSI[MAX_PATH];
0058:     LPD3DXBUFFER pAdjacencyBuffer = NULL;
0059:     LPD3DXBUFFER pMtrlBuffer = NULL;
0060:     HRESULT      hr;
0061: 
0062:     // Find the path for the file, and convert it to ANSI (for the D3DX API)
0063:     DXUtil_FindMediaFile( strPath, strFilename );
0064:     DXUtil_ConvertGenericStringToAnsi( strPathANSI, strPath );
0065: 
0066:     // Load the mesh
0067:     if( FAILED( hr = D3DXLoadMeshFromX( strPathANSI, D3DXMESH_SYSTEMMEM, pd3dDevice, 
0068:                                         &pAdjacencyBuffer, &pMtrlBuffer, 
0069:                                         &m_dwNumMaterials, &m_pSysMemMesh ) ) )
0070:     {
0071:         return hr;
0072:     }
0073: 
0074:     // Optimize the mesh for performance
0075:     if( FAILED( hr = m_pSysMemMesh->OptimizeInplace(
0076:                         D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
0077:                         (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
0078:     {
0079:         SAFE_RELEASE( pAdjacencyBuffer );
0080:         SAFE_RELEASE( pMtrlBuffer );
0081:         return hr;
0082:     }
0083: 
0084:     // Get material info for the mesh
0085:     // Get the array of materials out of the buffer
0086:     if( pMtrlBuffer && m_dwNumMaterials > 0 )
0087:     {
0088:         // Allocate memory for the materials and textures
0089:         D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();
0090:         m_pMaterials = new D3DMATERIAL8[m_dwNumMaterials];
0091:         m_pTextures  = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];
0092: 
0093:         // Copy each material and create its texture
0094:         for( DWORD i=0; i<m_dwNumMaterials; i++ )
0095:         {
0096:             // Copy the material
0097:             m_pMaterials[i]         = d3dxMtrls[i].MatD3D;
0098:             m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse;
0099:             m_pTextures[i]          = NULL;
0100: 
0101:             // Create a texture
0102:             if( d3dxMtrls[i].pTextureFilename )
0103:             {
0104:                 TCHAR strTexture[MAX_PATH];
0105:                 TCHAR strTextureTemp[MAX_PATH];
0106:                 DXUtil_ConvertAnsiStringToGeneric( strTextureTemp, d3dxMtrls[i].pTextureFilename );
0107:                 DXUtil_FindMediaFile( strTexture, strTextureTemp );
0108: 
0109:                 if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, 
0110:                                                        &m_pTextures[i] ) ) )
0111:                     m_pTextures[i] = NULL;
0112:             }
0113:         }
0114:     }
0115: 
0116:     SAFE_RELEASE( pAdjacencyBuffer );
0117:     SAFE_RELEASE( pMtrlBuffer );
0118: 
0119:     return S_OK;
0120: }
0121: 
0122: 
0123: 
0124: 
0125: //-----------------------------------------------------------------------------
0126: // Name:
0127: // Desc:
0128: //-----------------------------------------------------------------------------
0129: HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE8 pd3dDevice,
0130:                           LPDIRECTXFILEDATA pFileData )
0131: {
0132:     LPD3DXBUFFER pMtrlBuffer = NULL;
0133:     LPD3DXBUFFER pAdjacencyBuffer = NULL;
0134:     HRESULT      hr;
0135: 
0136:     // Load the mesh from the DXFILEDATA object
0137:     if( FAILED( hr = D3DXLoadMeshFromXof( pFileData, D3DXMESH_SYSTEMMEM, pd3dDevice,
0138:                                           &pAdjacencyBuffer, &pMtrlBuffer, 
0139:                                           &m_dwNumMaterials, &m_pSysMemMesh ) ) )
0140:     {
0141:         return hr;
0142:     }
0143: 
0144:     // Optimize the mesh for performance
0145:     if( FAILED( hr = m_pSysMemMesh->OptimizeInplace(
0146:                         D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
0147:                         (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
0148:     {
0149:         SAFE_RELEASE( pAdjacencyBuffer );
0150:         SAFE_RELEASE( pMtrlBuffer );
0151:         return hr;
0152:     }
0153: 
0154:     // Get material info for the mesh
0155:     // Get the array of materials out of the buffer
0156:     if( pMtrlBuffer && m_dwNumMaterials > 0 )
0157:     {
0158:         // Allocate memory for the materials and textures
0159:         D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();
0160:         m_pMaterials = new D3DMATERIAL8[m_dwNumMaterials];
0161:         m_pTextures  = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];
0162: 
0163:         // Copy each material and create its texture
0164:         for( DWORD i=0; i<m_dwNumMaterials; i++ )
0165:         {
0166:             // Copy the material
0167:             m_pMaterials[i]         = d3dxMtrls[i].MatD3D;
0168:             m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse;
0169:             m_pTextures[i]          = NULL;
0170: 
0171:             // Create a texture
0172:             if( d3dxMtrls[i].pTextureFilename )
0173:             {
0174:                 TCHAR strTexture[MAX_PATH];
0175:                 TCHAR strTextureTemp[MAX_PATH];
0176:                 DXUtil_ConvertAnsiStringToGeneric( strTextureTemp, d3dxMtrls[i].pTextureFilename );
0177:                 DXUtil_FindMediaFile( strTexture, strTextureTemp );
0178: 
0179:                 if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, 
0180:                                                        &m_pTextures[i] ) ) )
0181:                     m_pTextures[i] = NULL;
0182:             }
0183:         }
0184:     }
0185: 
0186:     SAFE_RELEASE( pAdjacencyBuffer );
0187:     SAFE_RELEASE( pMtrlBuffer );
0188: 
0189:     return S_OK;
0190: }
0191: 
0192: 
0193: 
0194: 
0195: //-----------------------------------------------------------------------------
0196: // Name:
0197: // Desc:
0198: //-----------------------------------------------------------------------------
0199: HRESULT CD3DMesh::SetFVF( LPDIRECT3DDEVICE8 pd3dDevice, DWORD dwFVF )
0200: {
0201:     LPD3DXMESH pTempSysMemMesh = NULL;
0202:     LPD3DXMESH pTempLocalMesh  = NULL;
0203: 
0204:     if( m_pSysMemMesh )
0205:     {
0206:         if( FAILED( m_pSysMemMesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM, dwFVF,
0207:                                                  pd3dDevice, &pTempSysMemMesh ) ) )
0208:             return E_FAIL;
0209:     }
0210:     if( m_pLocalMesh )
0211:     {
0212:         if( FAILED( m_pLocalMesh->CloneMeshFVF( 0L, dwFVF, pd3dDevice,
0213:                                                 &pTempLocalMesh ) ) )
0214:         {
0215:             SAFE_RELEASE( pTempSysMemMesh );
0216:             return E_FAIL;
0217:         }
0218:     }
0219: 
0220:     SAFE_RELEASE( m_pSysMemMesh );
0221:     SAFE_RELEASE( m_pLocalMesh );
0222: 
0223:     if( pTempSysMemMesh ) m_pSysMemMesh = pTempSysMemMesh;
0224:     if( pTempLocalMesh )  m_pLocalMesh  = pTempLocalMesh;
0225: 
0226:     // Compute normals in case the meshes have them
0227:     if( m_pSysMemMesh )
0228:         D3DXComputeNormals( m_pSysMemMesh, NULL );
0229:     if( m_pLocalMesh )
0230:         D3DXComputeNormals( m_pLocalMesh, NULL );
0231: 
0232:     return S_OK;
0233: }
0234: 
0235: 
0236: 
0237: 
0238: //-----------------------------------------------------------------------------
0239: // Name:
0240: // Desc:
0241: //-----------------------------------------------------------------------------
0242: HRESULT CD3DMesh::RestoreDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice )
0243: {
0244:     if( NULL == m_pSysMemMesh )
0245:         return E_FAIL;
0246: 
0247:     // Make a local memory version of the mesh. Note: because we are passing in
0248:     // no flags, the default behavior is to clone into local memory.
0249:     if( FAILED( m_pSysMemMesh->CloneMeshFVF( 0L, m_pSysMemMesh->GetFVF(),
0250:                                              pd3dDevice, &m_pLocalMesh ) ) )
0251:         return E_FAIL;
0252: 
0253:     return S_OK;
0254: 
0255: }
0256: 
0257: 
0258: 
0259: 
0260: //-----------------------------------------------------------------------------
0261: // Name:
0262: // Desc:
0263: //-----------------------------------------------------------------------------
0264: HRESULT CD3DMesh::InvalidateDeviceObjects()
0265: {
0266:     SAFE_RELEASE( m_pLocalMesh );
0267: 
0268:     return S_OK;
0269: }
0270: 
0271: 
0272: 
0273: 
0274: //-----------------------------------------------------------------------------
0275: // Name:
0276: // Desc:
0277: //-----------------------------------------------------------------------------
0278: HRESULT CD3DMesh::Destroy()
0279: {
0280:     InvalidateDeviceObjects();
0281:     for( UINT i=0; i<m_dwNumMaterials; i++ )
0282:         SAFE_RELEASE( m_pTextures[i] );
0283:     SAFE_DELETE_ARRAY( m_pTextures );
0284:     SAFE_DELETE_ARRAY( m_pMaterials );
0285: 
0286:     SAFE_RELEASE( m_pSysMemMesh );
0287: 
0288:     m_dwNumMaterials = 0L;
0289: 
0290:     return S_OK;
0291: }
0292: 
0293: 
0294: 
0295: 
0296: //-----------------------------------------------------------------------------
0297: // Name:
0298: // Desc:
0299: //-----------------------------------------------------------------------------
0300: HRESULT CD3DMesh::Render( LPDIRECT3DDEVICE8 pd3dDevice, BOOL bDrawOpaqueSubsets,
0301:                           BOOL bDrawAlphaSubsets )
0302: {
0303:     if( NULL == m_pLocalMesh )
0304:         return E_FAIL;
0305: 
0306:     // Frist, draw the subsets without alpha
0307:     if( bDrawOpaqueSubsets )
0308:     {
0309:         for( DWORD i=0; i<m_dwNumMaterials; i++ )
0310:         {
0311:             if( m_bUseMaterials )
0312:             {
0313:                 if( m_pMaterials[i].Diffuse.a < 1.0f )
0314:                     continue;
0315:                 pd3dDevice->SetMaterial( &m_pMaterials[i] );
0316:                 pd3dDevice->SetTexture( 0, m_pTextures[i] );
0317:             }
0318:             m_pLocalMesh->DrawSubset( i );
0319:         }
0320:     }
0321: 
0322:     // Then, draw the subsets with alpha
0323:     if( bDrawAlphaSubsets && m_bUseMaterials )
0324:     {
0325:         for( DWORD i=0; i<m_dwNumMaterials; i++ )
0326:         {
0327:             if( m_pMaterials[i].Diffuse.a == 1.0f )
0328:                 continue;
0329: 
0330:             // Set the material and texture
0331:             pd3dDevice->SetMaterial( &m_pMaterials[i] );
0332:             pd3dDevice->SetTexture( 0, m_pTextures[i] );
0333:             m_pLocalMesh->DrawSubset( i );
0334:         }
0335:     }
0336: 
0337:     return S_OK;
0338: }
0339: 
0340: 
0341: 
0342: 
0343: //-----------------------------------------------------------------------------
0344: // Name:
0345: // Desc:
0346: //-----------------------------------------------------------------------------
0347: CD3DFrame::CD3DFrame( TCHAR* strName )
0348: {
0349:     _tcscpy( m_strName, strName );
0350:     D3DXMatrixIdentity( &m_mat );
0351:     m_pMesh  = NULL;
0352: 
0353:     m_pChild = NULL;
0354:     m_pNext  = NULL;
0355: }
0356: 
0357: 
0358: 
0359: 
0360: //-----------------------------------------------------------------------------
0361: // Name:
0362: // Desc:
0363: //-----------------------------------------------------------------------------
0364: CD3DFrame::~CD3DFrame()
0365: {
0366:     SAFE_DELETE( m_pChild );
0367:     SAFE_DELETE( m_pNext );
0368: }
0369: 
0370: 
0371: 
0372: 
0373: //-----------------------------------------------------------------------------
0374: // Name:
0375: // Desc:
0376: //-----------------------------------------------------------------------------
0377: BOOL CD3DFrame::EnumMeshes( BOOL (*EnumMeshCB)(CD3DMesh*,VOID*),
0378:                             VOID* pContext )
0379: {
0380:     if( m_pMesh )
0381:         EnumMeshCB( m_pMesh, pContext );
0382:     if( m_pChild )
0383:         m_pChild->EnumMeshes( EnumMeshCB, pContext );
0384:     if( m_pNext )
0385:         m_pNext->EnumMeshes( EnumMeshCB, pContext );
0386: 
0387:     return TRUE;
0388: }
0389: 
0390: 
0391: 
0392: 
0393: //-----------------------------------------------------------------------------
0394: // Name:
0395: // Desc:
0396: //-----------------------------------------------------------------------------
0397: CD3DMesh* CD3DFrame::FindMesh( TCHAR* strMeshName )
0398: {
0399:     CD3DMesh* pMesh;
0400: 
0401:     if( m_pMesh )
0402:         if( !lstrcmpi( m_pMesh->m_strName, strMeshName ) )
0403:             return m_pMesh;
0404: 
0405:     if( m_pChild )
0406:         if( NULL != ( pMesh = m_pChild->FindMesh( strMeshName ) ) )
0407:             return pMesh;
0408: 
0409:     if( m_pNext )
0410:         if( NULL != ( pMesh = m_pNext->FindMesh( strMeshName ) ) )
0411:             return pMesh;
0412: 
0413:     return NULL;
0414: }
0415: 
0416: 
0417: 
0418: 
0419: //-----------------------------------------------------------------------------
0420: // Name:
0421: // Desc:
0422: //-----------------------------------------------------------------------------
0423: CD3DFrame* CD3DFrame::FindFrame( TCHAR* strFrameName )
0424: {
0425:     CD3DFrame* pFrame;
0426: 
0427:     if( !lstrcmpi( m_strName, strFrameName ) )
0428:         return this;
0429: 
0430:     if( m_pChild )
0431:         if( NULL != ( pFrame = m_pChild->FindFrame( strFrameName ) ) )
0432:             return pFrame;
0433: 
0434:     if( m_pNext )
0435:         if( NULL != ( pFrame = m_pNext->FindFrame( strFrameName ) ) )
0436:             return pFrame;
0437: 
0438:     return NULL;
0439: }
0440: 
0441: 
0442: 
0443: 
0444: //-----------------------------------------------------------------------------
0445: // Name:
0446: // Desc:
0447: //-----------------------------------------------------------------------------
0448: HRESULT CD3DFrame::Destroy()
0449: {
0450:     if( m_pMesh )  m_pMesh->Destroy();
0451:     if( m_pChild ) m_pChild->Destroy();
0452:     if( m_pNext )  m_pNext->Destroy();
0453: 
0454:     SAFE_DELETE( m_pMesh );
0455:     SAFE_DELETE( m_pNext );
0456:     SAFE_DELETE( m_pChild );
0457: 
0458:     return S_OK;
0459: }
0460: 
0461: 
0462: 
0463: 
0464: //-----------------------------------------------------------------------------
0465: // Name:
0466: // Desc:
0467: //-----------------------------------------------------------------------------
0468: HRESULT CD3DFrame::RestoreDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice )
0469: {
0470:     if( m_pMesh )  m_pMesh->RestoreDeviceObjects( pd3dDevice );
0471:     if( m_pChild ) m_pChild->RestoreDeviceObjects( pd3dDevice );
0472:     if( m_pNext )  m_pNext->RestoreDeviceObjects( pd3dDevice );
0473:     return S_OK;
0474: }
0475: 
0476: 
0477: 
0478: 
0479: //-----------------------------------------------------------------------------
0480: // Name:
0481: // Desc:
0482: //-----------------------------------------------------------------------------
0483: HRESULT CD3DFrame::InvalidateDeviceObjects()
0484: {
0485:     if( m_pMesh )  m_pMesh->InvalidateDeviceObjects();
0486:     if( m_pChild ) m_pChild->InvalidateDeviceObjects();
0487:     if( m_pNext )  m_pNext->InvalidateDeviceObjects();
0488:     return S_OK;
0489: }
0490: 
0491: 
0492: 
0493: 
0494: //-----------------------------------------------------------------------------
0495: // Name:
0496: // Desc:
0497: //-----------------------------------------------------------------------------
0498: HRESULT CD3DFrame::Render( LPDIRECT3DDEVICE8 pd3dDevice, BOOL bDrawOpaqueSubsets,
0499:                            BOOL bDrawAlphaSubsets, D3DXMATRIX* pmatWorldMatrix )
0500: {
0501:     // For pure devices, specify the world transform. If the world transform is not
0502:     // specified on pure devices, this function will fail.
0503: 
0504:     D3DXMATRIX matSavedWorld, matWorld;
0505: 
0506:     if ( NULL == pmatWorldMatrix )
0507:         pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
0508:     else
0509:         matSavedWorld = *pmatWorldMatrix;
0510: 
0511:     D3DXMatrixMultiply( &matWorld, &m_mat, &matSavedWorld );
0512:     pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
0513: 
0514:     if( m_pMesh )
0515:         m_pMesh->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets );
0516: 
0517:     if( m_pChild )
0518:         m_pChild->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matWorld );
0519: 
0520:     pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
0521: 
0522:     if( m_pNext )
0523:         m_pNext->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matSavedWorld );
0524: 
0525:     return S_OK;
0526: }
0527: 
0528: 
0529: 
0530: 
0531: //-----------------------------------------------------------------------------
0532: // Name:
0533: // Desc:
0534: //-----------------------------------------------------------------------------
0535: HRESULT CD3DFile::LoadFrame( LPDIRECT3DDEVICE8 pd3dDevice,
0536:                              LPDIRECTXFILEDATA pFileData,
0537:                              CD3DFrame* pParentFrame )
0538: {
0539:     LPDIRECTXFILEDATA   pChildData = NULL;
0540:     LPDIRECTXFILEOBJECT pChildObj = NULL;
0541:     const GUID* pGUID;
0542:     DWORD       cbSize;
0543:     CD3DFrame*  pCurrentFrame;
0544:     HRESULT     hr;
0545: 
0546:     // Get the type of the object
0547:     if( FAILED( hr = pFileData->GetType( &pGUID ) ) )
0548:         return hr;
0549: 
0550:     if( *pGUID == TID_D3DRMMesh )
0551:     {
0552:         hr = LoadMesh( pd3dDevice, pFileData, pParentFrame );
0553:         if( FAILED(hr) )
0554:             return hr;
0555:     }
0556:     if( *pGUID == TID_D3DRMFrameTransformMatrix )
0557:     {
0558:         D3DXMATRIX* pmatMatrix;
0559:         hr = pFileData->GetData( NULL, &cbSize, (VOID**)&pmatMatrix );
0560:         if( FAILED(hr) )
0561:             return hr;
0562: 
0563:         // Update the parent's matrix with the new one
0564:         pParentFrame->SetMatrix( pmatMatrix );
0565:     }
0566:     if( *pGUID == TID_D3DRMFrame )
0567:     {
0568:         // Get the frame name
0569:         CHAR  strAnsiName[512] = "";
0570:         TCHAR strName[MAX_PATH];
0571:         DWORD dwNameLength;
0572:         pFileData->GetName( NULL, &dwNameLength );
0573:         if( dwNameLength > 0 )
0574:             pFileData->GetName( strAnsiName, &dwNameLength );
0575:         DXUtil_ConvertAnsiStringToGeneric( strName, strAnsiName );
0576: 
0577:         // Create the frame
0578:         pCurrentFrame = new CD3DFrame( strName );
0579: 
0580:         pCurrentFrame->m_pNext = pParentFrame->m_pChild;
0581:         pParentFrame->m_pChild = pCurrentFrame;
0582: 
0583:         // Enumerate child objects
0584:         while( SUCCEEDED( pFileData->GetNextObject( &pChildObj ) ) )
0585:         {
0586:             // Query the child for its FileData
0587:             hr = pChildObj->QueryInterface( IID_IDirectXFileData,
0588:                                             (VOID**)&pChildData );
0589:             if( SUCCEEDED(hr) )
0590:             {
0591:                 hr = LoadFrame( pd3dDevice, pChildData, pCurrentFrame );
0592:                 pChildData->Release();
0593:             }
0594: 
0595:             pChildObj->Release();
0596: 
0597:             if( FAILED(hr) )
0598:                 return hr;
0599:         }
0600:     }
0601: 
0602:     return S_OK;
0603: }
0604: 
0605: 
0606: 
0607: 
0608: //-----------------------------------------------------------------------------
0609: // Name:
0610: // Desc:
0611: //-----------------------------------------------------------------------------
0612: HRESULT CD3DFile::LoadMesh( LPDIRECT3DDEVICE8 pd3dDevice,
0613:                             LPDIRECTXFILEDATA pFileData,
0614:                             CD3DFrame* pParentFrame )
0615: {
0616:     // Currently only allowing one mesh per frame
0617:     if( pParentFrame->m_pMesh )
0618:         return E_FAIL;
0619: 
0620:     // Get the mesh name
0621:     CHAR  strAnsiName[512] = {0};
0622:     TCHAR strName[MAX_PATH];
0623:     DWORD dwNameLength;
0624:     pFileData->GetName( NULL, &dwNameLength );
0625:     if( dwNameLength > 0 )
0626:         pFileData->GetName( strAnsiName, &dwNameLength );
0627:     DXUtil_ConvertAnsiStringToGeneric( strName, strAnsiName );
0628: 
0629:     // Create the mesh
0630:     pParentFrame->m_pMesh = new CD3DMesh( strName );
0631:     pParentFrame->m_pMesh->Create( pd3dDevice, pFileData );
0632: 
0633:     return S_OK;
0634: }
0635: 
0636: 
0637: 
0638: 
0639: //-----------------------------------------------------------------------------
0640: // Name:
0641: // Desc:
0642: //-----------------------------------------------------------------------------
0643: HRESULT CD3DFile::CreateFromResource( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strResource, TCHAR* strType )
0644: {
0645:     LPDIRECTXFILE           pDXFile   = NULL;
0646:     LPDIRECTXFILEENUMOBJECT pEnumObj  = NULL;
0647:     LPDIRECTXFILEDATA       pFileData = NULL;
0648:     HRESULT hr;
0649: 
0650:     // Create a x file object
0651:     if( FAILED( hr = DirectXFileCreate( &pDXFile ) ) )
0652:         return E_FAIL;
0653: 
0654:     // Register templates for d3drm and patch extensions.
0655:     if( FAILED( hr = pDXFile->RegisterTemplates( (VOID*)D3DRM_XTEMPLATES,
0656:                                                  D3DRM_XTEMPLATE_BYTES ) ) )
0657:     {
0658:         pDXFile->Release();
0659:         return E_FAIL;
0660:     }
0661:     
0662:     CHAR strTypeAnsi[MAX_PATH];
0663:     DXUtil_ConvertGenericStringToAnsi( strTypeAnsi, strType );
0664: 
0665:     DXFILELOADRESOURCE dxlr;
0666:     dxlr.hModule = NULL;
0667:     dxlr.lpName = strResource;
0668:     dxlr.lpType = (TCHAR*) strTypeAnsi;
0669: 
0670:     // Create enum object
0671:     hr = pDXFile->CreateEnumObject( (VOID*)&dxlr, DXFILELOAD_FROMRESOURCE, 
0672:                                     &pEnumObj );
0673:     if( FAILED(hr) )
0674:     {
0675:         pDXFile->Release();
0676:         return hr;
0677:     }
0678: 
0679:     // Enumerate top level objects (which are always frames)
0680:     while( SUCCEEDED( pEnumObj->GetNextDataObject( &pFileData ) ) )
0681:     {
0682:         hr = LoadFrame( pd3dDevice, pFileData, this );
0683:         pFileData->Release();
0684:         if( FAILED(hr) )
0685:         {
0686:             pEnumObj->Release();
0687:             pDXFile->Release();
0688:             return E_FAIL;
0689:         }
0690:     }
0691: 
0692:     SAFE_RELEASE( pFileData );
0693:     SAFE_RELEASE( pEnumObj );
0694:     SAFE_RELEASE( pDXFile );
0695: 
0696:     return S_OK;
0697: }
0698: 
0699: 
0700: 
0701: 
0702: //-----------------------------------------------------------------------------
0703: // Name:
0704: // Desc:
0705: //-----------------------------------------------------------------------------
0706: HRESULT CD3DFile::Create( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strFilename )
0707: {
0708:     LPDIRECTXFILE           pDXFile   = NULL;
0709:     LPDIRECTXFILEENUMOBJECT pEnumObj  = NULL;
0710:     LPDIRECTXFILEDATA       pFileData = NULL;
0711:     HRESULT hr;
0712: 
0713:     // Create a x file object
0714:     if( FAILED( hr = DirectXFileCreate( &pDXFile ) ) )
0715:         return E_FAIL;
0716: 
0717:     // Register templates for d3drm and patch extensions.
0718:     if( FAILED( hr = pDXFile->RegisterTemplates( (VOID*)D3DRM_XTEMPLATES,
0719:                                                  D3DRM_XTEMPLATE_BYTES ) ) )
0720:     {
0721:         pDXFile->Release();
0722:         return E_FAIL;
0723:     }
0724: 
0725:     // Find the path to the file, and convert it to ANSI (for the D3DXOF API)
0726:     TCHAR strPath[MAX_PATH];
0727:     CHAR  strPathANSI[MAX_PATH];
0728:     DXUtil_FindMediaFile( strPath, strFilename );
0729:     DXUtil_ConvertGenericStringToAnsi( strPathANSI, strPath );
0730:     
0731:     // Create enum object
0732:     hr = pDXFile->CreateEnumObject( (VOID*)strPathANSI, DXFILELOAD_FROMFILE, 
0733:                                     &pEnumObj );
0734:     if( FAILED(hr) )
0735:     {
0736:         pDXFile->Release();
0737:         return hr;
0738:     }
0739: 
0740:     // Enumerate top level objects (which are always frames)
0741:     while( SUCCEEDED( pEnumObj->GetNextDataObject( &pFileData ) ) )
0742:     {
0743:         hr = LoadFrame( pd3dDevice, pFileData, this );
0744:         pFileData->Release();
0745:         if( FAILED(hr) )
0746:         {
0747:             pEnumObj->Release();
0748:             pDXFile->Release();
0749:             return E_FAIL;
0750:         }
0751:     }
0752: 
0753:     SAFE_RELEASE( pFileData );
0754:     SAFE_RELEASE( pEnumObj );
0755:     SAFE_RELEASE( pDXFile );
0756: 
0757:     return S_OK;
0758: }
0759: 
0760: 
0761: 
0762: 
0763: //-----------------------------------------------------------------------------
0764: // Name:
0765: // Desc:
0766: //-----------------------------------------------------------------------------
0767: HRESULT CD3DFile::Render( LPDIRECT3DDEVICE8 pd3dDevice, D3DXMATRIX* pmatWorldMatrix )
0768: {
0769: 
0770:     // For pure devices, specify the world transform. If the world transform is not
0771:     // specified on pure devices, this function will fail.
0772: 
0773:     // Set up the world transformation
0774:     D3DXMATRIX matSavedWorld, matWorld;
0775: 
0776:     if ( NULL == pmatWorldMatrix )
0777:         pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
0778:     else
0779:         matSavedWorld = *pmatWorldMatrix;
0780: 
0781:     D3DXMatrixMultiply( &matWorld, &matSavedWorld, &m_mat );
0782:     pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
0783: 
0784:     // Render opaque subsets in the meshes
0785:     if( m_pChild )
0786:         m_pChild->Render( pd3dDevice, TRUE, FALSE, &matWorld );
0787: 
0788:     // Enable alpha blending
0789:     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
0790:     pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
0791:     pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
0792: 
0793:     // Render alpha subsets in the meshes
0794:     if( m_pChild )
0795:         m_pChild->Render( pd3dDevice, FALSE, TRUE, &matWorld );
0796: 
0797:     // Restore state
0798:     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
0799:     pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
0800: 
0801:     return S_OK;
0802: }
0803: 
0804: 
0805: 
0806: 
0807: