Skip to main content
GameDev.net gamedev.net
🔒 Locked

Using ID3DXAllocateHierarchy::CreateFrame

Started by In_Yack_Mode Feb 28, 2009 at 1:07 PM 9 replies 3.4k views
Original Post
In_Yack_Mode
In_Yack_Mode
Hello, I am trying to call ID3DXAllocateHierarchy::CreateFrame, but I am getting this error "error C2352: 'ID3DXAllocateHierarchy::CreateFrame' : illegal call of non-static member function." I thought maybe I needed to have an object to call it, but it wouldn't let me. So how do I need to call this then? I have this now:
 LPD3DXFRAME* ppNewFrame;
	LPCSTR frame1;
	
	ID3DXAllocateHierarchy::CreateFrame(
				frame1,
				ppNewFrame
				);
Any advice? Thanks!
Mike.Popoloski
Mike.Popoloski
The error message is telling you that ID3DXAllocateHierarchy::CreateFrame is not static, so you need an instance of that type in order to call the method. The reason you are unable to create an instance of ID3DXAllocateHierarchy is because it is an abstract base class, also known as an interface. You need to derive your own class from this interface, implement its methods, and then create an instance of it.

Finally, you should never really need to call CreateFrame yourself. D3DX will take care of doing that for you when you call D3DXLoadMeshHierarchyFromX().
Mike Popoloski | Journal | SlimDX
In_Yack_Mode
In_Yack_Mode
Ok. So what do I need to put in
HRESULT D3DXLoadMeshHierarchyFromX(  LPCSTR Filename,  DWORD MeshOptions,  LPDIRECT3DDEVICE9 pDevice,  LPD3DXALLOCATEHIERARCHY pAlloc,  LPD3DXLOADUSERDATA pUserDataLoader,  LPD3DXFRAME* ppFrameHierarchy,// this one?  LPD3DXANIMATIONCONTROLLER* ppAnimController);

Thanks for the help.
programci_84
programci_84
Hi,

First, execuse me if you cannot understand because of my bad English.

The interface ID3DXAllocateHierarchy is a user-implemented interface. So, you have to write declarations of all the functions of this interface how you want.

Suppose you've got a car mesh and a hierarchy in it: The root frame is body, and child frames are wheels. While loading a hierarchy by calling D3DXLoadMeshHierarchyFromX(), this function calls CreateFrame(), CreateMeshContainer() and the others (you've to declare all of this functions) every time a frame and/or a mesh container loading, for you; so you can't call'em in your application.

