Jump to content


3D game engine design and architecture help


9 replies to this topic

#1 sirfalas

    New Member

  • Members
  • PipPip
  • 22 posts

Posted 15 January 2007 - 07:49 AM

Hi there, I am trying to develop my own 3D engine with DirectX. I have not decided what kind of game engine I would be creating but it would most probably be a top-down rpg-like engine. Kinda like the Aurora engine that the first neverwinter nights game used (but obviously less complicated).

I just completed creating a bitmap font rendering class that uses texture quads with bitmapped fonts to render text. Coding this class got me thinking.
First let me give you my question and then elaborate my dilemma.

I know the benefits of a object-oriented design to the end user of my engine because it simplifies things and creating/destroying an object becomes a simpler task. However, how about interaction between individual engine components? Should I also design them in an object-oriented way? Let me elaborate

Basically I decided to encapsulate all primitive rendering functions into a simple function that my engine would mainly call. So instead of something like
mDevice->DrawPrimitive(D3DPT_TRIANGLELIST......blablabla), i would just have to call DrawTriList(numPrimitives, sourceToVertices).

Now, should I put all these functions into a new class (such as CGeometry.cpp) and then call these functions by first creating the geometry object?

Or should I just separate all the functions into a separate file, not make them functions of any particular class and go with a functional approach? This way all I have to do is call the function without creating an object first.

From what I understand, the object oriented approach makes thing look neater and it probably would be easier to maintain the engine in the future. However this would mean I have to create a geometry object every time I required some rendering function. This would obviously mean some minor speed penalty and minor increase in complexity of the code written.

However going the functional approach means its easier to call the functions but it might increase the overall untidiness of the engine because I would then be employing different approaches at different places.

What do you gurus suggest?

#2 jkleinecke

    New Member

  • Members
  • PipPip
  • 27 posts

Posted 15 January 2007 - 07:56 PM

I'd like to start off by saying that the object oriented approach is definitely more powerful, but in the long run will be more complex and harder to understand (take a look at the Ogre source for an example).

The flaw that I see in your implementation is in how you pass your data to Direct3d. The graphics card wants you to call Draw*() as few times as possible, which means you'll have to combine some of your vertices. The solution is to create a Renderer that maintains a queue of all the vertices to render, and flush the queue to the graphics card once per frame. This is how nearly every advanced rendering engine that I've seen works.

So the big change that you'd need to make is instead of having your geometry class call DrawPrimitive directly, have it hand the data off to the rendering system.

To solve the problem of everything needing to be derived from Geometry to render I'd create a SceneObject class that represents the base class for every object in your scene. Inside the SceneObject class I'd create an aggregate Geometry/Mesh member that would send its data to the rendering system if it was valid.

#3 eddie

    Senior Member

  • Members
  • PipPipPipPip
  • 751 posts

Posted 15 January 2007 - 10:20 PM

