我有一個能畫出微軟例子中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;
}