Archived

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

Promit

I jsut found one of the worst possible ways to build a game engine

Recommended Posts

I was curious, so i started by making a pure virtual object class with only a HRESULT Render() and a IDirect3DDevice8*. THen I derived a SpriteObject with a matrix and axes, then a camera from that....etc. Do you know what it is like trying to find the definition for a function that is implemented 5 levels of inheritance above the class you are writing? Remember Inheritance is good...to a point. Try not to use more than 3 levels, ever. ----------------------------- The sad thing about artificial intelligence is that it lacks artifice and therefore intelligence.

Share this post


Link to post
Share on other sites
I''m not going to argue your findings, and certainly in a game engine you need all the performance you can get. But in a less demanding app the number of inheritance levels doesn''t produce such a noticable impact. Yes, finding functions w/o source docs is annoying, that''s why I generate docs constantly when writing a framework or an engine.

Share this post


Link to post
Share on other sites
The level of inheritance does not change the speed of the application. Virtual function resolution has constant cost. Of course, writing more code will make your software slower, but it will not be because of inheritance.


Share this post


Link to post
Share on other sites
I''m not a pro when it comes to OO analysis and design, but I think there is something wrong when you derive a camera from a sprite object(?).

But then again, it could be just me...

Share this post


Link to post
Share on other sites
It was a little weird in that sense too. WHat the logic was:
CObject provides the HRESULT Render() and a bit of pointer management. The Render is pure virtual.

CSpriteObject implies an object which has a matrix in the world and therefore is an actual moving entity.

CCamera is a CSpriteObject with a lot of calculations for movement, about 20 short functions to just make life easier.

Because the code for a game object was so similar to CCamera, i derived CGameObject from CCamera for movement/rotation functions then added functions to work with a CD3DMesh provided by d3dfile.h.

It was really working well, but just too many levels of abstraction to make sense.

Share this post


Link to post
Share on other sites
It''s not the number of levels of abstraction that make it hard to follow. You have to make sure your inheritance tree makes sense, or any program will be hard to follow.

---
Make it work.
Make it fast.

"Commmmpuuuuterrrr.." --Scotty Star Trek IV:The Voyage Home

Share this post


Link to post
Share on other sites
I agree, it''s not the many levels of inheritance, but your design. A Camera is not a type of Sprite, so that kind of invalidates the idea of subclassing. What you probably should have done is used an abstract interface to represent a renderable object, CRenderable, and given it a single virtual function called Render(), then derive your Sprite and Camera (directly or indirectly) from CRenderable.

Share this post


Link to post
Share on other sites
Another thing about inheritance (and virtual functions) that many people overlook is that it makes effectively testing your code harder to do. Functions calling virtual functions or working with pointers to base classes don''t know for sure what the path of code execution is when they call them. So you can no longer be sure of the exact execution path within your function as soon as you start calling virtual functions. Even if you do have access to all the functions that could possibly be called now, someone could add a new derived class later and your code would end up calling it. The same problem applies for any kind of function pointer system, obviously, but normal use of function pointers rarely gets as widespread as with virtual functions.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost ]

Share this post


Link to post
Share on other sites
quote:
Original post by Promit
I didnt even mention performance...whered that coem from?


You did not, but jim_ross did. Your comment about inheritance are right. And so are Kylotan.

My rule of thumb is virtual functions are only for customization, and so the functions to implement are usually simple as most the work is (and should be ) done in the base class(es).

I would not attack your problem the way you are doing it right now. I would have 2 separate class :

1. a Sprite Class that gives access to all the properties of a sprite(image, size, whatever you need). The sprite class could still derive from an Object class that contains the current position and orientation.

2. A Sprite Renderer that is part of a renderer module.

The instance being rendered does need to be aware of the mean used to draw it.


I find this to be cleaner and easier to work with.

Share this post


Link to post
Share on other sites
Sprite implies animation, which is not what your sprite class does. A camera isn''t a sprite, but it is a node in the scene graph, which is what your sprite class appears to actually represent.

Starting with one pure virtual base class is the SI mindset; it''s not necessary with MI. A common base interface is often useful, but all the other interfaces don''t need to derive from it.

Several commercial engines use a virual render function that is called for objects such as (a real) CSprite, CTerrain, etc...

Share this post


Link to post
Share on other sites
Doesn''t anyone remeber the "Is A", "Has A" relationship lecture from the early college programming classes.

A Car "has" 4 tires.. so it doesn''t make sense to inherit a tires class from car class. The Car Class should contain 4 "tire" class objects.

A car "is" an automobile so is a truck, or an RV. So it makes sence to inherit a "Car" class from an "automobile" class.

Share this post


Link to post
Share on other sites
I''m waiting on the "Is a"/"Has a" lecture when I do my first OOP unit this coming semester, but wouldn''t an Automobile have -no- tires, and you''d leave it up to the derived classes to decide how many tire classes they''d include?

Share this post


Link to post
Share on other sites
It all depends on what you want to do. If you want to force the automobile to have 4 tires, go with it, but you can leave it up to the one who will inherit the class. Will an automobile run if there is no tire? probably not, so you''d better put the tires there. If the inherited class needs more (or less) tires, it can overload the methods. (maybe with some tricky stuff, it depends on how it''s designed at the begining)

Share this post


Link to post
Share on other sites
I was aware that i screwed up the Is-A relationships pretty badly, and the naming as well. It was a 2 hour long experiment in high levels of inheritance, to see just what the result would be. It was terrible.

Ive been doing research in interfacing and seeing what type of interface and setup works best. When that''s totally done, I''ll put all the code into a nice format.

The relationships are going to stand at CObject-CSprite-[Specific Object] i think. THe camera class is going to rotate and move somewhat differently from world sprites. Each camera will store it''s own matrix. The pipeline class will have an internal pointer to the camera that is to be used, and use it''s matrix for the view transform. The pipeline will also manage the top of the my frame-based hierarchy, and will allow direct access to the hierarchy if one needs it. There''ll be a mesh class in Specific object, which will probaly manage either a CD3DMesh(part of DX Common files), or directly deal with an ID3DXMesh. Not totally sure yet. Or i could use a union. But so theres the general break down.

Comments?

-----------------------------
The sad thing about artificial intelligence is that it lacks artifice and therefore intelligence.

Share this post


Link to post
Share on other sites