Also, for something as low-level as your renderer device (whether it's OpenGL/DirectX) -- if you wanted to abstract it into a class, you'd probably want to only have one of them kicking around.

Then, you can probably queue up objects like jkleinecke suggests, directly to your renderer, of which there is only one.

That way you could build up bigger objects ("Player"), and just attach it to your scene/renderer/etc, and it would be all OO-like.

Feel free to contest me - it's just the route I'm going with my hobby-engine.

#4 sirfalas

    New Member

  • Members
  • PipPip
  • 22 posts

Posted 15 January 2007 - 11:37 PM

Hmmmm,

The queuing idea does sound better. So i guess I have to have a render queue and a render class that flushes that queue once per frame. Wouldn't this mean I would also have to have multiple-queues for different vertex types? Some for tri-lists, some for strips and so on.

Ok, this certainly got me thinking. Thanks for the suggestions and showing me the more optimal solution.

#5 eddie

    Senior Member

  • Members
  • PipPipPipPip
  • 751 posts

Posted 16 January 2007 - 05:09 AM

sirfalas: If you use the magic of polymorphism, you don't necessarily have to care what types you're dealing with.

You could have something named your 'RenderDevice' (the thin sliver that wraps D3D, or what have you), and then have 'TriStripQueue', 'TriListQueue', etc, etc all be descended from 'RenderQueue', store it in a datastructure on the RenderDevice, iterate through them and say, "Draw" (or have some sort of scene hierarchy manager that determines draw order).

Anyhow: I'm not saying what I'm proposing is 'perfect' or 'fastest' - but it's something very OO-like that should get you thinking.

#6 sirfalas

    New Member

  • Members
  • PipPip
  • 22 posts

Posted 16 January 2007 - 08:53 AM

All right eddie. Thanks a lot. I'll post my progress as I continue on the journey.

#7 TheNut

    Senior Member

  • Moderators
  • 1395 posts
  • LocationThornhill, ON

Posted 16 January 2007 - 12:20 PM

Here's a snippet from my own engine. The core component here is the CShape class. It's composed of points, texels, indices (optional), transformation matrix, and materials, all packaged in a data structure for quick and efficient rendering. Now I don't want to have to manually create shapes every time, so I added support for common primitives that can be constructed mathematically. The CDraw class acts as abstraction for the currently supported renderer, so I could render my shapes using OpenGL, DirectX, DirectDraw, or even software.

This is just how I do things, doesn't mean you should follow it. Have a look and see if it will help you construct your setup. I can tell you now that OO-design will make your life easier. It will keep your game code minimal and neat, so strongly consider it.

Posted Image
http://www.nutty.ca - Being a nut has its advantages.

#8 sirfalas

    New Member

  • Members
  • PipPip
  • 22 posts

Posted 16 January 2007 - 10:05 PM

Thanks for the class diagram. That is another thing I am aiming for, the part about abstracting the actual drawing code so that implementing openlGL support or something else would be easy.

Actually in my earlier design, the one where I wanted to move all drawing classes into a separate CGeometry class, I was going use a couple of #defines to help split the drawing code between the different graphics APIs. But it would have become quite messy I suppose.

I think what I shall do now is to look at my engine and see whether there are places where I could have gone with an OO approach. Then when I get to writing my drawing code, I will see if I can use a combination of the shapes/vertex queues/render queue method and also make it such that the render function renders as much vertices as possible within a set duration so that the control can be passed to the other parts of the engine such as sounds,AI or something.

I will post again on my final decision. Won't be that soon though. I have classes later so I guess I'll just work on this during my break (yea, I am a CS student).

Thanks once again, you guys have been most helpful and I appreciate it.

#9 eddie

    Senior Member

  • Members
  • PipPipPipPip
  • 751 posts

Posted 16 January 2007 - 10:26 PM

If there's anything I can suggest: don't get too over-anxious doing OO. I do it sometimes myself ("should I create an Int class?"), and it really gets you nowhere.

The end object of programming is generally to produce something (although since you're a student, perhaps learning OO is your goal). If you *are* attempting to produce something, keep those principles in mind, for certain: but don't get caught up over-designing. Make something, make it work, and if you decide later you need to make it more OO to make it fit your needs, do so. But it's not wrong if you don't have a 1oo% OO design from the start.

Just my pennies.

#10 sirfalas

    New Member

  • Members
  • PipPip
  • 22 posts

Posted 17 January 2007 - 04:23 AM

eddie said:

If there's anything I can suggest: don't get too over-anxious doing OO. I do it sometimes myself ("should I create an Int class?"), and it really gets you nowhere.

The end object of programming is generally to produce something (although since you're a student, perhaps learning OO is your goal). If you *are* attempting to produce something, keep those principles in mind, for certain: but don't get caught up over-designing. Make something, make it work, and if you decide later you need to make it more OO to make it fit your needs, do so. But it's not wrong if you don't have a 1oo% OO design from the start.

Just my pennies.

Thanks for the heads up. I am trying to learn how to create something like a game engine with being too platform specific or API specific. I was just doing a quick review on my engine and then I realize I have made some mistakes too.

For example, my engine right now is too Windows oriented. Another thing I am doing is the engine code is compiled to a .lib which is then used by my game code and then compiled into one big executable. But I also want to learn on using things like DLL. So right now I am going to do a bit of designing before getting into code again and find ways to encapsulate all platform specific code so that it becomes easier to maintain the code should I decide to switch platforms.

I realise that I am trying to accomplish a lot of things but I am going to take my time accomplishing them. I do not need to actually produce anything because this is my own self project. It isn't something that I am doing for school. Hence I can take my time coding this engine and also learn a lot by the end of it.

I am setting a realistic target of June for the engine.. This is where I would be able to get a basic engine working with 3d graphics support w/ collision detection and some other features. It won't be very advanced or anything. It certainly won't be the Linderdaum engine (unless of course I suddenly transform into a John Carmack).

I have also reserved the book Ultimate 3D game engine design & architecture (amazon link: http://www.amazon.co...e/dp/1584504730) from the library but I am not sure when the book is going to arrive.

I will definitely be asking questions in this forum over the next coming months. When I am done with it all, I will be releasing the source code too to get criticisms and advice.

Thanks and I will keep in mind not to overdo anything.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users