A Direct3D application must first load a mesh before using it. The Meshes sample project loads the tiger mesh by calling InitGeometry>, an application-defined function, after loading the required Direct3D objects.
A mesh needs a material buffer that will store all the materials and textures that will be used. The function starts by declaring a material buffer as shown in the following code fragment.
LPD3DXBUFFER pD3DXMtrlBuffer;
The following code fragment loads the 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; } }
The first parameter is a pointer to a string that tells the name of the DirectX file to load. This sample loads the tiger mesh from Tiger.x.
The second parameter specifies how to create the mesh. The sample uses the D3DXMESH_SYSTEMMEM flag, which is equivalent to specifying both D3DXMESH_VB_SYSTEMMEM and D3DXMESH_IB_SYSTEMMEM. Both of these flags put the index buffer and vertex buffer for the mesh in system memory.
The third parameter is a pointer to a device that will be used to render the mesh.
The fourth parameter is a pointer to an ID3DXBuffer object. This object will be filled with information about neighbors for each face. This information is not required for this sample, so this parameter is set to NULL.
The fifth parameter also takes a pointer to an ID3DXBuffer object. After this method is finished, this object will be filled with D3DXMATERIAL structures for the mesh.
The sixth parameter is a pointer to the number of D3DXMATERIAL structures placed into the ppMaterials array after the method returns.
The seventh parameter is the address of a pointer to a mesh object, representing the loaded mesh.
After loading the mesh object and material information, you need to extract the material properties and texture names from the material buffer.
The Meshes sample project does this by first getting the pointer to the material buffer. The following code fragment uses the ID3DXBuffer::GetBufferPointer method to get this pointer.
D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
The following code fragment creates new mesh and texture objects based on the total number of materials for the mesh.
g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials]; g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];
For each material in the mesh the following steps occur.
The first step is to copy the material, as shown in the following code fragment.
g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
The second step is to set the ambient color for the material, as shown in the following code fragment.
g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;
The final step is to create the texture for the material, as shown in the following code fragment.
// Create the texture. if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, d3dxMaterials[i].pTextureFilename, &g_pMeshTextures[i] ) ) ) g_pMeshTextures[i] = NULL; }
After loading each material, you are finished with the material buffer and need to release it by calling IUnknown.
pD3DXMtrlBuffer->Release();
The mesh, along with the corresponding materials and textures are loaded. The mesh is ready to be rendered to the display, as described in Step 2 - Rendering a Mesh Object.