//----------------------------------------------------------------------------- // Name: // Desc: //----------------------------------------------------------------------------- HRESULT CD3DFile::Create( LPDIRECT3DDEVICE9 pd3dDevice, TCHAR* strFilename ) { LPDIRECTXFILE pDXFile = NULL; LPDIRECTXFILEENUMOBJECT pEnumObj = NULL; LPDIRECTXFILEDATA pFileData = NULL; HRESULT hr; // Create a x file object if( FAILED( hr = DirectXFileCreate( &pDXFile ) ) ) return E_FAIL; // Register templates for d3drm and patch extensions. if( FAILED( hr = pDXFile->RegisterTemplates( (void*)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES ) ) ) { pDXFile->Release(); return E_FAIL; } // Find the path to the file, and convert it to ANSI (for the D3DXOF API) TCHAR strPath[MAX_PATH]; CHAR strPathANSI[MAX_PATH]; DXUtil_FindMediaFileCb( strPath, sizeof(strPath), strFilename ); DXUtil_ConvertGenericStringToAnsiCb( strPathANSI, strPath, sizeof(strPathANSI) ); // Create enum object hr = pDXFile->CreateEnumObject( (void*)strPathANSI, DXFILELOAD_FROMFILE, &pEnumObj ); if( FAILED(hr) ) { pDXFile->Release(); return hr; } // Enumerate top level objects (which are always frames) while( SUCCEEDED( pEnumObj->GetNextDataObject( &pFileData ) ) ) { hr = LoadFrame( pd3dDevice, pFileData, this ); pFileData->Release(); if( FAILED(hr) ) { pEnumObj->Release(); pDXFile->Release(); return E_FAIL; } } SAFE_RELEASE( pFileData ); SAFE_RELEASE( pEnumObj ); SAFE_RELEASE( pDXFile ); return S_OK; }
//----------------------------------------------------------------------------- // Name: D3DUtil_CreateTexture() // Desc: Helper function to create a texture. It checks the root path first, // then tries the DXSDK media path (as specified in the system registry). //----------------------------------------------------------------------------- HRESULT D3DUtil_CreateTexture( LPDIRECT3DDEVICE9 pd3dDevice, TCHAR* strTexture, LPDIRECT3DTEXTURE9* ppTexture, D3DFORMAT d3dFormat ) { HRESULT hr; TCHAR strPath[MAX_PATH]; // Get the path to the texture if( FAILED( hr = DXUtil_FindMediaFileCb( strPath, sizeof(strPath), strTexture ) ) ) return hr; // Create the texture using D3DX return D3DXCreateTextureFromFileEx( pd3dDevice, strPath, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, d3dFormat, D3DPOOL_MANAGED, D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR, D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR, 0, NULL, NULL, ppTexture ); }
//----------------------------------------------------------------------------- // Name: // Desc: //----------------------------------------------------------------------------- HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, TCHAR* strFilename ) { TCHAR strPath[MAX_PATH]; LPD3DXBUFFER pAdjacencyBuffer = NULL; LPD3DXBUFFER pMtrlBuffer = NULL; HRESULT hr; // Find the path for the file, and convert it to ANSI (for the D3DX API) DXUtil_FindMediaFileCb( strPath, sizeof(strPath), strFilename ); // Load the mesh if( FAILED( hr = D3DXLoadMeshFromX( strPath, D3DXMESH_SYSTEMMEM, pd3dDevice, &pAdjacencyBuffer, &pMtrlBuffer, NULL, &m_dwNumMaterials, &m_pSysMemMesh ) ) ) { return hr; } // Optimize the mesh for performance if( FAILED( hr = m_pSysMemMesh->OptimizeInplace( D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) ) { SAFE_RELEASE( pAdjacencyBuffer ); SAFE_RELEASE( pMtrlBuffer ); return hr; } // Get material info for the mesh // Get the array of materials out of the buffer if( pMtrlBuffer && m_dwNumMaterials > 0 ) { // Allocate memory for the materials and textures D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer(); m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials]; if( m_pMaterials == NULL ) { hr = E_OUTOFMEMORY; goto LEnd; } m_pTextures = new LPDIRECT3DTEXTURE9[m_dwNumMaterials]; if( m_pTextures == NULL ) { hr = E_OUTOFMEMORY; goto LEnd; } // Copy each material and create its texture for( DWORD i=0; i<m_dwNumMaterials; i++ ) { // Copy the material m_pMaterials[i] = d3dxMtrls[i].MatD3D; m_pTextures[i] = NULL; // Create a texture if( d3dxMtrls[i].pTextureFilename ) { TCHAR strTexture[MAX_PATH]; TCHAR strTextureTemp[MAX_PATH]; DXUtil_ConvertAnsiStringToGenericCb( strTextureTemp, d3dxMtrls[i].pTextureFilename, sizeof(strTextureTemp) ); DXUtil_FindMediaFileCb( strTexture, sizeof(strTexture), strTextureTemp ); if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, &m_pTextures[i] ) ) ) m_pTextures[i] = NULL; } } } hr = S_OK; LEnd: SAFE_RELEASE( pAdjacencyBuffer ); SAFE_RELEASE( pMtrlBuffer ); return hr; }
/********************Public*Routine****************************************\ * CPlane * \**************************************************************************/ CHall::CPlane::CPlane( IDirect3DDevice9* pDevice, TCHAR *achName, LPCTSTR lpResourceName, float fU, float fV, D3DXMATRIX& M, float a, HRESULT *phr) : m_du( 0.f) , m_fU( fU ) , m_fV( fV ) , m_fSpeed( 0.f ) , m_pTexture( NULL ) { HRESULT hr = S_OK; TCHAR achTexturePath[MAX_PATH]; D3DXVECTOR3 vLB( M(0,0), M(1,0), M(2,0)); D3DXVECTOR3 vLT( M(0,1), M(1,1), M(2,1)); D3DXVECTOR3 vRT( M(0,2), M(1,2), M(2,2)); D3DXVECTOR3 vRB( M(0,3), M(1,3), M(2,3)); D3DXVECTOR3 V; try { if( !achName ) throw E_POINTER; hr = FindMediaFile( achTexturePath, sizeof(TCHAR)*MAX_PATH, achName, lpResourceName, RT_BITMAP); if( FAILED(hr)) { TCHAR achMsg[MAX_PATH]; _stprintf( achMsg, TEXT("Cannot find media file '%s'. ") TEXT("Make sure you have valid installation of DirectX SDK"), achName); ::MessageBox( NULL, achMsg, TEXT("Error"), MB_OK); if( phr ) { *phr = hr; return; } } if( !pDevice ) throw E_POINTER; if( a<0.01f || a>0.5f ) throw E_INVALIDARG; D3DXVECTOR3 vecDiff = vLB - vLT; if( D3DXVec3LengthSq( &vecDiff )< 0.001f ) throw E_INVALIDARG; if( m_fU < 0.001f || m_fV < 0.001f ) throw E_INVALIDARG; CHECK_HR( hr = DXUtil_FindMediaFileCb( achTexturePath, sizeof(TCHAR)*MAX_PATH, achName ), DbgMsg("CPlane::CPlane: cannot find bitmap file %s in SDK media folder", achTexturePath)); // load texture ASSERT( g_pEnvFormat ); CHECK_HR( hr = D3DUtil_CreateTexture( pDevice, achTexturePath, &m_pTexture, *g_pEnvFormat ), DbgMsg("CPlane::CPlane: failed to create the texture, hr = 0x%08x", hr)); // initialize geometry // POSITION // corners memcpy( &(m_V[0].Pos), &vLB, sizeof(D3DVECTOR)); memcpy( &(m_V[1].Pos), &vLT, sizeof(D3DVECTOR)); memcpy( &(m_V[2].Pos), &vRB, sizeof(D3DVECTOR)); memcpy( &(m_V[3].Pos), &vRT, sizeof(D3DVECTOR)); // TEXTURE COORD m_V[0].tu = 0.f; m_V[0].tv = fV; m_V[1].tu = 0.f; m_V[1].tv = 0.f; m_V[2].tu = fU; m_V[2].tv = fV; m_V[3].tu = fU; m_V[3].tv = 0.f; // corners are transparent, middle vertices are opaque m_V[0].color = D3DCOLOR_RGBA( 0xFF, 0xFF, 0xFF, 0xFF); m_V[1].color = D3DCOLOR_RGBA( 0xFF, 0xFF, 0xFF, 0xFF); m_V[2].color = D3DCOLOR_RGBA( 0xFF, 0xFF, 0xFF, 0xFF); m_V[3].color = D3DCOLOR_RGBA( 0xFF, 0xFF, 0xFF, 0xFF); } catch( HRESULT hr1 ) { RELEASE( m_pTexture ); hr = hr1; } if( phr ) { *phr = hr; } }
//----------------------------------------------------------------------------- // Name: InitDeviceObjects() // Desc: Initialize scene objects. //----------------------------------------------------------------------------- HRESULT CMeshRender::InitDeviceObjects() { DWORD cVerticesPerMesh; // Load mesh LPD3DXBUFFER pAdjacencyBuffer = NULL; LPDIRECT3DVERTEXBUFFER9 pVertexBuffer = NULL; LPD3DXMESH pMesh = NULL; LPD3DXPMESH pPMesh = NULL; LPD3DXMESH pTempMesh; LPD3DXBUFFER pD3DXMtrlBuffer = NULL; void* pVertices; TCHAR strMediaPath[512]; HRESULT hr; DWORD dw32BitFlag; DWORD cVerticesMin; DWORD cVerticesMax; DWORD iPMesh; D3DXWELDEPSILONS Epsilons; DWORD i; D3DXMATERIAL* d3dxMaterials; // Find the path to the mesh if( FAILED( DXUtil_FindMediaFileCb( strMediaPath, sizeof(strMediaPath), m_strMeshFilename ) ) ) return E_FAIL;//D3DAPPERR_MEDIANOTFOUND; // Load the mesh from the specified file if( FAILED( hr = D3DXLoadMeshFromX( strMediaPath, D3DXMESH_MANAGED, m_pd3dDevice, &pAdjacencyBuffer, &pD3DXMtrlBuffer, NULL, &m_dwNumMaterials, &pMesh ) ) ) { // hide error so that device changes will not cause exit, shows blank screen instead goto End; } dw32BitFlag = (pMesh->GetOptions() & D3DXMESH_32BIT); // perform simple cleansing operations on mesh if( FAILED( hr = D3DXCleanMesh( pMesh, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), &pTempMesh, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL ) ) ) { m_dwNumMaterials = 0; goto End; } SAFE_RELEASE(pMesh); pMesh = pTempMesh; // Perform a weld to try and remove excess vertices like the model bigship1.x in the DX9.0 SDK (current model is fixed) // Weld the mesh using all epsilons of 0.0f. A small epsilon like 1e-6 works well too memset(&Epsilons, 0, sizeof(D3DXWELDEPSILONS)); if( FAILED( hr = D3DXWeldVertices( pMesh, 0, &Epsilons, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL ) ) ) { m_dwNumMaterials = 0; goto End; } // verify validity of mesh for simplification if( FAILED( hr = D3DXValidMesh( pMesh, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL ) ) ) { m_dwNumMaterials = 0; goto End; } // Allocate a material/texture arrays d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); m_mtrlMeshMaterials = new D3DMATERIAL9[m_dwNumMaterials]; m_pMeshTextures = new LPDIRECT3DTEXTURE9[m_dwNumMaterials]; // Copy the materials and load the textures for( i=0; i<m_dwNumMaterials; i++ ) { m_mtrlMeshMaterials[i] = d3dxMaterials[i].MatD3D; m_mtrlMeshMaterials[i].Ambient = m_mtrlMeshMaterials[i].Diffuse; // Find the path to the texture and create that texture DXUtil_FindMediaFileCb( strMediaPath, sizeof(strMediaPath), d3dxMaterials[i].pTextureFilename ); if( FAILED( D3DXCreateTextureFromFile( m_pd3dDevice, strMediaPath, &m_pMeshTextures[i] ) ) ) m_pMeshTextures[i] = NULL; } pD3DXMtrlBuffer->Release(); pD3DXMtrlBuffer = NULL; // Lock the vertex buffer, to generate a simple bounding sphere hr = pMesh->GetVertexBuffer( &pVertexBuffer ); if( FAILED(hr) ) goto End; hr = pVertexBuffer->Lock( 0, 0, &pVertices, D3DLOCK_NOSYSLOCK ); if( FAILED(hr) ) goto End; hr = D3DXComputeBoundingSphere( (D3DXVECTOR3*)pVertices, pMesh->GetNumVertices(), D3DXGetFVFVertexSize(pMesh->GetFVF()), &m_vObjectCenter, &m_fObjectRadius ); pVertexBuffer->Unlock(); pVertexBuffer->Release(); if( FAILED(hr) || m_dwNumMaterials == 0 ) goto End; if ( !(pMesh->GetFVF() & D3DFVF_NORMAL) ) { hr = pMesh->CloneMeshFVF( dw32BitFlag|D3DXMESH_MANAGED, pMesh->GetFVF() | D3DFVF_NORMAL, m_pd3dDevice, &pTempMesh ); if (FAILED(hr)) goto End; D3DXComputeNormals( pTempMesh, NULL ); pMesh->Release(); pMesh = pTempMesh; } hr = D3DXGeneratePMesh( pMesh, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, 1, D3DXMESHSIMP_VERTEX, &pPMesh); if( FAILED(hr) ) goto End; cVerticesMin = pPMesh->GetMinVertices(); cVerticesMax = pPMesh->GetMaxVertices(); cVerticesPerMesh = (cVerticesMax - cVerticesMin) / 10; m_cPMeshes = max(1, (DWORD)ceil((cVerticesMax - cVerticesMin) / (float)cVerticesPerMesh)); m_pPMeshes = new LPD3DXPMESH[m_cPMeshes]; if (m_pPMeshes == NULL) { hr = E_OUTOFMEMORY; goto End; } memset(m_pPMeshes, 0, sizeof(LPD3DXPMESH) * m_cPMeshes); // clone full size pmesh hr = pPMesh->ClonePMeshFVF( D3DXMESH_MANAGED | D3DXMESH_VB_SHARE, pPMesh->GetFVF(), m_pd3dDevice, &m_pPMeshFull ); if (FAILED(hr)) goto End; // clone all the separate pmeshes for (iPMesh = 0; iPMesh < m_cPMeshes; iPMesh++) { hr = pPMesh->ClonePMeshFVF( D3DXMESH_MANAGED | D3DXMESH_VB_SHARE, pPMesh->GetFVF(), m_pd3dDevice, &m_pPMeshes[iPMesh] ); if (FAILED(hr)) goto End; // trim to appropriate space hr = m_pPMeshes[iPMesh]->TrimByVertices(cVerticesMin + cVerticesPerMesh * iPMesh, cVerticesMin + cVerticesPerMesh * (iPMesh+1), NULL, NULL); if (FAILED(hr)) goto End; hr = m_pPMeshes[iPMesh]->OptimizeBaseLOD(D3DXMESHOPT_VERTEXCACHE, NULL); if (FAILED(hr)) goto End; } // set current to be maximum number of vertices m_iPMeshCur = m_cPMeshes - 1; hr = m_pPMeshes[m_iPMeshCur]->SetNumVertices(cVerticesMax); if (FAILED(hr)) goto End; hr = m_pPMeshFull->SetNumVertices(cVerticesMax); if (FAILED(hr)) goto End; End: SAFE_RELEASE( pAdjacencyBuffer ); SAFE_RELEASE( pD3DXMtrlBuffer ); SAFE_RELEASE( pMesh ); SAFE_RELEASE( pPMesh ); if (FAILED(hr)) { for (iPMesh = 0; iPMesh < m_cPMeshes; iPMesh++) { SAFE_RELEASE( m_pPMeshes[iPMesh] ); } delete []m_pPMeshes; m_cPMeshes = 0; m_pPMeshes = NULL; SAFE_RELEASE( m_pPMeshFull ) } return hr; }
//----------------------------------------------------------------------------- // Name: // Desc: create from a file or build-in object // See paraworldassets for more details. //----------------------------------------------------------------------------- HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCTSTR strFilename ) { // --Paraworld: Create built-in objects // -- modified by [email protected] if(strFilename[0] == '_') { if(strcmp(strFilename,_T("_floor")) == 0) { RestorePolygonMesh(pd3dDevice, 1, 4, &(m_pSysMemMesh)); return S_OK; } } // -- file based mesh object creation. Below are original code by directx sdk sample TCHAR strPath[MAX_PATH]; LPD3DXBUFFER pAdjacencyBuffer = NULL; LPD3DXBUFFER pMtrlBuffer = NULL; HRESULT hr; // Find the path for the file, and convert it to ANSI (for the D3DX API) DXUtil_FindMediaFileCb( strPath, sizeof(strPath), strFilename ); // Load the mesh if( FAILED( hr = D3DXLoadMeshFromX( strPath, D3DXMESH_SYSTEMMEM, pd3dDevice, &pAdjacencyBuffer, &pMtrlBuffer, NULL, &m_dwNumMaterials, &m_pSysMemMesh ) ) ) { return hr; } // Optimize the mesh for performance if( FAILED( hr = m_pSysMemMesh->OptimizeInplace( D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) ) { SAFE_RELEASE( pAdjacencyBuffer ); SAFE_RELEASE( pMtrlBuffer ); return hr; } // Get material info for the mesh // Get the array of materials out of the buffer if( pMtrlBuffer && m_dwNumMaterials > 0 ) { // Allocate memory for the materials and textures D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer(); m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials]; if( m_pMaterials == NULL ) { hr = E_OUTOFMEMORY; goto LEnd; } m_pTextures = new LPDIRECT3DTEXTURE9[m_dwNumMaterials]; if( m_pTextures == NULL ) { hr = E_OUTOFMEMORY; goto LEnd; } // Copy each material and create its texture for( DWORD i=0; i<m_dwNumMaterials; i++ ) { // Copy the material m_pMaterials[i] = d3dxMtrls[i].MatD3D; m_pTextures[i] = NULL; // Create a texture if( d3dxMtrls[i].pTextureFilename ) { TCHAR strTexture[MAX_PATH]; TCHAR strTextureTemp[MAX_PATH]; DXUtil_ConvertAnsiStringToGenericCb( strTextureTemp, d3dxMtrls[i].pTextureFilename, sizeof(strTextureTemp) ); DXUtil_FindMediaFileCb( strTexture, sizeof(strTexture), strTextureTemp ); if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, &m_pTextures[i] ) ) ) m_pTextures[i] = NULL; } } } hr = S_OK; LEnd: SAFE_RELEASE( pAdjacencyBuffer ); SAFE_RELEASE( pMtrlBuffer ); return hr; }