跟着我一步一步来吧(我的思路和过程)。 我有一个能画出微软例子中tiger.x的工程,其中创建Mesh的代码片断如下(代码中有一些变量在.h文档中定义的): HRESULT CMyMesh::Create( LPDIRECT3DDEVICE9 pDevice, string MeshFile ) { if( pDevice == NULL ) return E_FAIL;
LPD3DXBUFFER pD3DXMtrlBuffer; if( FAILED( D3DXLoadMeshFromX( MeshFile.c_str(), D3DXMESH_SYSTEMMEM, pDevice, NULL, &pD3DXMtrlBuffer, NULL, &NumOfMaterials, &Mesh ) ) ) return E_FAIL; D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); MeshMaterials = new D3DMATERIAL9[NumOfMaterials]; MeshTextures = new LPDIRECT3DTEXTURE9[NumOfMaterials];
for( DWORD i = 0; i < NumOfMaterials_; i ++ ) { MeshMaterials[i] = d3dxMaterials[i].MatD3D; MeshMaterials[i].Ambient = MeshMaterials[i].Diffuse; MeshTextures[i] = NULL; if( d3dxMaterials[i].pTextureFilename != NULL && lstrlen(d3dxMaterials[i].pTextureFilename) > 0 ) { if( FAILED( D3DXCreateTextureFromFile( pDevice, d3dxMaterials[i].pTextureFilename, &MeshTextures[i] ) ) ) return E_FAIL; } }
pD3DXMtrlBuffer->Release(); return S_OK; }
画这个Mesh的代码如下: void CMyMesh::Render( LPDIRECT3DDEVICE9 pDevice ) { for( DWORD i = 0; i < NumOfMaterials; i ++ ) { pDevice->SetMaterial( &MeshMaterials[i] ); pDevice->SetTexture( 0, MeshTextures[i] );
Mesh->DrawSubset( i ); } } 我们先想办法替换DrawSubset函数,代码如下: void CMyMesh::Render( LPDIRECT3DDEVICE9 pDevice ) { LPDIRECT3DVERTEXBUFFER9 pVertexBuffer; LPDIRECT3DINDEXBUFFER9 pIndexBuffer; DWORD dwNumBytesPerVertex; DWORD dwFVF; DWORD dwNumVertex; DWORD dwFaces; Mesh->GetVertexBuffer(&pVertexBuffer); Mesh->GetIndexBuffer(&pIndexBuffer); dwNumBytesPerVertex = Mesh->GetNumBytesPerVertex(); dwFVF = Mesh->GetFVF(); dwNumVertex = Mesh->GetNumVertices(); dwFaces = Mesh->GetNumFaces();
pDevice->SetStreamSource(0, pVertexBuffer, 0, dwNumBytesPerVertex); pDevice->SetFVF(dwFVF); pDevice->SetTexture(0, MeshTextures[0]); pDevice->SetMaterial(&MeshMaterials[0]); pDevice->SetIndices(pIndexBuffer); pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, dwNumVertex, 0, dwFaces); } 虽然MeshTextures和MeshMaterials处有点问题,但是我们知道了画tiger.x的时候都需要什么东西: VB,IB,NumBytesPerVertex,FVF,NumVertex,Faces,Texture,Material 那么我们将这些东西保存到文件中,不就和.x文件目的相同了么, 并且可以绕过D3DXMesh了。那么这些东西怎么得到呢:我修改了Create部分的代码:
HRESULT CMyMesh::Create( LPDIRECT3DDEVICE9 pDevice, string MeshFile ) { if( pDevice == NULL ) return E_FAIL;
LPD3DXBUFFER pD3DXMtrlBuffer; if( FAILED( D3DXLoadMeshFromX( MeshFile.c_str(), D3DXMESH_SYSTEMMEM, pDevice, NULL, &pD3DXMtrlBuffer, NULL, &NumOfMaterials, &Mesh ) ) ) return E_FAIL; D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); MeshMaterials = new D3DMATERIAL9[NumOfMaterials]; MeshTextures = new LPDIRECT3DTEXTURE9[NumOfMaterials];
for( DWORD i = 0; i < NumOfMaterials_; i ++ ) { MeshMaterials_[i] = d3dxMaterials[i].MatD3D; MeshMaterials_[i].Ambient = MeshMaterials_[i].Diffuse; MeshTextures_[i] = NULL; if( d3dxMaterials[i].pTextureFilename != NULL && lstrlen(d3dxMaterials[i].pTextureFilename) > 0 ) { FILE* fp; int nLen = 0; char* pBuf; if(fp=fopen( d3dxMaterials[i].pTextureFilename, "rb" )) { fseek(fp,0,SEEK_END); nLen = ftell(fp); fseek(fp,0,SEEK_SET); pBuf = new char[nLen]; fread(pBuf,1,nLen,fp); fclose(fp); } HRESULT hr = D3DXCreateTextureFromFileInMemory(D3DDevice,pBuf,nLen,&MeshTextures[i]); delete [] pBuf;
//HRESULT hr = D3DXCreateTextureFromFile( D3DDevice_, d3dxMaterials[i].pTextureFilename, &MeshTextures_[i] ); if( FAILED( hr ) ) return E_FAIL; } }
//下面是增加的内容 FILE* fp; if( ( fp = fopen("tiger.o","w") ) != NULL ) { LPDIRECT3DVERTEXBUFFER9 pVertexBuffer; LPDIRECT3DINDEXBUFFER9 pIndexBuffer; D3DVERTEXBUFFER_DESC desc; D3DINDEXBUFFER_DESC idesc; Mesh->GetVertexBuffer(&pVertexBuffer); Mesh->GetIndexBuffer(&pIndexBuffer); pVertexBuffer->GetDesc( &desc ); pIndexBuffer->GetDesc( &idesc ); VOID* pVBData = NULL; VOID* pIBData = NULL; pVertexBuffer->Lock( 0, 0, (VOID**)&pVBData, 0 ); pIndexBuffer->Lock( 0, 0, (VOID**)&pIBData, 0 ); DWORD dwFVF = Mesh->GetFVF(); DWORD dwNumBytesPerVertex = Mesh->GetNumBytesPerVertex(); DWORD dwNumFaces = Mesh->GetNumFaces(); //怎么样?该有的都有了吧,要怎么保存就看你的了 //这段代码显然不完善,你需要自己去完善它 //有人说了你光考虑了Mesh,还有多AnimationSet等等东西呢? //这里本来就只是建立静态模型,当然没有AnimationSet啦。动画的部分我后面在写吧。 pVertexBuffer->UnLock(); pIndexBuffer->UnLock(); fclose(fp); } //增加结束
pD3DXMtrlBuffer->Release(); return S_OK; } 
|