I've been following Chad Vernon's (very good) Direct X 9 tutorial [ http://www.chadvernon.com/blog/resources/directx9/loading-a-static-mesh-x-format/ ].
I am stuck at one point because I'm trying to load a .x model, I have it set up so it will output errors if something goes wrong but nothing appears, I've setup breakpoints and looked at return values of functions, and they all indicate success. I've put a breakpoint in the rendering code and saw that it wasn't trying to render a NULL pointer aswell. But the model I'm trying to load still doesn't have any textures, the model just shows up fully black and I can't figure out why.
This is my loading code:
bool CMesh::Load(LPDIRECT3DDEVICE9 pDevice, char *filename)
{
Release(); // release memory if already loaded
LPD3DXBUFFER pMaterialBuffer = NULL;
wchar_t wstr[MAX_PATH];
wstr[0]=0;
mbstowcs(wstr, filesystem->Transform(filename), MAX_PATH);
HRESULT hr = D3DXLoadMeshFromX(wstr, D3DXMESH_MANAGED, pDevice,
NULL, &pMaterialBuffer, NULL, &m_nMaterials, &m_pMesh);
switch(hr)
{
case D3D_OK:
break;
case D3DERR_INVALIDCALL:
Release();
logger->Log(LL_WARN, "[CMesh::Load(%p, %s)] Couldn't load mesh '%s': Invalid call.\n", pDevice, filename, filename);
return false;
case E_OUTOFMEMORY:
Release();
logger->Log(LL_WARN, "[CMesh::Load(%p, %s)] Couldn't load mesh '%s': Out of memory.\n", pDevice, filename, filename);
return false;
case D3DXFERR_FILENOTFOUND:
Release();
logger->Log(LL_WARN, "[CMesh::Load(%p, %s)] Couldn't load mesh '%s': File not found.\n", pDevice, filename, wstr);
return false;
default:
Release();
logger->Log(LL_WARN, "[CMesh::Load(%p, %s)] Couldn't load mesh '%s': Unknown error.\n", pDevice, filename, filename);
return false;
}
D3DXMATERIAL *pMaterials = (D3DXMATERIAL*)pMaterialBuffer->GetBufferPointer();
m_pMeshMaterials = new D3DMATERIAL9[m_nMaterials];
m_pMeshTextures = new LPDIRECT3DTEXTURE9[m_nMaterials];
if(!m_pMeshMaterials)
{
Release();
return false;
}
for(int i = 0; i < m_nMaterials; i++)
{
m_pMeshMaterials[i] = pMaterials[i].MatD3D;
m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse;
m_pMeshTextures[i] = NULL;
if(pMaterials[i].pTextureFilename)
{
char *f = Q_format("models/%s", pMaterials[i].pTextureFilename);
wchar_t str[MAX_PATH];
mbstowcs(str, filesystem->Transform(f), MAX_PATH);
HRESULT hr = D3DXCreateTextureFromFile(pDevice, str, &m_pMeshTextures[i]);
switch(hr)
{
case D3D_OK:
break;
case D3DERR_NOTAVAILABLE:
logger->Log(LL_WARN, "[CMesh::Load(%p, %s)] Could not load material '%s': Not available.\n", pDevice,
filename, pMaterials[i].pTextureFilename);
break;
case D3DERR_OUTOFVIDEOMEMORY:
case E_OUTOFMEMORY:
logger->Log(LL_WARN, "[CMeshLoad(%p, %s)] Could not load material '%s': Out of memory.\n", pDevice,
filename, pMaterials[i].pTextureFilename);
break;
case D3DERR_INVALIDCALL:
logger->Log(LL_WARN, "[CMesh::Load(%p, %s)] Could not load material '%s': Invalid call.\n", pDevice,
filename, pMaterials[i].pTextureFilename);
break;
case D3DXERR_INVALIDDATA:
logger->Log(LL_WARN, "[CMesh::Load(%p, %s)] Could not load material '%s': Invalid data.\n", pDevice,
filename, pMaterials[i].pTextureFilename);
break;
default:
logger->Log(LL_WARN, "[CMesh::Load(%p, %s)] Could not load material '%s': Unknown error.\n", pDevice,
filename, pMaterials[i].pTextureFilename);
break;
}
}
}
pMaterialBuffer->Release();
return true;
}
logger is thing i made to just pring out to the console, and the Release function of this class just calls ->Release on the textures and materials and mesh.
This is my rendering code:
void CMeshInstance::Render(LPDIRECT3DDEVICE9 pDevice)
{
if(pDevice && m_pMesh)
{
pDevice->SetTransform(D3DTS_WORLD, GetTransform());
int nmaterials = m_pMesh->GetNumMaterials();
for(int i = 0; i < nmaterials; i++)
{
D3DMATERIAL9 *mat = m_pMesh->GetMeshMaterial(i);
LPDIRECT3DTEXTURE9 tex = m_pMesh->GetMeshTexture(i);
if(mat)
pDevice->SetMaterial(mat);
if(tex)
pDevice->SetTexture(0, tex);
m_pMesh->GetMesh()->DrawSubset(i);
}
}
}
Like I've said I've setup break points all through this function to check that all the pDevice-> calls are actually being called and they are, but it still doesn't work.
filesystem->Transform is just a function I made to turn a filename like "models/test.x" to an absolute (full) filename.
If you require any more details just ask. Any help would be appreciated.