Archived

This topic is now archived and is closed to further replies.

D3DXVECTOR3

Should evey object have it's own LPDIRECT3DDEVICE9?

Recommended Posts

Or pass the LPDIRECT3DDEVICE9 as an parameter when needed?? Lets say I have a class that handles DirectX *.x meshes, its need a LPDIRECT3DDEVICE9 for loading and rendering. Should classes like this one have his own LPDIRECT3DDEVICE9 or use the LPDIRECT3DDEVICE9 from the main class ??

class DXMesh
{
public:
	DXMesh();
	~DXMesh();

	HRESULT LoadMesh(LPDIRECT3DDEVICE9 pd3dDevice);
	void RenderMesh();

private:

	LPDIRECT3DDEVICE9	gd3dDevice;
	LPD3DXMESH              gMesh;
	D3DMATERIAL9*           gMeshMaterials;
	LPDIRECT3DTEXTURE9*     gMeshTextures;
	DWORD                   gdwNumMaterials;
};

In LoadMesh I have a line like this : gd3dDevice = pd3dDevice; or Like this

class DXMesh
{
public:
	DXMesh();
	~DXMesh();

	HRESULT LoadMesh(LPDIRECT3DDEVICE9 pd3dDevice);
	void RenderMesh(LPDIRECT3DDEVICE9 pd3dDevice);

private:

	LPD3DXMESH              gMesh;
	D3DMATERIAL9*           gMeshMaterials;
	LPDIRECT3DTEXTURE9*     gMeshTextures;
	DWORD                   gdwNumMaterials;
};

I''m asking this because of memory usage. Which is the best lets say in memory usage and speed?? I have always used the 2nd option. pass the LPDIRECT3DDEVICE9 as a parameter when needed, but now I have changed it (along with some other changes) and my memory usuage went from 50MB to about a 100MB and this is the only reason that comes to my mind.

Share this post


Link to post
Share on other sites
I think it very unlikely that this is causing the change in memory. I make the device global and use extern to use it in other source files. I know globals are bad but so is passing a pointer around all over the shop and making a local copy is even worse! So I would say go with it as global but try to find a way to prevent the problems with globals - multiple instances, who creates them ? who deletes them? etc. e.g. you could create a singleton class whose function is to manage globals like this

Share this post


Link to post
Share on other sites
Passing pointers used to eat a lot, but those days are gone now so you can savely store one single device pointer in a parent class, or you can always keep it global(Or namespaced) ofcourse

But creating overhead for all your classes, that''s not the way to go, not to mention the mess it creates.

Share this post


Link to post
Share on other sites
WHat i did, don''t knowwhether its good or bad, was to havea pointer to a device in every object and have teh creation of the device in one class.

regards

ace

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
If you have a case where code that knows nothing about D3D calls a member function that needs a device pointer, you <u>can''t</u> pass it as a parameter because it isn''t available. You might save yourself some trouble if you plan ahead for this and keep a copy of the pointer in the class.

Share this post


Link to post
Share on other sites
I think you should be using only one IDirect3DDevice9 interface
each mesh should not have its own d3d device

Share this post


Link to post
Share on other sites
Having the pointer (which doesn''t use much memory (32 bits I think?)) in every class is a nice way to have quick access to it within the class''s private functions and it prevents having to pass the pointer (except in the constructor). I like to do it this way for that reason. On the other hand, if 100 MB of memory usage (you are talking about system memory right?) is too much for the requirements you want to meet, then pass it through functions...at the expense of a little larger executable. You may be able to optimize things a little more too. For instance, instead of putting the pointer in every single class, put it in the parent class (like a manager of some type), then from the child classes, call Parent->Device, where you saved the Parent of the class.

class cWindow
{
public:
LPDIRECT3DDEVICE9 pd3dDevice;
cWindow(LPDIRECT3DDEVICE9 fp3dDevice);
};

class cWindowComponent
{
private:
pfUpdateVertices(void);
cWindow *pParent;
public:
cWindowComponent(cWindow *fpParent);
};

cWindowComponent:fUpdateVertices(void)
{
// Do whatever with pParent->p3dDevice.
}

This way, you could make 1 window with 20 components, but only store the device in the 1 window. You could take it a step further by storing the device in the cWindowContainer class, then calling pParent->Parent(this one would have to be public)->p3dDevice; for all windows and all components in every window. It would generate a slightly small loss of cpu (are we counting nanoseconds? Yes we are...we make games. ) but it would reduce your memory overhead.

Chris

Share this post


Link to post
Share on other sites
It''s just a 4 byte pointer, so passing a copy in the creator and storing it locally isn''t that big a deal.
Alternatively you can make your own (singleton) device class with the pd3ddevice as a public static member and use that in every draw call.

Share this post


Link to post
Share on other sites
Or you could have a static member in DXMesh holding the LPDIRECT3DDEVICE9. Then you would just set it in your D3D initiation code like so: DXMesh::device = pointerToDevice. Now you have one pointer for all meshes.

Share this post


Link to post
Share on other sites
quote:
Original post by The Beholder
Or you could have a static member in DXMesh holding the LPDIRECT3DDEVICE9. Then you would just set it in your D3D initiation code like so: DXMesh::device = pointerToDevice. Now you have one pointer for all meshes.


That feels wrong, if the device manipulates static data in the mesh class or calls a static function. Then everytime you add another class (a sprite class, progressive mesh class) you have to mofidy code in your device init function.

Share this post


Link to post
Share on other sites
Every D3D object contains a pointer to the D3D Device already...4 bytes isn''t a big deal, and is probably less cumbersome than passing the pointer for function calls.

Personally, I use a singleton-based system with a global macro that allows me to simply call:

RenderEngine.GetDevice()->DrawPrimitive()

Nice, clean, easy.

Wee.

Share this post


Link to post
Share on other sites
Yes Etnu that is what I have been advocating and seems to be what most people do. Its not the overhead of passing the pointer around but rather the clumsiness of it and the alternative of storing multiple pointers to the same memory scares me - but then I tend to code defensively

Share this post


Link to post
Share on other sites
If adding a device pointer to your objects adds 50MB, you
have a serious spectre problem.

Unless you're creating 12500000 objects.

One 100x100 32-bit bitmap uses 40000 bytes of memory.
One device pointer uses 4 bytes. One bitmap = enough
memory for 10,000 pointers.

This is a beginner phobia that will desolve over time.

[edited by - Jiia on May 18, 2004 11:42:52 PM]

Share this post


Link to post
Share on other sites
what i do is when initialising the class that requires the device is initialise it with the dx code and then use the getdevice() function if it is required later from what ever objects you are using eg vertexbuffers

eg in loadMesh() you initialise your program with the device

and with renderMesh() you use gMesh->getDevice() to get the device back

im not sure if this is regarded as a bad way, anyone know? eg slower?

[edited by - johnnyBravo on May 19, 2004 1:28:40 AM]

Share this post


Link to post
Share on other sites
To answer that we would need to know what goes on in the dx code when that call is invoked i.e. the source code. Unless some kind Microsoft person would give the answer

Share this post


Link to post
Share on other sites
I have found the reason going from 50MB to 100MB. its on one of the textures I load. 5 Textures and the largest is ''only'' 512*512. But still I''d like to know what the best solution is. I see some idea''s on how you some of you do it so I will look into that.

Wait a sec, I have the sode from ALLEGIANCE, time to take a look into it on how they have done it

Share this post


Link to post
Share on other sites