Direct3D应用程序在使用mesh之前必须加载它。Meshes示例工程通过调用InitGeometry加载所必需的Direct3D对象,之后便加载一个老虎的mesh。
一个mesh需要一个缓冲来存储所有的材质和纹理。函数最开始声明了一个材质缓冲,如下所示:
LPD3DXBUFFER pD3DXMtrlBuffer;
下面的代码加载了mesh
// Load the mesh from the specified file
if( FAILED( D3DXLoadMeshFromX( "Tiger.x", D3DXMESH_SYSTEMMEM,
g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL,
&g_dwNumMaterials, &g_pMesh ) ) )
{
// If model is not in current folder, try parent folder
if( FAILED( D3DXLoadMeshFromX( "..\\Tiger.x",
D3DXMESH_SYSTEMMEM, g_pd3dDevice, NULL,
&pD3DXMtrlBuffer, NULL, &g_dwNumMaterials,
&g_pMesh ) ) )
{
MessageBox(NULL, "Could not find tiger.x",
"Meshes.exe", MB_OK);
return E_FAIL;
}
}
第一个参数是指向字符串的指针,它指明了需要加载的文件。这个示例从Tiger.x文件中加载老虎的mesh。
第二个参数说明了怎样创建mesh。示例使用D3DXMESH_SYSTEMMEM标志,用它来代表D3DXMESH_VB_SYSTEMMEM和D3DXMESH_IB_SYSTEMMEM这两个标志位。这两个标识将mesh的索引缓冲和顶点缓冲都放到系统内存中。
第三个参数是指向设备的指针,用来渲染mesh。
第四个参数是一个指向ID3DBuffer对象的指针。这个对象将包含每一个表面的相邻信息。在这里,这个信息不是必须的,所以设置为NULL。
第五个参数同样是指向一个ID3DXBuffer对象的指针,这个方法完成后,D3DXMATERIAL将填充到这个对象当中。
第六个参数是一个指向dw数值的指针,这个数值说明了函数返回后,有多少D3DXMATERIAL结构被放入了ppMaterials数组中。
第七个参数是指向mesh对象的指针,代表了加载的mesh。
在加载mesh对象和材质信息之后,你应该从材质缓冲中取出材质属性和纹理名称。
Meshes示例工程通过得到材质缓冲的指针来完成这项工作。使用ID3DXBuffer::GetBufferPointer方法,如下所示:
D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
下面的代码将基于材质的数量创建新的mesh和纹理对象。
g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials];
g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];
对于mesh中的每一个材质,会发生一下几个步骤:
第一步是要拷贝材质,如下所示:
g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
第二步是设置环境光,如下所示:
g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;
最有一步是创建材质,如下所示:
// Create the texture.
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,
d3dxMaterials[i].pTextureFilename, &g_pMeshTextures[i] ) ) )
g_pMeshTextures[i] = NULL;
}
加载每个材质之后,材质缓冲的工作就完成了。调用IUnknown::Release来释放它。
pD3DXMtrlBuffer->Release();