• Advertisement

Archived

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

How do you wrapp D3D?!

This topic is 5812 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

hi, I''m make a litle research for my new engine, and i''m searching for a good way to handle d3d. Is it a good way to add an additional layer to the D3d interface?! Because when i would render my scene i''ve to give every object, that have to render, the d3d interface pointer as an param. And when i would create an vertex or an index buffer, there is the same, both interfaces need the d3d device pointer. How did you wrapp the Direct3d interface to an higher layer, or how did you handle the functionality?! If so, how did you wrapp it, add you for every d3d method an similar method to your wrapper?! And how did you handle the the creation of vertex and index buffers, and the render and texture states?! Hmm, i''ve thinking about an similar implementation like opengl, but i don''t know if this the best way to handle the 3d interface. I hope this was not that confuse (soz for the friggin english *g*) Many thanks... Mfg Impz0r

Share this post


Link to post
Share on other sites
Advertisement
Is the ultimate goal of your engine to support multiple renderers? If "no", then you might be wasting your time.

Otherwise, the best way to deal with a wrapper or abstraction is to look at commonalities betweek the two APIs (OpenGL and Direct3D). Both have a "rendering device". Both require lists of triangles. Both have device states. Both have texturing systems.

Designing an abstraction essentially means that if someone would read your code, they would not be able to tell which API you are using at the highest level of programming.

Example: My sprite engine uses a hardware 3d renderer to render sprites, so the code to render one sprite might look like:

lpGraphics->RenderQuad(lpTexture, x, y, w, h, dwColor);

This is a simplification but it should give you an example of a call rather than seeing glBegin(), glDrawIndexedPrimitive(), glEnd() calls and pD3DDevice->SetTextureStageState(), pD3DDevice->DrawindexedPrimitiveUP(), pD3D->Present() calls.

Good luck!


MatrixCubed
http://MatrixCubed.cjb.net






Share this post


Link to post
Share on other sites
hi,

No it''s not my ultimate goal to support both API''s D3D and OpenGl.
If it''s then a good way to wrapp all the functionality because i use only one of the API''s?!

Thanks alot...

Mfg Impz0r

Share this post


