D3DXLoadMeshHierarchyFromX Problems

Started by
2 comments, last by ParadoxKing 12 years, 11 months ago
I am trying to load a rigged mesh from an x file. However I cannot get the darn thing to load. All my code seems correct, but obviously something is wrong somewhere. Here is all the relevant code:

mesh.cpp
[source lang="cpp"]#include "..\inc\libdecl.h"

using namespace std;

CMesh::CMesh(LPDIRECT3DDEVICE9 dev)
: lpDev(dev), lpRoot(NULL), lpAnimControl(NULL),
pBoneMatrices(NULL), pCurrContainer(NULL)
{ }


CMesh::~CMesh()
{
clear();
}


bool CMesh::init()
{
clear();
return 1;
}


bool CMesh::init(const string& fname)
{
clear();
dbgPrintln("CMesh::init!");
return loadFile(fname);
}


void CMesh::clear()
{
vPos = D3DXVECTOR3(0,0,0);
vScl = D3DXVECTOR3(1,1,1);
vRot = D3DXVECTOR3(0,0,0);
chError = 0;

if (lpRoot != NULL)
{
CT6Allocate alh;
D3DXFrameDestroy (lpRoot, &alh);
lpRoot = NULL;
}

Release<LPD3DXANIMATIONCONTROLLER>(lpAnimControl);

DeleteArray<D3DXMATRIX*>(pBoneMatrices);

iMaxBones = 0;
pCurrContainer = NULL;
vCenter = D3DXVECTOR3(0,0,0);
fRadius = 0.0f;
iCurrAnim = 0;
iNumAnims = 0;
iCurrTrack = 0;
fSpeed = 1.0f;
fCurrTime = 0.0f;
fTransition = 0.25f;
}


bool CMesh::loadFile(const string& filename)
{
if (!lpDev)
return 0;

CT6Allocate alh;

dbgPrintln("CMesh::loadFile alh");

if (FAILED(D3DXLoadMeshHierarchyFromX(filename.c_str(), D3DXMESH_MANAGED,
lpDev, &alh, NULL, &lpRoot, &lpAnimControl)))
return 0;

dbgPrintln("lpAnimControl");
if (lpAnimControl)
iNumAnims = lpAnimControl->GetMaxNumAnimationSets();

dbgPrintln("iNumAnims");

if (lpRoot)
{
setupMatrices((Bone*)lpRoot, NULL);

pBoneMatrices = new D3DXMATRIX[iMaxBones];
ZeroMemory(pBoneMatrices, sizeof(D3DXMATRIX)*iMaxBones);

D3DXFrameCalculateBoundingSphere(lpRoot, &vCenter, &fRadius);
}

setAnim(0);

return 1;
}[/source]

gfx.cpp
[source lang="cpp"]//////////////////////////////////////////////////////////////////////
// //
// Initialize Model............................................... //
// (Placed Here for access to dev)...................{CGIM} //
//////////////////////////////////////////////////////////////////////

bool CGraphics::initMesh(CMesh*& pMesh, const string& fname)
{
pMesh = new CMesh(dev);

return pMesh->init(fname);
}[/source]


games.cpp
[source lang="cpp"]//////////////////////////////////////////////////////////////////////
// //
// CGame Class Constructor........................................ //
// .................................................{CGaCC} //
//////////////////////////////////////////////////////////////////////

CGame::CGame()
: gfx(NULL), input(NULL), timer(NULL), pMesh(NULL)
{
hwnd = 0;
width = 0;
height = 0;
windowed = 0;
paused = 0;
random = 1;
textCount = 0.0f;
colorCount = 0.0f;
lightCount = 0.0f;
pt.x = 0;
pt.y = 0;
}


//////////////////////////////////////////////////////////////////////
// //
// Initialize CGame Class......................................... //
// .................................................{CGaIn} //
//////////////////////////////////////////////////////////////////////

bool CGame::init(HWND hWnd, int w, int h, bool mode)
{
hwnd = hWnd;
width = w;
height = h;
windowed = mode;

if (!initGFX()) return 0;
dbgPrintln(endl << "Initialized Graphics Class!" << endl);

if (!initInput()) return 0;
dbgPrintln(endl << "Initialized Input Class!" << endl);

if (!initMesh("solider.X")) return 0;
dbgPrintln(endl << "Initialized Soldier Mesh!" << endl);


bg = gfx->loadSurface("background.png", D3DCOLOR_XRGB(255,255,255));

timer = new CTimer();

gfx->clear(D3DCOLOR_XRGB(255,255,255));


gfx->setRenderState(D3DRS_ALPHABLENDENABLE, true);
gfx->setRenderState(D3DRS_NORMALIZENORMALS, true);

gfx->setRenderState(D3DRS_SPECULARENABLE, true);

gfx->setRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
gfx->setRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
gfx->setRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);

gfx->setTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
gfx->setTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
gfx->setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
gfx->setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);

gfx->setTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
gfx->setTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);


plPos = D3DXVECTOR3(-0.0f, 0.0f, -10.0f);
pColor = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
initPointLight(pLight, plPos, pColor, 0.4f, 0.6f,
1.0f, 100.0f, 1.0f, 0.0f, 0.0f);
gfx->setLight(0, &pLight);
gfx->lightEnable(0, true);


return 1;
}


bool CGame::initMesh(const string& fname)
{ return gfx->initMesh(pMesh, fname); }[/source]

XStructs.h
[source lang="cpp"]
#include "libdecl.h"

#ifndef __XSTRUCTS_H__
#define __XSTRUCTS_H__


typedef struct Bone : public D3DXFRAME
{
D3DXMATRIX combinedMatrices;
}T6Bone, *LPBONE;

struct T6MeshContainer : public D3DXMESHCONTAINER
{
LPDIRECT3DTEXTURE9* textures;
D3DMATERIAL9* mat;
LPD3DXMESH originalMesh;
D3DXMATRIX **boneMatrices;
};


class CT6Allocate : public ID3DXAllocateHierarchy
{
public:
STDMETHOD(CreateFrame)(THIS_ LPCSTR, LPD3DXFRAME*);

STDMETHOD(CreateMeshContainer)(THIS_ LPCSTR, const D3DXMESHDATA*,
const D3DXMATERIAL*, const D3DXEFFECTINSTANCE*,
DWORD, const DWORD*, LPD3DXSKININFO, LPD3DXMESHCONTAINER*);

STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME inFrame);
STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER container);
};

#endif //not __XSTRUCTS_H__[/source]

XStrructs.cpp
[source lang="cpp"]#include "..\inc\libdecl.h"

HRESULT CT6Allocate::CreateFrame(LPCSTR name, LPD3DXFRAME* outFrame)
{
dbgPrintln("CreateFrame::START");
Bone* bone = new Bone;
ZeroMemory(bone, sizeof(Bone));

*outFrame = NULL;
bone->Name = NULL;

if (name)
{
int len = strlen(name) + 1;
bone->Name = new char[len];
memcpy(bone->Name, name, len * sizeof(char));
}

bone->pMeshContainer = NULL;
bone->pFrameSibling = NULL;
bone->pFrameFirstChild = NULL;

D3DXMatrixIdentity(&bone->TransformationMatrix);
D3DXMatrixIdentity(&bone->combinedMatrices);

*outFrame = bone;

dbgPrintln("CrerateFrame::END");
return S_OK;
}


HRESULT CT6Allocate::CreateMeshContainer(THIS_ LPCSTR name,
const D3DXMESHDATA* mesh, const D3DXMATERIAL* mats,
const D3DXEFFECTINSTANCE* fx, DWORD numMats,
const DWORD* indices, LPD3DXSKININFO skin,
LPD3DXMESHCONTAINER* outContainer)
{
dbgPrintln("CreateMeshContainer::START");
T6MeshContainer *meshCon = new T6MeshContainer;
ZeroMemory(meshCon, sizeof(T6MeshContainer));

*outContainer = NULL;
meshCon->Name = NULL;

if(name)
{
int len = strlen(name) + 1;

meshCon->Name = new char[len];
memcpy(meshCon->Name, name, len * sizeof(char));
}

if(mesh->Type != D3DXMESHTYPE_MESH)
{
DestroyMeshContainer(meshCon);
return E_FAIL;
}

meshCon->MeshData.Type = D3DXMESHTYPE_MESH;

unsigned long numFaces = mesh->pMesh->GetNumFaces();
meshCon->pAdjacency = new unsigned long[numFaces * 3];
memcpy(meshCon->pAdjacency, indices, sizeof(unsigned long) * numFaces * 3);

LPDIRECT3DDEVICE9 d3dDev = NULL;
mesh->pMesh->GetDevice(&d3dDev);

D3DVERTEXELEMENT9 elements[MAX_FVF_DECL_SIZE];
if(FAILED(mesh->pMesh->GetDeclaration(elements)))
return E_FAIL;


mesh->pMesh->CloneMesh(D3DXMESH_MANAGED, elements, d3dDev, &meshCon->MeshData.pMesh);


meshCon->NumMaterials = max(numMats, 1);
meshCon->mat = new D3DMATERIAL9[meshCon->NumMaterials];
meshCon->textures = new LPDIRECT3DTEXTURE9[meshCon->NumMaterials];
ZeroMemory(meshCon->mat, sizeof(D3DMATERIAL9) * meshCon->NumMaterials);
ZeroMemory(meshCon->textures, sizeof(LPDIRECT3DTEXTURE9) * meshCon->NumMaterials);

if(numMats > 0)
{
for (unsigned long i = 0; i < numMats; ++i)
{
meshCon->textures = NULL;
meshCon->mat = mats.MatD3D;

if (mats.pTextureFilename)
{
if (FAILED(D3DXCreateTextureFromFile(d3dDev, mats.pTextureFilename,
&meshCon->textures)))
meshCon->textures = NULL;
}
}
}

else
{
ZeroMemory(&meshCon->mat[0], sizeof(D3DMATERIAL9));

meshCon->mat[0].Diffuse.r = 0.5f;
meshCon->mat[0].Diffuse.g = 0.5f;
meshCon->mat[0].Diffuse.b = 0.5f;
meshCon->mat[0].Specular = meshCon->mat[0].Diffuse;
meshCon->textures[0] = NULL;
}

meshCon->pSkinInfo = NULL;
meshCon->boneMatrices = NULL;

if (skin)
{
meshCon->pSkinInfo = skin;
skin->AddRef();

UINT numBones = skin->GetNumBones();
meshCon->boneMatrices = new D3DXMATRIX* [numBones];
}

Release<LPDIRECT3DDEVICE9>(d3dDev);

*outContainer = meshCon;

dbgPrintln("CreateMeshContainer::END");

return S_OK;
}


