3D游戏从入门到精通-30

加载复杂网格模型
上面都是简单的网格例子,并且只能作为演示作用,没有多少实用价值,下面来加载一个更复杂的网格模型。在我们玩过的游戏里,绝大多数都有室内场境的地方,比如到武器店里买东西,就需要有一个室内场境。在我们最常见的房子,大多数都是长方形的,也就是有6个面的立方体,而在这六个面贴上纹理,就是室内环境了。由于我没有美工,只能拿现成的网格模型来加载显示,模型文件放在目录G:/MM3D/Engine/bin/models里,其中room.x是网格模型文件,DoorDiff.dds、FireplaceDiff.dds、oldwood.dds、wallpaper.dds都是纹理图片。实现的效果图如下:
 
电子书MM3D引擎源程序例子源程序49元一套
联系人:蔡军生 
联系方式:
QQ: 9073204
EMAIL: caimouse1976 at sina.com
 
在这个场境里,主要有四部份组成,地板是由贴木板纹理的模型组成。四周的墙是由花纹纹理的模型组成。还有一个门模型,以及火墙模型。在这个例子里,比上面一个复杂的地方,就是多了纹理贴图。
先看看加载网格模型的函数,看看怎么样实现加载网格和纹理。
//
//加载网格模型。
//蔡军生 2006/09/15
//
HRESULT CCAIRoom::LoadMeshFromFile(void)
{
 //网格模型路径。
 char chPath[MAX_PATH];
 if ( !GetModuleFileName( NULL, chPath, MAX_PATH ) )
 {
       return S_FALSE;
 }
 
 std::string strName(chPath);
 std::basic_string <char>::size_type stPos = strName.find_last_of("//");
 if(stPos != std::string::npos)
 {
       strName = strName.substr(0,stPos);
 }
 
 std::string strPath = strName;
 const std::string strFile("//bin//models//room.x");
 strName += strFile;
 
 //加载X文件。
  LPD3DXBUFFER pAdjacencyBuffer = NULL;
 LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
 HRESULT hr = D3DXLoadMeshFromX( strName.c_str(), D3DXMESH_MANAGED,
       m_pd3dDevice, &pAdjacencyBuffer,
       &pD3DXMtrlBuffer, NULL, &m_dwNumRoomMaterials,
       &m_pMeshRoom );
 if (FAILED(hr))
 {
       return DXTRACE_ERR( "D3DXLoadMeshFromX", hr );
 }
 
 // 优化网格显示。
 if( FAILED( hr = m_pMeshRoom->OptimizeInplace(
       D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
       (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
 {
       if (pAdjacencyBuffer)
       {
             pAdjacencyBuffer->Release();
       }
 
       if (pD3DXMtrlBuffer)
       {
             pD3DXMtrlBuffer->Release();
       }
       return DXTRACE_ERR("OptimizeInplace",hr);
 }
 
 //是否有材料。
 if (pD3DXMtrlBuffer && m_dwNumRoomMaterials > 0)
 {
       //
       D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
       m_pMeshRoomMaterials = new D3DMATERIAL9[m_dwNumRoomMaterials];
       if (!m_pMeshRoomMaterials)
       {
             //        
             pD3DXMtrlBuffer->Release();
             return E_OUTOFMEMORY;
       }
 
       //保存材料和纹理。
       for( DWORD i = 0; i < m_dwNumRoomMaterials; i++ )
       {
             //
             m_pMeshRoomMaterials[i] = d3dxMaterials[i].MatD3D;
             m_pMeshRoomMaterials[i].Ambient = m_pMeshRoomMaterials[i].Diffuse;
 
             //
             if( d3dxMaterials[i].pTextureFilename != NULL &&
                  lstrlen(d3dxMaterials[i].pTextureFilename) > 0 )
             {
                  //
                  LPDIRECT3DTEXTURE9 pMeshTextures = NULL;
                  std::string strTemp = strPath + "//bin//models//";
                  strTemp += d3dxMaterials[i].pTextureFilename;
 
                  hr = D3DXCreateTextureFromFile( m_pd3dDevice,
                        strTemp.c_str(),
                        &pMeshTextures );
 
                  if (SUCCEEDED(hr))
                  {
                        m_vMeshRoomTextures.push_back(pMeshTextures);
                  }
                  else
                  {
                        m_vMeshRoomTextures.push_back(NULL);
                  }                    
 
                  OutputDebugString("Texture/n");
             }
             else
             {
                  m_vMeshRoomTextures.push_back(NULL);
             }
       }
 
 }
 
 //
 if (pD3DXMtrlBuffer)
 {
       pD3DXMtrlBuffer->Release();
 }
 
 if (pAdjacencyBuffer)
 {
       pAdjacencyBuffer->Release();
 }
 
 
 return S_OK;
}
 
 
 
 
posted @ 2006-09-17 12:56  ajuanabc  阅读(182)  评论(0编辑  收藏  举报