建立自己的3D静态模型文件介绍

资讯 驱动中国 若水 1,659 次阅读 0 条评论
分享 Q

    跟着我一步一步来吧(我的思路和过程)。

    我有一个能画出微软例子中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;#p#分页标题#e#
          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;
  }

版权声明:本文由驱动中国整理发布,转载需注明出处与原文链接。如有疑问请联系 editor@qudong.com
本文价值 成为第一个评分的人
登录后为本文打分
网友评论0 条评论
正在回复 的评论取消
评论加载中…
🔐

登录后参与互动

评论、点赞均可赚积分
连续签到、邀请好友也有奖励 🎁

电脑端: 微信扫码登录 微信内: 一键登录

微信扫一扫

打开微信「扫一扫」,分享本文到朋友圈或好友