Jump to content
  • Advertisement
Sign in to follow this  
DarioMicera

[DirectX] Problem Loading .X File with Hierarchy

This topic is 2588 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

The problem i'm finding is that all the classes are properly configured and by debugging my LoadXFile function it fills the mesh struct (since it writes the bone names of the .x file loaded).

But for some reason it won't load the model in the window (the model doesn't appear in the window itself)

Here's the code:



#include <d3d9.h>
#include <d3dx9.h>
#include "CModel.h"
LPDIRECT3D9 obj=NULL;
LPDIRECT3DDEVICE9 dev=NULL;
CModel * model = NULL;

D3DXMATRIXA16 matWorld,matYWorld,matXWorld,matTranslate,matUp,matView,matProj,matZWorld;
D3DXVECTOR3 vLookatPt(0.0f,0.0f,0.0f);
D3DXVECTOR3 vEyePt(0.0f,0.0f,0.0f);
D3DXVECTOR3 vUpVec(0.0f,1.0f,0.0f);

static float fAngle = 0.0f;
static float fForward = 0.0f;
static float fUp = 0.0f;
static float fAngle2 = 0.0f;
static float fAngle3 = 0.0f;
static bool bWireframe = false;

double starttime;
LARGE_INTEGER nowtime;
LONGLONG ticks;

LARGE_INTEGER time;


LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
bool initialize(HWND hwnd);
void render();
void clear();

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX window;
ZeroMemory(&window,sizeof(WNDCLASSEX));
window.cbSize = sizeof(WNDCLASSEX);
window.style = CS_HREDRAW | CS_VREDRAW;
window.lpfnWndProc = WndProc;
window.hInstance = hInstance;
window.lpszClassName = "WindowClass";

RegisterClassEx(&window);

HWND hwnd = CreateWindow("WindowClass", "Strategy Game", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);
if (!hwnd)
return 0;
initialize(hwnd);


delete []model;
model = new CModel(dev);
model->LoadXFile("tiny.x");
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);


D3DXMatrixIdentity(&matWorld);
D3DXMatrixIdentity(&matYWorld);
D3DXMatrixIdentity(&matXWorld);
D3DXMatrixIdentity(&matZWorld);
D3DXMatrixIdentity(&matTranslate);
D3DXMatrixIdentity(&matUp);

D3DXMatrixRotationY(&matYWorld,D3DXToRadian(fAngle));
D3DXMatrixRotationX(&matXWorld,D3DXToRadian(fAngle2));
D3DXMatrixRotationZ(&matZWorld,D3DXToRadian(fAngle3));

D3DXMatrixTranslation(&matTranslate,0.0f,fUp,fForward);

matWorld = (matYWorld*matXWorld*matZWorld*matTranslate);

dev->SetTransform(D3DTS_WORLD,&matWorld);

D3DXMatrixLookAtLH(&matView,&vEyePt,&vLookatPt,&vUpVec);
dev->SetTransform(D3DTS_VIEW,&matView);


D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,(800.0f/600.0f),1.0f,2500.0f);
dev->SetTransform(D3DTS_PROJECTION,&matProj);


MSG msg;
ZeroMemory(&msg,sizeof(msg));

while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
render();

}
clear();
return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
return 0;

}

return DefWindowProc(hwnd,message,wParam,lParam);
}

bool initialize(HWND hwnd)
{
obj=Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS param;
ZeroMemory(&param,sizeof(param));
param.Windowed=TRUE;
param.SwapEffect=D3DSWAPEFFECT_DISCARD;
param.BackBufferFormat=D3DFMT_UNKNOWN;
param.PresentationInterval=D3DPRESENT_INTERVAL_ONE;

HRESULT hr= obj->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,&param,&dev);
if(FAILED(hr)){
if(FAILED(obj->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&param,&dev)))
return false;
}
dev->SetRenderState(D3DRS_LIGHTING,FALSE);

return true;
}

void render()
{
dev->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(125,125,125),1.0,0);

if(SUCCEEDED(dev->BeginScene()))
{

model->Draw();
dev->EndScene();
}
dev->Present(NULL,NULL,NULL,NULL);

}

void clear()
{
if(model)
{
delete model;
model=NULL;
}
if(dev)
{
dev->Release();
dev=NULL;
}
if(obj)
{
obj->Release();
obj=NULL;
}
}



