Книга: DirectX 8 Programming Tutorial

Loading a .x file into your program

Loading a .x file into your program

For this tutorial I have created a wrapper class called CMesh for loading and rendering meshes loaded from a .x file. Below is the main code for the CMesh class. The constuctor shows how to load a mesh from a .x file and store it in memory. The destructor shows how to free the memory that was used to store the mesh. The Render method shows how to render a mesh.

The CMesh constructor takes two parameters, the first is a pointer to the device and the second is string containing the path of the .x file to load. We use the D3DXLoadMeshFromX function to load the mesh into memory. Once this is done we create two arrays, one to hold the materials and one to hold the textures of our model. We then loop around and populate the two arrays from the loaded mesh. The last thing to do is make sure that the normals are set for each vertex of the mesh. We clone the mesh and use the D3DXComputeNormals function to set the normals.

In the destructor we release each texture and the mesh itself. We also have to delete the two array pointers that we created in the constructor.

The Render function is pretty straight forward, we simply loop through each subset of the mesh and render it with the appropriate texture and material.

CMesh::CMesh(LPDIRECT3DDEVICE8 pD3DDevice, LPSTR pFilename) {
 LPD3DXBUFFER pMaterialsBuffer = NULL;
 LPD3DXMESH pMesh = NULL;
 m_pD3DDevice = pD3DDevice;
 if (FAILED(D3DXLoadMeshFromX(pFilename, D3DXMESH_SYSTEMMEM, m_pD3DDevice, NULL, &pMaterialsBuffer, &m_dwNumMaterials, &pMesh))) {
  m_pMesh = NULL;
  m_pMeshMaterials = NULL;
  m_pMeshTextures = NULL;
  LogError("<li>Mesh '%s' failed to load", pFilename);
  return;
 }
 D3DXMATERIAL* matMaterials = (D3DXMATERIAL*)pMaterialsBuffer->GetBufferPointer();
 //Create two arrays. One to hold the materials and only to hold the textures
 m_pMeshMaterials = new D3DMATERIAL8[m_dwNumMaterials];
 m_pMeshTextures = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];
 for (DWORD i = 0; i < m_dwNumMaterials; i++) {
  //Copy the material
  m_pMeshMaterials[i] = matMaterials[i].MatD3D;
  //Set the ambient color for the material (D3DX does not do this)
  m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse;
  //Create the texture
  if (FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, matMaterials[i].pTextureFilename, &m_pMeshTextures[i]))) {
   m_pMeshTextures[i] = NULL;
  }
 }
 //We've finished with the material buffer, so release it
 SafeRelease(pMaterialsBuffer);
//Make sure that the normals are setup for our mesh
 pMesh->CloneMeshFVF(D3DXMESH_MANAGED, MESH_D3DFVF_CUSTOMVERTEX, m_pD3DDevice, &m_pMesh);
 SafeRelease(pMesh);
 D3DXComputeNormals(m_pMesh);
 LogInfo("<li>Mesh '%s' loaded OK", pFilename);
}
CMesh::~CMesh() {
 SafeDelete(m_pMeshMaterials);
 if (m_pMeshTextures != NULL) {
  for (DWORD i = 0; i < m_dwNumMaterials; i++) {
   if (m_pMeshTextures[i]) {
    SafeRelease(m_pMeshTextures[i]);
   }
  }
 }
 SafeDelete(m_pMeshTextures);
 SafeRelease(m_pMesh);
 LogInfo("<li>Mesh destroyed OK");
}
DWORD CMesh::Render() {
 if (m_pMesh != NULL) {
  for (DWORD i = 0; i < m_dwNumMaterials; i++) {
   m_pD3DDevice->SetMaterial(&m_pMeshMaterials[i]);
   m_pD3DDevice->SetTexture(0, m_pMeshTextures[i]);
   m_pMesh->DrawSubset(i);
  }
  return m_pMesh->GetNumFaces();
 } else {
  return 0;
 }
}

Оглавление книги


Генерация: 0.056. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз