Archived

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

DirectX + OGL games

This topic is 5129 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 in the slow and painfully enjoyable task of piecing together a 3d engine using DirectX. My question is, how on earth do games employ engines that support both Direct3D AND OpenGL. For example, if i was to make my engine support OpenGL also, i would have to change 80% of the code. My lighting would be different, so would my meshes, initialisation, depth buffering, transformations. OpenGL even operates on entirely different concepts in some aspects of operation. Anyone got a clear and precise answer? Cheers! Dave

Share this post


Link to post
Share on other sites
Through abstraction.

You''ve obviously fused your DirectX code with your engine code, which isn''t neccessarily wrong or bad, but not very modular (as you can see).

Say you have CHeightMap, this data would contain nothing but raw vertex information, texture information, etc.

Then you pass the Height Map to your renderer, and the renderer (DirectX or OpenGL) would render it appropriately, using its in-house functions.

You might just have something like CHeightMap->Render() which calls all your DirectX functions, so instead you just pass the height map to a renderer.

The key is to make your content as API inspecific as possible.

Share this post


Link to post
Share on other sites
Fundamentaly Opengl is VERY similar to DirectX. 3d concepts are the same for both. Its not too complex to have both Direct3d and opengl in an engine, especially when using a object oriented language.

Just do a base abstract class "IRenderer" that will serve as an interface to the application, then derive 2 class, for example COGLRenderer and CD3DRenderer. Those 2 would encapsulate all the API specific code to make it easy to maintain.

Then, during initialization of your engine, you would simply create an instance of the appropriate renderer.
Since all methods defined in IRenderer are implemented in both subclasses, the application will run without modication regarless of what graphic api is being used.

You could also go further and have both COGLRenderer and CD3DRenderer in their own .dll

class IRenderer
{
virtual void DrawObject(Mesh* p_objectToDraw) = 0;
};

class COGLRenderer : public IRenderer
{
void DrawObject(Mesh* p_objectToDraw);
}

class CD3DRenderer : public IRenderer
{
void DrawObject(Mesh* p_objectToDraw);
}

IRenderer* m_pGraphicSystem;

if(renderer == RENDERER_OGL)
m_pGraphicSystem = new COGLRenderer();
else
m_pGraphicSystem = new CD3DRenderer();

m_pGraphicSystem->DrawObject(object);

[edited by - dopeflow on November 30, 2003 12:39:14 AM]

[edited by - dopeflow on December 1, 2003 2:56:59 PM]

Share this post


Link to post
Share on other sites
OK That''s a great answer thanks. But, in abstracting my code as much as possible, I am losing most of the benefits of the dx or ogl interfaces. For example, i would obviously lose the "mesh" function in dx and have to store my data in my own arrays or vectors, as the dx mesh would be different to the ogl mesh. How should i do my lighting? That is, should i calculate it all my self in order to be compatible with dx and ogl? And finally, matrix transformations? Should i code these myself also?

I suppose what i need to know is where do i draw the line in what i leave to dx/ogl and what do i do myself?

dave

Share this post


Link to post
Share on other sites
quote:
Original post by dopeflow
Fundamentaly Opengl is VERY similar to DirectX. 3d concepts are the same for both. Its not too complex to have both Direct3d and opengl in an engine, especially when using a object oriented language.

Just do a base abstract class "IRenderer" that will serve as an interface to the application, then derive 2 class, for example COGLRenderer and CD3DRenderer. Those 2 would encapsulate all the API specific code to make it easy to maintain.

Then, during initialization of your engine, you would simply create an instance of the appropriate renderer.
Since all methods defined in IRenderer are implemented in both subclasses, the application will run without modication regarless of what graphic api is being used.

You could also go further and have both COGLRenderer and CD3DRenderer in their own .dll

class IRenderer
{
virtual void DrawObject(Mesh* p_objectToDraw);
};

class COGLRenderer
{
void DrawObject(Mesh* p_objectToDraw);
}

class CD3DRenderer
{
void DrawObject(Mesh* p_objectToDraw);
}

IRenderer* m_pGraphicSystem;

if(renderer == RENDERER_OGL)
m_pGraphicSystem = new COGLRenderer();
else
m_pGraphicSystem = new CD3DRenderer();

m_pGraphicSystem->DrawObject(object);

[edited by - dopeflow on November 30, 2003 12:39:14 AM]


Your classes don''t inherit from IRenderer

Share this post


Link to post
Share on other sites
to be more specific, for example if i used my own array to hold mesh info, and passed this to either ogl or dx, i would lose the capabilities of these interfaces to store all the mesh data in some decently fast memory ie video memory.

just an example

dave

Share this post


Link to post
Share on other sites
no you wouldn''t, just abstract it above the highest api feature you are planing yo use, make an array of whatever thing, vertex buffers or textures for example, in your high level game code keep trak of who''s useing what by an index to that array.

Bobboau, bringing you products that work... in theory

Share this post


Link to post
Share on other sites
ok fair enough. i''m sorry i''m being so repetitive, i''m having trouble find good resources that cover 3d engine design without either totally avoiding API''s or being totally API specific.

I would most appreciate it if you could suggest any directx classes/functions i should avoid using in making an Opengl+DX engine due to their incompatible styles. Eg should i store my vertices in vectors instead of using API meshes?

To tell the truth, i''m having trouble thinking of anything in a 3d engine whose code isn''t API specific other than object culling. Lighting, transforming, rasterising, vertex storage, depth buffering are all coded differently in different API''s.

cheers
dave

Share this post


Link to post
Share on other sites
Alternatively to dopeflow's implementation, you might want to abstract at the more practicle, low level such as abstracting to a vertex buffer so that you create a generalized VB object and pass that object to the renderer. That way you write the model loading code once, and then just write how the renderers handle the data. Less code writing and IMO works out better. This is a good thread to look at, it will give you more of an idea on how to implement things: http://www.gamedev.net/community/forums/topic.asp?topic_id=137467

James Simmons
MindEngine Development
http://medev.sourceforge.net

[edited by - neurokaotix on December 1, 2003 3:57:16 PM]

Share this post


Link to post
Share on other sites
why not something simple like this:

class D3DRenderer
{
render()
loadmesh()
rotate()
}

class OGLRenderer
{
render()
loadmesh()
rotate()
}

then in the engine code....
IF Direct3D is the way to go THEN
RenderObject=D3DRenderer
ELSE
RenderObject=OGLRenderer

....later on:
RenderObject.LoadMesh();
RenderObject.Render();
etc

Why all the class derivation and fancy stuff?

cheers!
dave


Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Davefromalbury
Why all the class derivation and fancy stuff?



Well duh! ''Cause its FANCY!!!
Humans are emotional, irrational, and illogical, thats why they need the complicated fancy stuff.

Share this post


Link to post
Share on other sites
Seems more natural to me to have an interface, since both classes have exactly the same functions, the code in them is just different.

Imho pc''s are so fast today, that its an error to not use the benifits of oo programming simply because of some function overhead.

And besides,

IF Direct3D is the way to go THEN
RenderObject=D3DRenderer
ELSE
RenderObject=OGLRenderer


that would mean RenderObject is the same type for both, or at least, an object derived from the same class, which would be the interface

Share this post


Link to post
Share on other sites
I also feel the oo way is the best way. I have been using the opensource Ogre graphics engine as of lately, and have foudd it to perform nicely, and it has a good community base. It uses some of the approaches already mentioned in this thread: generic base class, with derived classes for each specific render system (GL DX7, DX9). Also uses the dll thing for windows and .so on Linux. You should look at how its render systems are designed. ogre.sourceforge.net

Share this post


Link to post
Share on other sites