What i'm actually trying to do here (FOR NOW) is load the model without animatic it (like static) and then go to the next step and work with the stored animation.

The .x file it's a proper one since i've used it with a tutorial code that loads it properly.

The problem could reside in the world matrix, but it seems fine to me (my matrix was simplier and then i've decided to use all the transformation matrix to see if something was missing).

This is the CModel Class that handles the model:

#include "CModel.h"

CModel::CModel(LPDIRECT3DDEVICE9 pD3DDevice)
{
m_pd3dDevice = pD3DDevice;
m_pFrameRoot = NULL;
m_pBoneMatrices = NULL;
m_vecCenter = D3DXVECTOR3 (0.0f,0.0f,0.0f);
m_fRadius = 0.0f;
m_dwCurrentAnimation = -1;
m_dwAnimationSetCount = 0;
m_uMaxBones = 0;
m_pAnimController = NULL;
m_pFirstMesh = NULL;
}

CModel::~CModel()
{

m_pAnimController = NULL;

if(m_pFrameRoot)
{
CAllocateHierarchy Alloc;
D3DXFrameDestroy (m_pFrameRoot,&Alloc);

m_pFrameRoot = NULL;
}

delete [] m_pBoneMatrices;
m_pBoneMatrices = NULL;

m_pd3dDevice->Release();
m_pd3dDevice = NULL;
}

void CModel::LoadXFile(char* strFileName)
{
CAllocateHierarchy Alloc;

if(FAILED(D3DXLoadMeshHierarchyFromX(strFileName,
D3DXMESH_MANAGED,
m_pd3dDevice,
&Alloc,
NULL,
&m_pFrameRoot,
&m_pAnimController)))
{
MessageBox(NULL,strFileName, "Model Load Error", MB_OK);
}

if(m_pAnimController)
m_dwAnimationSetCount = m_pAnimController->GetMaxNumAnimationSets();

if(m_pFrameRoot)
{
SetupBoneMatrices((LPFRAME)m_pFrameRoot,NULL);

m_pBoneMatrices = new D3DXMATRIX[m_uMaxBones];
ZeroMemory(m_pBoneMatrices,sizeof(D3DXMATRIX)*m_uMaxBones);

D3DXFrameCalculateBoundingSphere(m_pFrameRoot,&m_vecCenter,&m_fRadius);
}
}

void CModel::SetupBoneMatrices(LPFRAME pFrame, LPD3DXMATRIX pParentMatrix)
{
LPMESHCONTAINER pMesh = (LPMESHCONTAINER)pFrame->pMeshContainer;

if(pMesh)
{
if(!m_pFirstMesh)
m_pFirstMesh = pMesh;

if(pMesh->pSkinInfo)
{
pMesh->MeshData.pMesh->CloneMeshFVF(D3DXMESH_MANAGED,
pMesh->MeshData.pMesh->GetFVF(),m_pd3dDevice,&pMesh->pSkinMesh);

if(m_uMaxBones < pMesh->pSkinInfo->GetNumBones())
{
m_uMaxBones = pMesh->pSkinInfo->GetNumBones();
}

LPFRAME pTempFrame = NULL;

for (UINT i = 0; i < pMesh->pSkinInfo->GetNumBones(); i++)
{
pTempFrame = (LPFRAME)D3DXFrameFind(m_pFrameRoot,
pMesh->pSkinInfo->GetBoneName(i));

pMesh->ppFrameMatrices = &pTempFrame->matCombined;
}
}
}

if(pFrame->pFrameSibling)
SetupBoneMatrices((LPFRAME)pFrame->pFrameSibling, pParentMatrix);

if(pFrame->pFrameFirstChild)
SetupBoneMatrices((LPFRAME)pFrame->pFrameFirstChild, &pFrame->matCombined);
}

void CModel::SetCurrentAnimation(DWORD dwAnimationFlag)
{
if(dwAnimationFlag != m_dwCurrentAnimation && dwAnimationFlag < m_dwAnimationSetCount)
{
m_dwCurrentAnimation = dwAnimationFlag;
LPD3DXANIMATIONSET AnimSet = NULL;
m_pAnimController->GetAnimationSet(m_dwCurrentAnimation,&AnimSet);
m_pAnimController->SetTrackAnimationSet(0,AnimSet);
AnimSet->Release();
AnimSet = NULL;
}
}

void CModel::Draw()
{
LPMESHCONTAINER pMesh = m_pFirstMesh;

while(pMesh)
{
LPD3DXMESH pDrawMesh = (pMesh->pSkinInfo)
? pMesh->pSkinMesh : pMesh->MeshData.pMesh;

for (DWORD i = 0; i < pMesh->NumMaterials; i++)
{
m_pd3dDevice->SetMaterial(&pMesh->pMaterials9);
m_pd3dDevice->SetTexture(0, pMesh->ppTextures);
pDrawMesh->DrawSubset(i);
}

pMesh = (LPMESHCONTAINER)pMesh->pNextMeshContainer;
}
}

void CModel::DrawFrame(LPFRAME pFrame)
{
LPMESHCONTAINER pMesh = (LPMESHCONTAINER) pFrame->pMeshContainer;

while(pMesh)
{
LPD3DXMESH pDrawMesh = (pMesh->pSkinInfo)
? pMesh->pSkinMesh: pMesh->MeshData.pMesh;

for (DWORD i = 0; i < pMesh->NumMaterials; i++)
{
m_pd3dDevice->SetMaterial(&pMesh->pMaterials9);
m_pd3dDevice->SetTexture(0,pMesh->ppTextures);
pDrawMesh->DrawSubset(i);
}

pMesh = (LPMESHCONTAINER) pMesh->pNextMeshContainer;
}

if(pFrame->pFrameSibling)
DrawFrame((LPFRAME)pFrame->pFrameSibling);
if(pFrame->pFrameFirstChild)
DrawFrame((LPFRAME)pFrame->pFrameFirstChild);
}

void CModel::Update(double dElapsedTime)
{
if(m_pAnimController && m_dwCurrentAnimation != -1)
m_pAnimController->AdvanceTime(dElapsedTime,NULL);
if(m_pFrameRoot)
{
UpdateFrameMatrices((LPFRAME)m_pFrameRoot,NULL);

LPMESHCONTAINER pMesh = m_pFirstMesh;
if(pMesh)
{
if(pMesh->pSkinInfo)
{
UINT Bones = pMesh->pSkinInfo->GetNumBones();
for(UINT i = 0; i < Bones; i++)
{
D3DXMatrixMultiply(
&m_pBoneMatrices,
&pMesh->pBoneOffsets,
pMesh->ppFrameMatrices
);
}

void *SrcPtr, *DestPtr;
pMesh->MeshData.pMesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&SrcPtr);
pMesh->pSkinMesh->LockVertexBuffer(0,(void**)&DestPtr);

pMesh->pSkinInfo->UpdateSkinnedMesh(m_pBoneMatrices,NULL,SrcPtr,DestPtr);

pMesh->pSkinMesh->UnlockVertexBuffer();
pMesh->MeshData.pMesh->UnlockVertexBuffer();
}
}
}
}

