Drawing Meshes
Now that you have your meshes loaded and you've updated those skinned meshes
that needed updating, it is time to throw some pixels at the display and show
off those meshes! In total, I have created four mesh−rendering functions to help
you in your projects.
HRESULT draw_mesh(D3DXMESHCONTAINER_EX* mesh_container)
{
// error checking
if(mesh_container == NULL)
return E_FAIL;
if(mesh_container->MeshData.pMesh == NULL)
return E_FAIL;
if(mesh_container->NumMaterials == 0 || mesh_container->pMaterials == NULL)
return E_FAIL;
// get the device interface
IDirect3DDevice9* device;
mesh_container->MeshData.pMesh->GetDevice(&device);
// release vertex shader if being used
device->SetVertexShader(NULL);
device->SetVertexDeclaration(NULL);
DWORD last_alpha_blend, old_alpha_blend, old_src_blend, old_dest_blend;
// save render states
device->GetRenderState(D3DRS_ALPHABLENDENABLE, &old_alpha_blend);
device->GetRenderState(D3DRS_SRCBLEND, &old_src_blend);
device->GetRenderState(D3DRS_DESTBLEND, &old_dest_blend);
last_alpha_blend = old_alpha_blend;
// setup pointer for mesh to draw, either regular or skinned.
ID3DXMesh* mesh_to_draw = (mesh_container->skin_mesh == NULL) ?
mesh_container->MeshData.pMesh : mesh_container->skin_mesh;
// look through all subsets
for(DWORD i = 0; i < mesh_container->NumMaterials; i++)
{
// set material and texture
device->SetMaterial(&mesh_container->pMaterials[i].MatD3D);
device->SetTexture(0, mesh_container->textures[i]);
// enable or disable alpha blending per material
if(mesh_container->pMaterials[i].MatD3D.Diffuse.a != 1.0f)
{
if(last_alpha_blend != TRUE)
{
last_alpha_blend = TRUE;
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); // src color
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTCOLOR);
}
}
else
{
if(last_alpha_blend != FALSE)
{
last_alpha_blend = FALSE;
device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
}
mesh_to_draw->DrawSubset(i);
}
// restore alpha blending states
if(last_alpha_blend != old_alpha_blend)
{
device->SetRenderState(D3DRS_ALPHABLENDENABLE, old_alpha_blend);
device->SetRenderState(D3DRS_SRCBLEND, old_src_blend);
device->SetRenderState(D3DRS_DESTBLEND, old_dest_blend);
}
// make sure to release the device object!
device->Release();
return S_OK;
}
If a material being used specifies an alpha value other than 1, then alpha
blending is enabled. This way, you can specify portions of a mesh to use alpha
blending by merely changing the material information. Also, if a
D3DXMESHCONTAINER_EX object contains a skinned mesh, that mesh is rendered
instead of the regular mesh.