//----------------------------------------------------------------------------- // Name: // Desc: //----------------------------------------------------------------------------- HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strFilename ) { TCHAR strPath[MAX_PATH]; CHAR strPathANSI[MAX_PATH]; LPD3DXBUFFER pMtrlBuffer = NULL; HRESULT hr; // Find the path for the file, and convert it to ANSI (for the D3DX API) DXUtil_FindMediaFile( strPath, strFilename ); DXUtil_ConvertGenericStringToAnsi( strPathANSI, strPath ); // Load the mesh if( FAILED( hr = D3DXLoadMeshFromX( strPathANSI, D3DXMESH_SYSTEMMEM, pd3dDevice, NULL, &pMtrlBuffer, &m_dwNumMaterials, &m_pSysMemMesh ) ) ) 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 D3DMATERIAL8[m_dwNumMaterials]; m_pTextures = new LPDIRECT3DTEXTURE8[m_dwNumMaterials]; // Copy each material and create it's texture for( DWORD i=0; i<m_dwNumMaterials; i++ ) { // Copy the material m_pMaterials[i] = d3dxMtrls[i].MatD3D; m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse; m_pTextures[i] = NULL; // Create a texture if( d3dxMtrls[i].pTextureFilename ) { TCHAR strTexture[MAX_PATH]; CHAR strTextureANSI[MAX_PATH]; DXUtil_ConvertGenericStringToAnsi( strTextureANSI, d3dxMtrls[i].pTextureFilename ); DXUtil_FindMediaFile( strTexture, strTextureANSI ); if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, &m_pTextures[i] ) ) ) m_pTextures[i] = NULL; } } } SAFE_RELEASE( pMtrlBuffer ); return S_OK; }
//----------------------------------------------------------------------------- // Name: // Desc: //----------------------------------------------------------------------------- HRESULT CD3DFile::Create( LPDIRECT3DDEVICE8 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_FindMediaFile( strPath, strFilename ); DXUtil_ConvertGenericStringToAnsi( strPathANSI, strPath ); // 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( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strTexture, LPDIRECT3DTEXTURE8* ppTexture, D3DFORMAT d3dFormat ) { // Get the path to the texture TCHAR strPath[MAX_PATH]; DXUtil_FindMediaFile( strPath, strTexture ); // 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: InitDeviceObjects() // Desc: Initialize scene objects. //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::InitDeviceObjects() { HRESULT hr = S_OK; // Restore the fonts m_pFont->InitDeviceObjects( m_pd3dDevice ); // if no filename, use the default if (m_szPath[0] == '\0') { DXUtil_FindMediaFile( m_szPath, _T("tiny.x") ); } LoadMeshHierarchy(); if( m_pdeHead != NULL) m_ArcBall.SetRadius( m_pdeHead->fRadius ); m_ArcBall.SetRightHanded( TRUE ); return S_OK; }
//----------------------------------------------------------------------------- // Name: // Desc: //----------------------------------------------------------------------------- HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE8 pd3dDevice, LPDIRECTXFILEDATA pFileData ) { LPD3DXBUFFER pMtrlBuffer = NULL; LPD3DXBUFFER pAdjacencyBuffer = NULL; HRESULT hr; // Load the mesh from the DXFILEDATA object if( FAILED( hr = D3DXLoadMeshFromXof( pFileData, D3DXMESH_SYSTEMMEM, pd3dDevice, &pAdjacencyBuffer, &pMtrlBuffer, &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 D3DMATERIAL8[m_dwNumMaterials]; m_pTextures = new LPDIRECT3DTEXTURE8[m_dwNumMaterials]; // 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_pMaterials[i].Ambient = m_pMaterials[i].Diffuse; m_pTextures[i] = NULL; // Create a texture if( d3dxMtrls[i].pTextureFilename ) { TCHAR strTexture[MAX_PATH]; TCHAR strTextureTemp[MAX_PATH]; DXUtil_ConvertAnsiStringToGeneric( strTextureTemp, d3dxMtrls[i].pTextureFilename ); DXUtil_FindMediaFile( strTexture, strTextureTemp ); if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, &m_pTextures[i] ) ) ) m_pTextures[i] = NULL; } } } SAFE_RELEASE( pAdjacencyBuffer ); SAFE_RELEASE( pMtrlBuffer ); return S_OK; }
//----------------------------------------------------------------------------- // Name: RestoreDeviceObjects // Desc: //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::RestoreDeviceObjects() { HRESULT hr; // Restore the font m_pFont->RestoreDeviceObjects(); m_pFontSmall->RestoreDeviceObjects(); // Create light D3DLIGHT8 light; ZeroMemory(&light, sizeof(light)); light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse.r = m_colorLight.r; light.Diffuse.g = m_colorLight.g; light.Diffuse.b = m_colorLight.b; light.Diffuse.a = m_colorLight.a; light.Specular.r = 1.0f; light.Specular.g = 1.0f; light.Specular.b = 1.0f; light.Specular.a = 0.0f; light.Direction.x = m_vecLight.x; light.Direction.y = m_vecLight.y; light.Direction.z = m_vecLight.z; m_pd3dDevice->SetLight(0, &light); m_pd3dDevice->LightEnable(0, TRUE); // Create material D3DMATERIAL8 material; ZeroMemory(&material, sizeof(material)); material.Diffuse.a = 1.0f; material.Specular.r = 0.5f; material.Specular.g = 0.5f; material.Specular.b = 0.5f; material.Power = 20.0f; m_pd3dDevice->SetMaterial(&material); // Setup render states m_pd3dDevice->SetVertexShader(D3DFVF_XYZ); m_pd3dDevice->SetTransform(D3DTS_VIEW, &m_matView); m_pd3dDevice->SetTransform(D3DTS_WORLD, &m_matIdentity); m_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); m_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE); m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); m_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT); m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); m_pd3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); m_pd3dDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); m_pd3dDevice->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR); m_pd3dDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); m_pd3dDevice->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT); m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); // Create caustic texture D3DDISPLAYMODE mode; m_pd3dDevice->GetDisplayMode(&mode); if(FAILED(hr = D3DXCreateTexture(m_pd3dDevice, WATER_CAUSTICS_SIZE, WATER_CAUSTICS_SIZE, 1, D3DUSAGE_RENDERTARGET, mode.Format, D3DPOOL_DEFAULT, &m_pCausticTex)) && FAILED(hr = D3DXCreateTexture(m_pd3dDevice, WATER_CAUSTICS_SIZE, WATER_CAUSTICS_SIZE, 1, 0, mode.Format, D3DPOOL_DEFAULT, &m_pCausticTex))) { return hr; } D3DSURFACE_DESC desc; m_pCausticTex->GetSurfaceLevel(0, &m_pCausticSurf); m_pCausticSurf->GetDesc(&desc); if(FAILED(hr = D3DXCreateRenderToSurface(m_pd3dDevice, desc.Width, desc.Height, desc.Format, FALSE, D3DFMT_UNKNOWN, &m_pRenderToSurface))) { return hr; } // Shader TCHAR sz[512]; DXUtil_FindMediaFile(sz, _T("water.sha")); if(FAILED(hr = D3DXCreateEffectFromFile(m_pd3dDevice, sz, &m_pEffect, NULL))) return hr; m_pEffect->SetMatrix("mID", &m_matIdentity); m_pEffect->SetMatrix("mENV", &m_matIdentity); m_pEffect->SetTexture("tFLR", m_pFloorTex); m_pEffect->SetTexture("tCAU", m_pCausticTex); m_pEffect->SetTexture("tENV", m_pSkyCubeTex); if(FAILED(hr = GetNextTechnique(0, FALSE))) return hr; // Set surfaces if(FAILED(hr = m_Environment.SetSurfaces( m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_X], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_X], m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_Y], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_Y], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_Z], m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_Z]))) { return hr; } // OnResetDevice if(FAILED(hr = m_Water.OnResetDevice())) return hr; if(FAILED(hr = m_Environment.OnResetDevice())) return hr; return S_OK; }
//----------------------------------------------------------------------------- // Name: InitDeviceObjects // Desc: //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::InitDeviceObjects() { HRESULT hr; TCHAR sz[512]; m_bDrawWater = TRUE; m_bDrawCaustics = TRUE; m_bDrawEnvironment = TRUE; // Initialize the font's internal textures m_pFont->InitDeviceObjects( m_pd3dDevice ); m_pFontSmall->InitDeviceObjects( m_pd3dDevice ); // Floor DXUtil_FindMediaFile(sz, _T("Water.bmp")); D3DXCreateTextureFromFileEx(m_pd3dDevice, sz, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &m_pFloorTex); // Sky TCHAR* szSkyTex[6] = { _T("lobbyxpos.bmp"), _T("lobbyxneg.bmp"), _T("lobbyypos.bmp"), _T("lobbyyneg.bmp"), _T("lobbyzneg.bmp"), _T("lobbyzpos.bmp") }; for(UINT i = 0; i < 6; i++) { DXUtil_FindMediaFile(sz, szSkyTex[i]); D3DXCreateTextureFromFileEx(m_pd3dDevice, sz, D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &m_pSkyTex[i]); } if(SUCCEEDED(D3DXCreateCubeTexture(m_pd3dDevice, 128, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, &m_pSkyCubeTex))) { for(UINT i = 0; i < 6; i++) { if(m_pSkyTex[i]) { IDirect3DSurface8 *pSrc; IDirect3DSurface8 *pDest; m_pSkyTex[i]->GetSurfaceLevel(0, &pSrc); m_pSkyCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES) i, 0, &pDest); if(pSrc && pDest) D3DXLoadSurfaceFromSurface(pDest, NULL, NULL, pSrc, NULL, NULL, D3DX_DEFAULT, 0); SAFE_RELEASE(pDest); SAFE_RELEASE(pSrc); } } D3DXFilterCubeTexture(m_pSkyCubeTex, NULL, 0, D3DX_DEFAULT); } // OnCreateDevice if(FAILED(hr = m_Water.OnCreateDevice(m_pd3dDevice))) return hr; if(FAILED(hr = m_Environment.OnCreateDevice(m_pd3dDevice))) return hr; return S_OK; }
HRESULT CMyD3DApplication::LoadMeshData ( LPD3DXMESH *ppMesh, LPD3DXBUFFER *ppAdjacencyBuffer ) { LPDIRECT3DVERTEXBUFFER8 pMeshVB = NULL; LPD3DXBUFFER pD3DXMtrlBuffer = NULL; BYTE* pVertices; TCHAR strMesh[512]; HRESULT hr = S_OK; BOOL bNormalsInFile; LPD3DXMESH pMeshSysMem = NULL; LPD3DXMESH pMeshTemp; DWORD *rgdwAdjacencyTemp = NULL; DWORD i; D3DXMATERIAL* d3dxMaterials; DWORD dw32Bit; // Get a path to the media file DXUtil_FindMediaFile( strMesh, m_strMeshFilename ); // Load the mesh from the specified file hr = D3DXLoadMeshFromX( strMesh, D3DXMESH_SYSTEMMEM, m_pd3dDevice, ppAdjacencyBuffer, &pD3DXMtrlBuffer, &m_dwNumMaterials, &pMeshSysMem ); if( FAILED(hr) ) goto End; // remember if the mesh is 32 or 16 bit, to be added in on the clones dw32Bit = pMeshSysMem->GetOptions() & D3DXMESH_32BIT; // Get the array of materials out of the returned buffer, and allocate a texture array d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); m_pMeshMaterials = new D3DMATERIAL8[m_dwNumMaterials]; m_pMeshTextures = new LPDIRECT3DTEXTURE8[m_dwNumMaterials]; for( i=0; i<m_dwNumMaterials; i++ ) { m_pMeshMaterials[i] = d3dxMaterials[i].MatD3D; m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse; m_pMeshTextures[i] = NULL; // Get a path to the texture TCHAR strPath[512]; if (d3dxMaterials[i].pTextureFilename != NULL) { DXUtil_FindMediaFile( strPath, d3dxMaterials[i].pTextureFilename ); // Load the texture D3DXCreateTextureFromFile( m_pd3dDevice, strPath, &m_pMeshTextures[i] ); } } // Done with the material buffer SAFE_RELEASE( pD3DXMtrlBuffer ); // Lock the vertex buffer, to generate a simple bounding sphere hr = pMeshSysMem->GetVertexBuffer( &pMeshVB ); if( SUCCEEDED(hr) ) { hr = pMeshVB->Lock( 0, 0, &pVertices, D3DLOCK_NOSYSLOCK ); if( SUCCEEDED(hr) ) { hr = D3DXComputeBoundingSphere( pVertices, pMeshSysMem->GetNumVertices(), pMeshSysMem->GetFVF(), &m_vObjectCenter, &m_fObjectRadius ); pMeshVB->Unlock(); } pMeshVB->Release(); } if( FAILED(hr) ) goto End; // remember if there were normals in the file, before possible clone operation bNormalsInFile = pMeshSysMem->GetFVF() & D3DFVF_NORMAL; // if using 32byte vertices, check fvf if (m_bForce32ByteFVF) { // force 32 byte vertices if (pMeshSysMem->GetFVF() != (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)) { hr = pMeshSysMem->CloneMeshFVF( pMeshSysMem->GetOptions(), D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1, m_pd3dDevice, &pMeshTemp ); if( FAILED(hr) ) goto End; pMeshSysMem->Release(); pMeshSysMem = pMeshTemp; } } // otherwise, just make sure that there is a normal mesh else if ( !(pMeshSysMem->GetFVF() & D3DFVF_NORMAL) ) { hr = pMeshSysMem->CloneMeshFVF( pMeshSysMem->GetOptions(), pMeshSysMem->GetFVF() | D3DFVF_NORMAL, m_pd3dDevice, &pMeshTemp ); if (FAILED(hr)) return hr; pMeshSysMem->Release(); pMeshSysMem = pMeshTemp; } // Compute normals for the mesh, if not present if (!bNormalsInFile) { D3DXComputeNormals( pMeshSysMem, NULL ); } *ppMesh = pMeshSysMem; pMeshSysMem = NULL; End: SAFE_RELEASE( pMeshSysMem ); return hr; }