void CModel::UpdateFrameMatrices(LPFRAME pFrame, LPD3DXMATRIX pParentMatrix)
{
if(pParentMatrix)
{
D3DXMatrixMultiply(&pFrame->matCombined,
&pFrame->TransformationMatrix,
pParentMatrix);
}
else
pFrame->matCombined = pFrame->TransformationMatrix;

if(pFrame->pFrameSibling)
{
UpdateFrameMatrices((LPFRAME)pFrame->pFrameSibling,pParentMatrix);
}
if(pFrame->pFrameFirstChild)
{
UpdateFrameMatrices((LPFRAME)pFrame->pFrameFirstChild,&pFrame->matCombined);
}
}



Any clue on what i'm missing?

Maybe i'm trying to draw the model in a weird way?

Thanks in advance

Share this post


Link to post
Share on other sites
Advertisement
UPDATE:

Tried to use the DrawFrame function and passed the model frame root (m_pFrameRoot) and casted it to LPFRAME (since it was a LPD3DXFRAME type).

By making the m_pFrameRoot and DrawFrame public in the class and compiling the program, the model was still not rendered, so i used the debug to see what was happening in the DrawFrame call.

The problem i noticed is that the frame root has no data at all about the mesh container, sibiling and childs. This is the same when the x. file is loaded (model->LoadXFile).

EDIT: Problem solved! i had to USE the draw function, but after load call i had to initialize the bounding center and the bounding box.

Thanks anyway :D

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!