HRESULT CT6Allocate::DestroyFrame(LPD3DXFRAME inFrame)
{
dbgPrintln("DestroyFrame::START");
Bone* bone = (Bone*) inFrame;

DeleteArray<LPSTR>(bone->Name);

Delete<Bone*>(bone);

dbgPrintln("DestroyFrame::END");

return S_OK;
}


HRESULT CT6Allocate::DestroyMeshContainer(LPD3DXMESHCONTAINER container)
{
dbgPrintln("DestroyMeshContainer::Start");
T6MeshContainer* meshCon = (T6MeshContainer*) container;

DeleteArray<LPSTR>(meshCon->Name);

DeleteArray<D3DMATERIAL9*>(meshCon->mat);

if (meshCon->textures)
{
for (UINT i = 0; i < meshCon->NumMaterials; i++)
{
if (meshCon->textures)
meshCon->textures->Release();

meshCon->textures = NULL;
}
}

DeleteArray<LPDIRECT3DTEXTURE9*>(meshCon->textures);
DeleteArray<DWORD*>(meshCon->pAdjacency);
DeleteArray<D3DXMATRIX**>(meshCon->boneMatrices);

Release<LPD3DXMESH>(meshCon->originalMesh);
Release<LPD3DXMESH>(meshCon->MeshData.pMesh);

Delete<T6MeshContainer*>(meshCon);

dbgPrintln("DestroyMeshContainer::END");

return S_OK;
}[/source]

debug.out
Created New Game Object!
CGraphics::init
Initialized Direct3D
Initialized GFX Device
Initialized Back Buffer
Initialized Camera

Initialized Graphics Class!

Initialized Direct Input
Initialized the Keyboard

Initialized Input Class!

CMesh::init!
CMesh::loadFile alh
Exiting Game...
Here
Released Dev!


I attached the entire vs2010 project to this post, if anyone can help it would be greatly appreciated.
Advertisement
That is alot of code to look over. You probably wont get any help unless you can narrow down the area where the problem is occurring. If you do that and repost, you will get help then.
Wisdom is knowing when to shut up, so try it.
--Game Development http://nolimitsdesigns.com: Reliable UDP library, Threading library, Math Library, UI Library. Take a look, its all free.
smasherprog has some good advice. In addition, there's a lot more you can do to help yourself find problems.

First: use the Debug Runtime and, in the Dx control panel, set the debug level to max.

Second: Using the FAILED/SUCCEEDED macros is a good start, but you're only detecting where the error occurs, not what error occurs. Try using something like:

HRESULT hr;

if( FAILED( hr = D3DXLoadMeshHierarchyFromX(...) ) )
{
MessageBox(NULL,DXGetErrorDescription9( hr ), "Failed to load X File", MB_OK );
return 0;
}
// etc.

Include "dxerr9.h" in any cpp file where you call DXGetErrorDescription9, and link to dxerr9.lib.

Third: Didn't look through much of your code but, because you're failing at D3DXLoadMesh..., start by checking your filename. Chances are it can't find the file if you don't have a fully qualified path in filename. Change filename to something like "c:\\myprojects\\myXfile.x" ( rather than just "myFile.x" ) and see how that works.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

It was that file was not being found, as soon as I stuck in an absolute path the mesh was loaded. is there anyway to use a relative path, like add a path to my VC++ directories?

This topic is closed to new replies.

Advertisement