// ============================================================================
// Filename: MESH.cpp
// Description: Mesh Tutorial, Mesh class implementation. From the 32Bits
// DirectX Techniques Series 1 Tutorial 4.
// Created by wizard version 0.1 Beta.
//
// Found a bug in this code framework? Need some help? Come to www.32bits.co.uk
// for support, feedback and the best DirectX dev community on the net!
// ============================================================================
#include <d3d9.h>
#include <d3dx9.h>
#include <dxerr9.h>
#include "CD3DMesh.h"
// =====================================================================================
// Constructor and destructor
// =====================================================================================
CD3DMesh::CD3DMesh()
{
m_dwNumMaterials = 0;
m_pMaterialsBuffer = NULL;
m_pMaterials = NULL;
m_pTextures = NULL;
m_pMesh = NULL;
// Remove these 2 if you are removing the inheritance from CD3DObject
SetClassDesc("Basic Mesh");
SetRTTI(MESH);
}
CD3DMesh::~CD3DMesh()
{
Shutdown();
}
HRESULT CD3DMesh::Shutdown()
{
// Free the materials array
if(m_pMaterials)
delete [] m_pMaterials;
// If there are textures...
if(m_pTextures)
{
// ...index through the texture array & release the texture object
for(int iCount = 0; iCount < (int)m_dwNumMaterials; iCount++)
{
m_pTextures[iCount]->Release();
m_pTextures[iCount] = NULL;
}
// Don't forget to delete the array as well
delete [] m_pTextures;
}
// Release the mesh object
if(m_pMesh)
m_pMesh->Release();
m_dwNumMaterials = 0;
m_pMaterialsBuffer = NULL;
m_pMaterials = NULL;
m_pTextures = NULL;
m_pMesh = NULL;
return S_OK;
}
// =====================================================================================
// Initialisation
// =====================================================================================
HRESULT CD3DMesh::Initialise(char* szMeshFile, LPDIRECT3DDEVICE9& pDevice)
{
HRESULT rslt = S_OK;
// First, load the .X file into a mesh object, and fill out the materials buffer
rslt = D3DXLoadMeshFromX(szMeshFile, D3DXMESH_MANAGED, pDevice, NULL,
&m_pMaterialsBuffer, NULL, &m_dwNumMaterials, &m_pMesh);
if(FAILED(rslt)) { return Error(rslt, __LINE__, __FILE__, "Couldn't load mesh from .X file"); }
// Next, get a pointer to the first element of data in the materials buffer, ready
// to read out.
D3DXMATERIAL* pMaterials = (D3DXMATERIAL*)m_pMaterialsBuffer->GetBufferPointer();
// Create 2 arrays, 1 for textures and 1 for materials. D3DXLoadMeshFromX puts the
// number of materials/textures (always the same) into m_dwNumMaterials above.
m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials];
m_pTextures = new LPDIRECT3DTEXTURE9[m_dwNumMaterials];
// Next, iterate through the pMaterials buffer.
{
for(int iCount = 0; iCount < (int)m_dwNumMaterials; iCount++)
{
// For each material buffer element, copy the D3DMATERIAL into this class' array.
m_pMaterials[iCount] = pMaterials[iCount].MatD3D;
// As we learnt in the Lighting tutorial (D3D Basics Series 3 Tut 4), each material
// has diffuse & ambient light properties. Set the Ambient light ARGB to the diffuse
// light ARGB.
m_pMaterials[iCount].Ambient = m_pMaterials[iCount].Diffuse;
// Finally, create a texture from the file specified in the mateirals buffer and put
// it in the m_pTextures array.
rslt=D3DXCreateTextureFromFile(pDevice, pMaterials[iCount].pTextureFilename, &m_pTextures[iCount]);
if(FAILED(rslt)) { return Error(rslt, __LINE__, __FILE__, "D3DXCreateTextureFromFile() failed."); }
}
}
// m_pMaterialsBuffer is a COM object created by D3DXLoadMeshFromX. We only need it when
// reading the data from the X file - now that we've populated our mesh, materials and
// textures we can get rid of it.
m_pMaterialsBuffer->Release();
m_pMaterialsBuffer = NULL;
return S_OK;
}
// =====================================================================================
// Rendering
// =====================================================================================
HRESULT CD3DMesh::Render(LPDIRECT3DDEVICE9& pDevice)
{
HRESULT rslt = S_OK;
// Rendering a mesh is very easy. Simply iterate through each material...
{
for(int iCount = 0; iCount < (int)m_dwNumMaterials; iCount++)
{
//... set the material and texture in the normal way
rslt = pDevice->SetMaterial(&m_pMaterials[iCount]);
if(FAILED(rslt)) { return Error(rslt, __LINE__, __FILE__, "Couldn't set the material."); }
rslt = pDevice->SetTexture(0, m_pTextures[iCount]);
if(FAILED(rslt)) { return Error(rslt, __LINE__, __FILE__, "Couldn't set the texture."); }
//... then call ID3DXMesh::DrawSubset to draw the vertices in the mesh
// that have this material and texture applied to them.
rslt = m_pMesh->DrawSubset(iCount);
if(FAILED(rslt)) { return Error(rslt, __LINE__, __FILE__, "DrawSubset() failed."); }
}
}
return S_OK;
}