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;
}
