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

  • 来源: IT168.com  作者: 若水   2008-04-03/11:38
  •     跟着我一步一步来吧(我的思路和过程)。

        我有一个能画出微软例子中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;
      }


    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多