Here an example from my code:
class CActor{   CActor();   virtual ~CActor();   //some other functions here   LPD3DXFRAME m_pRootFrame;}class CAlloc : public ID3DXAllocateHierarchy{STDMETHOD(CreateFrame) (THIS_ LPCSTR Name, LPD3DXFRAME *ppNewFrame);	STDMETHOD(CreateMeshContainer) (THIS_ LPCSTR Name,                                 CONST D3DXMESHDATA *pMeshData,                                 CONST D3DXMATERIAL *pMaterials,                                 CONST D3DXEFFECTINSTANCE *pEffectInstances,                                 DWORD NumMaterials, CONST DWORD *pAdjacency,                                 LPD3DXSKININFO pSkinInfo,                                 LPD3DXMESHCONTAINER *ppNewMeshContainer);	STDMETHOD(DestroyFrame) (THIS_ LPD3DXFRAME pFrameToFree);STDMETHOD(DestroyMeshContainer)	(THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree);CAlloc (CActor act) : m_pActor (act) {}CActor* m_pActor;}


CAlloc is ID3DXAllocateHierarchy-driven class. And for example, here's a CreateFrame() declaration from my code again:
HRESULT CAlloc::CreateFrame(LPCSTR Name, LPD3DXFRAME *ppNewFrame){	//Define the objects	/******************************************/	D3DXFRAME* pmfNF	=	new D3DXFRAME;	ZeroMemory (pmfNF, sizeof (D3DXFRAME));	if (!pmfNF) 	{		DestroyFrame (pmfNF);		return E_OUTOFMEMORY;	}	*ppNewFrame = NULL;	/******************************************/		//Copy name	/******************************************/	if (Name) 		pmfNF->Name	=	(CHAR*) MyStrCopyFunc ((CHAR*)Name);	else		pmfNF->Name =	(CHAR*) MyStrCopyFunc ("<unnamed>");	/******************************************/	//All matrices must be an identity	/******************************************/	D3DXMatrixIdentity (&pmfNF->TransformationMatrix);	/******************************************/	//Out	/******************************************/	*ppNewFrame		=	(D3DXFRAME*) pmfNF;	pmfNF			=	NULL;	/******************************************/	return S_OK;}


I must say, declarations of CreateFrame(), CreateMeshContainer(), DestroyFrame() and DestroyMeshContainer() depend on your applications. That's why ID3DXAllocateHierarchy is user-implemented.

Suppose you wrote your CreateXXX() and DestroyXXX() declarations. Before calling D3DXLoadMeshHierarchyFromX(), you must define a CAlloc* pointer and pass this into D3DXLoadMeshHierarchyFromX() function:

...HRESULT CActor::LoadMeshHierarchy (...){   CAlloc* allocator (this);   HRESULT hr = D3DXLoadMeshHierarchyFromX (FileName, D3DXMESH_MANAGED,                                             m_pD3DDevice, &allocator,                                             NULL, &m_pRootFrame, NULL);   return hr;}


Regards,
Rohat.

[Edited by - programci_84 on March 1, 2009 2:49:44 AM]
There's no "hard", and "the impossible" takes just a little time.
In_Yack_Mode
In_Yack_Mode
Ok so do I need to call it or will D3DXLoadMeshHierarchyFromX() call it for me? I have
D3DXLoadMeshHierarchyFromX(				"basicani.x",				D3DXMESH_SYSTEMMEM,    // load the mesh into system memory                d3ddev,                // the Direct3D Device				LPD3DXALLOCATEHIERARCHY pAlloc,				0,				LPD3DXFRAME* ppNewFrame,				LPD3DXANIMATIONCONTROLLER* ppAnimController				);

I get 1 error "error C2275: 'LPD3DXALLOCATEHIERARCHY' : illegal use of this type as an expression." Why am I getting that error? It seems like I need to do what programci_84 said to get rid of the error. Thanks for the replies.
programci_84
programci_84
Hi,

Quote:
Ok so do I need to call it or will D3DXLoadMeshHierarchyFromX() call it for me?


You don't need to call; D3DXLoadMeshHierarchyFromX() calls it for you everytime a frame is being created. But if you don't declare CreateXXX() and DestroyXXX() functions correctly, D3DXLoadMeshHierarchyFromX() will fail.

Let us turn the other issue: error C2275. You must write your own ID3DXAllocateHierarcy-derived class (e.g. CAlloc) and get a pointer (CAlloc* allocator). Then you must pass it with address parameter (&allocator) to D3DXLoad...() function:

Here's the true way:
D3DXLoadMeshHierarchyFromX (FileName, D3DXMESH_MANAGED,                                   m_pD3DDevice, &allocator,                                   NULL, &m_pRootFrame, NULL);


But as in yours, you mustn't pass the 4th parameter as "LPD3DXALLOCATEHIERARCHY pAlloc".

Regards.
There's no "hard", and "the impossible" takes just a little time.
In_Yack_Mode
In_Yack_Mode
I have built the class to inheirit from the interface, but now I am getting these errors:
WinMain1.obj : error LNK2001: unresolved external symbol "private: virtual long __stdcall CAlloc::CreateFrame(char const *,struct _D3DXFRAME * *)" (?CreateFrame@CAlloc@@EAGJPBDPAPAU_D3DXFRAME@@@Z)WinMain1.obj : error LNK2001: unresolved external symbol "private: virtual long __stdcall CAlloc::CreateMeshContainer(char const *,struct _D3DXMESHDATA const *,struct _D3DXMATERIAL const *,struct _D3DXEFFECTINSTANCE const *,unsigned long,unsigned long const *,struct ID3DXSkinInfo *,struct _D3DXMESHCONTAINER * *)" (?CreateMeshContainer@CAlloc@@EAGJPBDPBU_D3DXMESHDATA@@PBU_D3DXMATERIAL@@PBU_D3DXEFFECTINSTANCE@@KPBKPAUID3DXSkinInfo@@PAPAU_D3DXMESHCONTAINER@@@Z)WinMain1.obj : error LNK2001: unresolved external symbol "private: virtual long __stdcall CAlloc::DestroyFrame(struct _D3DXFRAME *)" (?DestroyFrame@CAlloc@@EAGJPAU_D3DXFRAME@@@Z)WinMain1.obj : error LNK2001: unresolved external symbol "private: virtual long __stdcall CAlloc::DestroyMeshContainer(struct _D3DXMESHCONTAINER *)" (?DestroyMeshContainer@CAlloc@@EAGJPAU_D3DXMESHCONTAINER@@@Z)


I am not sure what they mean.

This is the class I built. I just took the interface and made it inheirit from my class and made the functions not pure.
class CAlloc : public ID3DXAllocateHierarchy	{      STDMETHOD(CreateFrame)(THIS_ LPCSTR Name,                             LPD3DXFRAME *ppNewFrame);    STDMETHOD(CreateMeshContainer)(THIS_         LPCSTR Name,         CONST D3DXMESHDATA *pMeshData,         CONST D3DXMATERIAL *pMaterials,         CONST D3DXEFFECTINSTANCE *pEffectInstances,         DWORD NumMaterials,         CONST DWORD *pAdjacency,         LPD3DXSKININFO pSkinInfo,         LPD3DXMESHCONTAINER *ppNewMeshContainer);    STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree);     STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree); 	};

Thanks for the help so far programci_84 and Mike.
programci_84
programci_84
Hi,

The reason of LNK2001 errors is that you've only "define" your derived class. You have to "declare" 'em as well.

I don't know how will you use hirerarchical meshes but now I'm sending you my mesh hierarchy project. You can use it to write your own ;)

Click

You have to look at GHareketli.h, GHareketli.cpp, GMesh.h and GMesh.cpp.

They're all (especially // and /* */ comments) Turkish but I think you can understand "codes" :) I hope this will useful for you ;)

Regards.
There's no "hard", and "the impossible" takes just a little time.
In_Yack_Mode
In_Yack_Mode
Thanks programci_84. It is almost working and I think I can figure it out from here.
jtagge75
jtagge75
This helped me quite a bit when I was trying to do .x animations.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.