bool CEntity::ComputeNormalVector( LPD3DXMESH _pMesh, D3DXVECTOR3& _vNormal, D3DXVECTOR3& _vCol, CEntity* target) { BOOL isHit = false; DWORD dwFaceIndex = 0; float fDist = 0; LPD3DXBUFFER ppAllhit; DWORD pCountOfHits; D3DXVECTOR3 vPos = m_vPos - target->GetPos(); D3DXVECTOR3 vtar = (-vPos); D3DXVec3Normalize( &vtar, &vtar); D3DXIntersect( _pMesh, &vPos, &vtar, &isHit, &dwFaceIndex, NULL, NULL, &fDist, &ppAllhit, &pCountOfHits ); if ( !isHit || fDist > GetSize() ) return false;// Ãæµ¹ÀÌ ¾È‰ç°Å³ª °Å¸®°¡ ¸Ö´Ù¸é ¸®ÅÏ; LPDIRECT3DVERTEXBUFFER9 pVB; LPDIRECT3DINDEXBUFFER9 pIB; _pMesh->GetVertexBuffer(&pVB); _pMesh->GetIndexBuffer( &pIB ); WORD* pIndices; D3DVERTEX* pVertices; pIB->Lock( 0, 0, (void**)&pIndices, 0 ); pVB->Lock( 0, 0,(void**)&pVertices, 0); D3DXVECTOR3 v0 = pVertices[pIndices[3*dwFaceIndex+0]].vPos; D3DXVECTOR3 v1 = pVertices[pIndices[3*dwFaceIndex+1]].vPos; D3DXVECTOR3 v2 = pVertices[pIndices[3*dwFaceIndex+2]].vPos; D3DXPLANE plane; D3DXPlaneFromPoints( &plane, &v0, &v1, &v2); _vCol = (v0 + v1 + v2)/3.f; _vCol += target->GetPos(); _vNormal.x = plane.a; _vNormal.y = plane.b; _vNormal.z = plane.c; #ifdef _DEBUG //Ãæµ¹ÁöÁ¡ Ç¥½Ã _SINGLE(CDebug)->AddPosMark( _vCol, COLOR_BLACK); #endif pVB->Unlock(); pIB->Unlock(); Safe_Release(pVB); Safe_Release(pIB); return true; }
/** * \brief Called to render a mesh * \param device - the Direct3D device object * \param meshContainerBase - the mesh container * \param frameBase - frame containing the mesh * \author Keith Ditchburn \date 18 July 2005 */ void CXFileEntity::DrawMeshContainer(LPD3DXMESHCONTAINER meshContainerBase, LPD3DXFRAME frameBase) { DWORD attrSize = 0; // Cast to our extended frame type D3DXFRAME_EXTENDED *frame = (D3DXFRAME_EXTENDED*)frameBase; // Cast to our extended mesh container D3DXMESHCONTAINER_EXTENDED *meshContainer = (D3DXMESHCONTAINER_EXTENDED*)meshContainerBase; // Set the world transform m_d3dDevice->SetTransform(D3DTS_WORLD, &frame->exCombinedTransformationMatrix); unsigned int pass; if (effect) { effect->SetMatrix("worldmat",&frame->exCombinedTransformationMatrix); effect->Begin(&pass,0); effect->BeginPass(0); } // Loop through all the materials in the mesh rendering each subset for (unsigned int iMaterial = 0; iMaterial < meshContainer->NumMaterials; iMaterial++) { // use the material in our extended data rather than the one in meshContainer->pMaterials[iMaterial].MatD3D //m_d3dDevice->SetMaterial( &meshContainer->exMaterials[iMaterial] ); //m_d3dDevice->SetTexture( 0, meshContainer->exTextures[iMaterial] ); // Select the mesh to draw, if there is skin then use the skinned mesh else the normal one LPD3DXMESH pDrawMesh = (meshContainer->pSkinInfo) ? meshContainer->exSkinMesh: meshContainer->MeshData.pMesh; // Finally Call the mesh draw function //pDrawMesh->DrawSubset(iMaterial); pDrawMesh->GetVertexBuffer(&vb.vb); pDrawMesh->GetIndexBuffer(&ib.ib); //D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE]; //pDrawMesh->GetDeclaration(pDecl); //renderSystem->CreateVertexDeclaration(&pDecl[0],&vb.declaration); // Получение данных о количестве вершин, индексов и полигонов dwNumVerticies = pDrawMesh->GetNumVertices(); dwNumIndecies = pDrawMesh->GetNumFaces()*3; dwNumFaces = pDrawMesh->GetNumFaces(); vb.vertexSize = (short)pDrawMesh->GetNumBytesPerVertex(); renderSystem->DrawIndexedPrimitive(vb,0,dwNumVerticies,ib,0,dwNumFaces); } if (effect) { effect->EndPass(); effect->End(); } }
HRESULT initGeometry(){ LPD3DXBUFFER pD3DXMtrlBuffer; if(FAILED(D3DXLoadMeshFromX(L"seafloor.x", D3DXMESH_MANAGED, g_pDevice, NULL, &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh))) return E_FAIL; //Extract material & texture D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials]; if(g_pMeshMaterials == NULL) return E_OUTOFMEMORY; g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials]; if(g_pMeshTextures == NULL) return E_OUTOFMEMORY; //Extract for(DWORD i=0; i<g_dwNumMaterials; ++i){ g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D; g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse; g_pMeshTextures[i] = NULL; if(d3dxMaterials[i].pTextureFilename != NULL && strlen(d3dxMaterials[i].pTextureFilename) > 0){ WCHAR name[256]; removePathFromFileName(d3dxMaterials[i].pTextureFilename, name); if(FAILED(D3DXCreateTextureFromFile(g_pDevice, name, &g_pMeshTextures[i]))){ MessageBox(NULL, L"Cound not find texture file", L"initGeometry()", MB_OK); } } } pD3DXMtrlBuffer->Release(); //Modify the mesh LPDIRECT3DVERTEXBUFFER9 pVB; if(SUCCEEDED(g_pMesh->GetVertexBuffer(&pVB))){ struct VERTEX{FLOAT x,y,z,tu,tv;}; VERTEX* pVertices; DWORD dwNumVertices = g_pMesh->GetNumVertices(); pVB->Lock(0,0,(void**)&pVertices, 0); for(DWORD i=0; i<dwNumVertices; ++i) pVertices[i].y = heightField(pVertices[i].x, pVertices[i].z); pVB->Unlock(); pVB->Release(); } return S_OK; };
bool CMesh::__GetBoundBox(const LPD3DXMESH pMesh, CRectangle3D& Rect3d) { if (pMesh == NULL) return false; UINT uVertexNum = pMesh->GetNumVertices(); LPD3DXMESH pTempMesh; pMesh->CloneMeshFVF(D3DXMESH_SYSTEMMEM, D3DFVF_XYZ, &DEVICE, &pTempMesh); LPDIRECT3DVERTEXBUFFER9 pVertexBuffer; pTempMesh->GetVertexBuffer(&pVertexBuffer); FLOAT maxX = 0.0f, maxY = 0.0f, maxZ = 0.0f; FLOAT minX = 0.0f, minY = 0.0f, minZ = 0.0f; D3DXVECTOR3* pVertices; pVertexBuffer->Lock(0, 0, (void**)&pVertices, 0); for(UINT i = 0; i < uVertexNum; i ++) { if(pVertices[i].x > maxX) maxX = pVertices[i].x; if(pVertices[i].y > maxY) maxY = pVertices[i].y; if(pVertices[i].z > maxZ) maxZ = pVertices[i].z; if(pVertices[i].x < minX) minX = pVertices[i].x; if(pVertices[i].y < minY) minY = pVertices[i].y; if(pVertices[i].z < minZ) minZ = pVertices[i].z; } pVertexBuffer->Unlock(); Rect3d.Set(minX, maxX, minY, maxY, minZ, maxZ); DEBUG_RELEASE(pVertexBuffer); DEBUG_RELEASE(pTempMesh); return true; }
//------------------------------------------------------------------------------ //this is a check function //------------------------------------------------------------------------------ void TriPickDemo::checkPick(LPD3DXMESH mesh, D3DXMATRIX matWorld) { HRESULT hr; D3DXMATRIX mWorldViewProjection; mWorldViewProjection = matWorld * g_Camera->viewProj(); HR(m_FX->SetTechnique("RenderScene")); // send matrix to shader HR(m_FX->SetMatrix("g_mWorldViewProjection", &mWorldViewProjection)); HR(m_FX->SetMatrix("g_mWorld", &matWorld)); UINT uPasses; V(m_FX->Begin(&uPasses, 0)); g_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); V(m_FX->BeginPass(0)); //get select ray D3DXVECTOR3 originW(0.0f, 0.0f, 0.0f); D3DXVECTOR3 dirW(0.0f, 0.0f, 0.0f); if (gDInput->mouseButtonDown(0)) { getWorldPickingRay(originW, dirW, matWorld); LPD3DXMESH pMesh; mesh->CloneMeshFVF(D3DXMESH_MANAGED, D3DVERTEX::FVF, g_pDevice, &pMesh); BOOL hit = 0; DWORD faceIndex = -1; float u = 0.0f; float v = 0.0f; float dist = 0.0f; ID3DXBuffer* allhits = 0; DWORD numHits = 0; HR(D3DXIntersect(pMesh, &originW, &dirW, &hit, &faceIndex, &u, &v, &dist, &allhits, &numHits)); SAFE_RELEASE(allhits); //if hit if (hit) { IDirect3DVertexBuffer9* vb = 0; IDirect3DIndexBuffer9* ib = 0; HR(pMesh->GetVertexBuffer(&vb)); HR(pMesh->GetIndexBuffer(&ib)); HR(g_pDevice->SetIndices(ib)); HR(g_pDevice->SetFVF(D3DVERTEX::FVF)); HR(g_pDevice->SetStreamSource(0, vb, 0, sizeof(D3DVERTEX))); //render hit surface HR(g_pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, pMesh->GetNumVertices(), faceIndex * 3, 1)) g_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); SAFE_RELEASE(vb); SAFE_RELEASE(ib); SAFE_RELEASE(pMesh); } } HR(m_FX->EndPass()); HR(m_FX->End()); }
HRESULT EVERYMODULE::DrawMesh(LPD3DXMESH newmesh, UINT EPointSize) { if(!Mesh) return E_FAIL; HRESULT att=S_OK; LPDIRECT3DVERTEXBUFFER9 vertexbuffer; LPDIRECT3DINDEXBUFFER9 indexbuffer; if(newmesh==NULL) { if(CreateAttrib==1) { Mesh->GetVertexBuffer(&vertexbuffer); d3ddevice->SetStreamSource(0, vertexbuffer, 0, EachPointSize); if(VertexShader && Declaration) { d3ddevice->SetVertexDeclaration(Declaration); d3ddevice->SetVertexShader(VertexShader); } else { // d3ddevice->SetVertexDeclaration(NULL); d3ddevice->SetVertexShader(NULL); d3ddevice->SetFVF(m_FVF); } d3ddevice->SetMaterial(&Material); d3ddevice->BeginScene(); if(FAILED(d3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, VertexNum-2))) att=E_FAIL; d3ddevice->EndScene(); } else if(CreateAttrib==2) { Mesh->GetVertexBuffer(&vertexbuffer); Mesh->GetIndexBuffer(&indexbuffer); d3ddevice->SetStreamSource(0, vertexbuffer, 0, EachPointSize); d3ddevice->SetIndices(indexbuffer); if(VertexShader && Declaration) { d3ddevice->SetVertexDeclaration(Declaration); d3ddevice->SetVertexShader(VertexShader); } else { // d3ddevice->SetVertexDeclaration(NULL); d3ddevice->SetVertexShader(NULL); d3ddevice->SetFVF(m_FVF); } d3ddevice->SetMaterial(&Material); d3ddevice->BeginScene(); if(FAILED(d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, VertexNum, 0, IndexVertexNum/3))) att=E_FAIL; d3ddevice->EndScene(); } } else { if(CreateAttrib==1) { newmesh->GetVertexBuffer(&vertexbuffer); d3ddevice->SetStreamSource(0, vertexbuffer, 0, EPointSize); if(VertexShader && Declaration) { d3ddevice->SetVertexDeclaration(Declaration); d3ddevice->SetVertexShader(VertexShader); } else { // d3ddevice->SetVertexDeclaration(NULL); d3ddevice->SetVertexShader(NULL); d3ddevice->SetFVF(m_FVF); } d3ddevice->SetMaterial(&Material); d3ddevice->BeginScene(); if(FAILED(d3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, VertexNum-2))) att=E_FAIL; d3ddevice->EndScene(); } else if(CreateAttrib==2) { newmesh->GetVertexBuffer(&vertexbuffer); newmesh->GetIndexBuffer(&indexbuffer); d3ddevice->SetStreamSource(0, vertexbuffer, 0, EPointSize); d3ddevice->SetIndices(indexbuffer); if(VertexShader && Declaration) { d3ddevice->SetVertexDeclaration(Declaration); d3ddevice->SetVertexShader(VertexShader); } else { // d3ddevice->SetVertexDeclaration(NULL); d3ddevice->SetVertexShader(NULL); d3ddevice->SetFVF(m_FVF); } d3ddevice->SetMaterial(&Material); d3ddevice->BeginScene(); if(FAILED(d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, VertexNum, 0, IndexVertexNum/3))) att=E_FAIL; d3ddevice->EndScene(); } } return att; }
//----------------------------------------------------------------------------- // 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; }
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; }
//----------------------------------------------------------------------------- // Name: InitGeometry() // Desc: Load the mesh and build the material and texture arrays //----------------------------------------------------------------------------- HRESULT InitGeometry() { LPD3DXBUFFER pD3DXMtrlBuffer; LPDIRECT3DVERTEXBUFFER9 pMeshSourceVB; LPDIRECT3DINDEXBUFFER9 pMeshSourceIB; D3DVERTEX* pSrc; D3DVERTEX* pDst; // load the textures we are going to be using if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"cartoonpallet-white-to-black.bmp", &g_pTexture ) ) ) MessageBox(NULL, L"Texture Load Problem", NULL, NULL); if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"cartoonpallet-black-to-white.bmp", &g_pTexture2 ) ) ) MessageBox(NULL, L"Texture Load Problem", NULL, NULL); if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"marble.bmp", &marbleTexture ) ) ) MessageBox(NULL, L"Texture Load Problem", NULL, NULL); if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"background.jpg", &backgroundTexture ) ) ) MessageBox(NULL, L"Texture Load Problem", NULL, NULL); // Load the mesh from the specified file if( FAILED( D3DXLoadMeshFromX( L"skull.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh ) ) ) g_pd3dDevice->SetFVF(D3DFVF_D3DVERTEX ); g_dwNumVertices = g_pMesh->GetNumVertices(); g_dwNumFaces = g_pMesh->GetNumFaces(); //Clone the mesh to set the FVF LPD3DXMESH pTempSysMemMesh = NULL; if( FAILED( g_pMesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM, D3DFVF_D3DVERTEX, g_pd3dDevice, &pTempSysMemMesh ) ) ) MessageBox(NULL,L"Mesh clone problem",NULL,NULL); g_pMesh->Release(); g_pMesh = pTempSysMemMesh; //Compute normals in case the meshes have them if( g_pMesh ) D3DXComputeNormals( g_pMesh, NULL ); //Meshes cloned if( FAILED(g_pd3dDevice->CreateVertexBuffer( g_dwNumVertices * sizeof(D3DVERTEX), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &g_pMeshVB, NULL ))) MessageBox(NULL,L"Vertex buffer create problem",NULL,NULL); if( FAILED(g_pd3dDevice->CreateIndexBuffer( g_dwNumFaces * 3 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &g_pMeshIB, NULL ))) MessageBox(NULL,L"Index buffer create problem",NULL,NULL); g_pMesh->GetVertexBuffer(&pMeshSourceVB); g_pMeshVB->Lock( 0, 0, (void**)&pDst, 0 ); pMeshSourceVB->Lock( 0, 0, (void**)&pSrc, 0 ); memcpy( pDst, pSrc, g_dwNumVertices * sizeof(D3DVERTEX) ); g_pMeshVB->Unlock(); pMeshSourceVB->Unlock(); pMeshSourceVB->Release(); g_pMesh->GetIndexBuffer(&pMeshSourceIB); g_pMeshIB->Lock( 0, 0, (void**)&pDst, 0 ); pMeshSourceIB->Lock( 0, 0, (void**)&pSrc, 0 ); memcpy( pDst, pSrc, g_dwNumFaces * 3 * sizeof(WORD)); g_pMeshIB->Unlock(); pMeshSourceIB->Unlock(); pMeshSourceIB->Release(); //// Done with the material buffer pD3DXMtrlBuffer->Release(); return S_OK; }