Link to post
Share on other sites
I''m not sure if I understand you. But my DirectX Graphics wrapper is simple. It''s a class that encapsulates info like screen width, height, fullscreen or not, etc. And it only has 4 public functions. Initiate(), Release(), BeginScene(), EndScene().

}+TITANIUM+{

Share this post


Link to post
Share on other sites
A wrapper essentially can do any thing you want to simplify your life; Example Initiate Direct3D, Present the screen, shutdown Direct3D....

I wrote a simple one just to aid the speed of me writing programs - I no longer have to write and rewrite the same code to initiate D3D.

Of course you could use it to encapsulate OpenGL as well....

Neil

WHATCHA GONNA DO WHEN THE LARGEST ARMS IN THE WORLD RUN WILD ON YOU?!?!

Share this post


Link to post
Share on other sites
hi,

hmm, the question was not how to write a wrapper, i know how to write some , but i''m interested how You write some :D

Seriema: if you only implement this fourth public method, how do you handle the rest aka create an vertex or an index buffer?!

Thanks alot...

Mfg Impz0r

Share this post


Link to post
Share on other sites
If you''re only wrapping one API, then your wrapper should not replace calls to the Direct3D functions, but instead simplify things. So your wrapper should have a function for setting the display mode, for example, but there''s no point in giving the wrapper a function to change the fill mode, since that can be done in just one call to SetRenderState. So your wrapper should have a GetDevice() function that returns the Direct3D device, so your code can work with it directly when it wants to.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
I have wrappers for each DX interface I use, that wrap every method of those interfaces, because they simplify things .
Basically, they convert HRESULTs to exceptions, and automatically call error handing functions that can log stuff, TRACE stuff, dump call stack, etc. The rationale for this is simple: I have debug DX runtime that hits three breakpoints before returning a failed HRESULT, but none of my friends do. I know it isn''t the fastest way to do things, which is why some methods *can* be expanded inline, if extra error checking is not needed.

Share this post


Link to post
Share on other sites
Oh, you mean how specifically we write them? Well, I support both OpenGL and Direct3D so my code can never work with OpenGL or Direct3D directly; everything is done through the wrapper.

You would use my wrapper like this:

renderer* Renderer = new direct3d;
// SetDisplayMode (Width,Height,BitDepth,IsFullscreen,ZBitDepth)
Renderer->SetDisplayMode( 800, 600, 16, true, 16 );
// SetViewport (X,Y,Width,Height,FOV,Near,Far)
Renderer->SetViewport( 0, 0, 800, 600, 90, 0.125, 10000 );
// SetClearValues (Red,Green,Blue,Alpha,ZBufferValue)
Renderer->SetClearValues( 0, 0.125, 0.5, 0, 1 );

UINT Grass;
Renderer->CreateMaterial( &Grass, RENDER_3D );
Renderer->SetProperty( &Grass, RENDER_FILLMODE, RENDER_SOLID );
Renderer->SetProperty( &Grass, RENDER_SHADEMODE, RENDER_GOURAUD );
Renderer->SetProperty( &Grass, RENDER_DEPTHTEST, RENDER_LEQUAL );
Renderer->SetProperty( &Grass, RENDER_FILTERS, RENDER_LINEAR, RENDER_LINEAR );

Renderer->LoadTexture( &Grass, RENDER_USEMIPMAPS, STREAM_FILE, "Grass.bmp" );
// Let''s assume the vertices and indices are arrays whose data
// has already been loaded beforehand
Renderer->AddGeometry( &Grass, NumVertices, VertexArray, NumIndices, IndexArray );

// Then in the main loop:
Renderer->Clear( );
Renderer->DrawMaterial( &Grass );
Renderer->Show( );


~CGameProgrammer( );

Share this post


Link to post
Share on other sites
hi,

first thanks for your replays, i hope many more show his way of wrapping the d3d functionality

CGameProgrammer : your way looks cool in my opinion *g*, your implementation looks similar to opengl, your way to work with this handle is cool. How do you handle this, when you call this method : Renderer->CreateMaterial( &Grass, RENDER_3D ); did you create in your renderer an struct with all informations about renderstates, vertices and textures etc.?! mean that that you have internal an vertexbuffer for every handle where you add thoes vertices per this method call Renderer->AddGeometry()?!
And im interested in how do you handle this one : Renderer->SetDisplayMode() if you use internaly the d3d renderer, how do you handle the adapter shit with all those enumerates for the displaymodes?!

Thanks alot...

Mfg Impz0r

Share this post


Link to post
Share on other sites
My CreateMaterial function creates a "material" struct and assigns "Grass" as a pointer to it. I could say material* Grass but I like the look of using a UINT better. Anyway, the material struct contains the texture dword (used as an LPDIRECT3DTEXTURE8 or the dword glBindTexture and glGenTextures use), the render properties, and a linked list of geometry data. Each time you call AddGeometry, it adds a new geometry list to the material.

My SetDisplayMode function doesn''t enumerate the display modes, I have a seperate GetDisplayModes() function that does that. SetDisplayMode() just tries to set the display mode to whatever''s passed to the function. It''s nothing fancy.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Forgot to mention that my wrapper has a GetDevice() *of course* My cDX8Graphics wrapper class only wraps the "bare bones" of DirectGraphics. To initiate and destroy, open scene and plot scene, and provide a pointer to the device. Stuff like "vertex or an index buffer" have their own wrapper classes I don''t want everything in one BIG class. I like to make several specific classes.

}+TITANIUM+{

Share this post


Link to post
Share on other sites
My wrapper uses DLLs, and is similar to CGameProgrammer()''s. I have functions exported from the DLL like GetInterface(), and GetName(), that returns a interface IRender; pointer, which is an abstract class (only has pure virtual functions). The IRender interface has functions like CreateTexture(), LoadModel(), BeginScene(), etc.
In the DLL itself, there is a class CD3DRender; or class COGLRender; that derives from IRender. Each specific class has its own data members like the LPDIRECT3DDEVICE8.
I use handles (array indices) for textures, models, etc. like CGameProgrammer()''s UINTs.
This way, the client program is completely unaware of what renderer its using.
At the start of the client program, i use Win32 functions to search for .dll files, and see if they are valid renderer dlls (they have all the nescesary functions (through GetProcAddress())). Then i can display i dialog to the user asking what DLL they want to use, and stick the value returned from GetName() in a combo box for example. So D3DRender.dll''s GetName() function would return "Direct3D 8 Rendering Device".

Just my over-complex way of doing things.

Steve

Share this post


Link to post
Share on other sites

  • Advertisement