Thoughts on renderer 'classes'

Started by
13 comments, last by _the_phantom_ 20 years, 5 months ago
While reading the OOP in games thread below someone mentioned that doing OOP doesnt always mean using classes, and this tripped off a little thought in my head regarding game writing. Most ppl will, as they progress, make a renderer class to deal with all the rendering. However, what if you didnt do that, what if instead you placed all your rendering calls into a namespace instead of a class? From first thoughts there doesnt seem to be any reason why you couldnt do this and have it work just as well. Any infomation you want hidden from the calling functions can be hidden in an anon namespace inside the file. The same can be said of function you dont want the outside world to see as well. So, much like a class you are only exposing the interface you want the other functions to use/see and hiding the rest of the system behind it. Any thoughts/comments on this idea? Do you think its workable with any advantages/disadvantages i've not seen? (I've only just thought this up so i might have missed a few issues) [edited by - _the_phantom_ on October 22, 2003 11:07:30 PM]
Advertisement
a lot of people (myself included) design their renderers to be pluggable, in so far as you have an abstract base class and then perhaps an OGL renderer or a D3D renderer. Having functions in a namespace wont give you that functionality at all.

i think a renderer is one of those things that does belong in a class, but things like math functions dont.
-jonnii=========jon@voodooextreme.comwww.voodooextreme.com
Seeing as I wrote that comment in the other thread, it shouldn''t come as a surprise that that''s the path I take.

It''s just that, I prefer rnd::renderScene() to something like CRenderer::GetSingletonPtr()->renderScene() ... and don''t laugh at that example, because it''s exactly the kind of code that''s used in the glorified Enginuity set of articles (not to downplay the importance of the articles, I just dislike the syntax).

Now, maybe for large commercial projects, having base classes might be a smarter thing to do. I can see the benefit there. But does it have to be "inheritable" to be re-usable? I can''t see why you can''t take a set of functions and add to them.

- Ben
- Ben
greetings from Carmack f
http://www.8ung.at/basiror/theironcross.html
With an abstract base renderer class you can support multiple rendering apis by creating an instance of the renderer class you wish to use. This inherited renderer class can even be created by a dynamic library, this gives even more flexibility. Quake 2 did this, same for half-life.

I agree with you that the interface for that singleton is ugly:

CRenderer::GetSingletonPtr()->renderScene()

I wonder why they don''t simply return a reference to the singleton object instead of a pointer. I also wonder why they didnt bother making at least a definition of the renderer to hide the singleton calls, or even create a global pointer to it.
Personally, I find that singletons are a waste... You just have to create one instance and avoid creating others, works fine.


Looking for a serious game project?
www.xgameproject.com

Looking for a serious game project?
www.xgameproject.com
quote:Original post by jonnii
a lot of people (myself included) design their renderers to be pluggable, in so far as you have an abstract base class and then perhaps an OGL renderer or a D3D renderer. Having functions in a namespace wont give you that functionality at all.


Ok, but look at it this way, you've still got a common interface, yes?
Its just the underlaying system which has changed the data still has to be passed down the same way, so you could still have your class under the namespace, via a factory to select the right class to create, but only have the name space functions avalible to the outside world

namespace mygfxsystem{   namespace   {       RenderClass * myrender;        // any other private data required   }   void Draw(Object *myobject)   {     RenderClass->Draw(myobject);   }}


Ok, i admit that its a simple example, however given that the Draw call should be inlined you arent losing anything at all vs the current system speedwise but i just feel that mygfxsystem::Draw(data); is easier to work out then CRender::GetRender()->Draw(data);

Any yep Basiror i do realise that this does smack somewhat of the C-style way of doing things, however now i think about it does make as much sense conceptualy as objects.

Certainly if you only plan on supporting one API this could be an effective method (unless i can spot any serious flaws in this method I plan to use it with the OpenGL engine i'm planning to write).

Edit:
In response to the above post, you dont even really need a singleton, as the rest of the system doesnt need to see anything beyond the namespace (which you cant create an instance of anyways) and that namespace will control all access/creation of the gfx objects


[edited by - _the_phantom_ on October 23, 2003 2:35:21 PM]
In the same vain tho you could just use static methods and go something like

CRenderClass::Draw(Object o);

I dont see the point of hiding things in namespaces, and it doesnt stop people from using the child namespace and calling the methods directly...

-jonnii=========jon@voodooextreme.comwww.voodooextreme.com
quote:Original post by _the_phantom_
Most ppl will, as they progress, make a renderer class to deal with all the rendering.
However, what if you didnt do that, what if instead you placed all your rendering calls into a namespace instead of a class?

From first thoughts there doesnt seem to be any reason why you couldnt do this and have it work just as well.
Any infomation you want hidden from the calling functions can be hidden in an anon namespace inside the file.
The same can be said of function you dont want the outside world to see as well.
So, much like a class you are only exposing the interface you want the other functions to use/see and hiding the rest of the system behind it.

Any thoughts/comments on this idea? Do you think its workable with any advantages/disadvantages i''ve not seen?
(I''ve only just thought this up so i might have missed a few issues)


Because then you can''t change your rendering type at runtime. The concept of having a base type is that the two different renderers (IE an opengl implementation and a direct3d implementation) can be created and switched at runtime and just refered to using the same pointer. This way, you can create a new renderer type (inheriting from the base type) and you can switch between it and other renderers at runtime without having to change any other code. If you wanna take it further, this even allows you to completely put your rendering code into separate DLLs (which create instances of child renderers) and you main executable code has to be changed despite you being able to make an infinite amount of renderers, all which can be switched between at runtime.
quote:Original post by jonnii
I dont see the point of hiding things in namespaces, and it doesnt stop people from using the child namespace and calling the methods directly...


it does if they are anon namespaces as they arent viewable outside of the namespace.

And i cant help but thing there is a flaw with the ''make the functions static'' idea, but atm i cant put my finger on it (blame the vodka).. if i can i''ll come back to that point..

quote:Original post by Polymorphic OOP
Because then you can''t change your rendering type at runtime.


errm, yes you can.... see my example above where you have an anon namespace internal to the mygfxsystem namespace.
With either method you need a factory system to make the instance of the correct class (mygfxsystem::init("OpenGL") and off the top of my head i cant think how you''d do it for a singleton system), and the class would still derive (sp?) from a common base class but would be totaly hidden from the external world.
You now have no global objects in play as the render is hidden away inside a namespace and everything just seems a bit cleaner to my way of thinking.

// following on from above#include "mygfxsystem.h"int main(){    mygfxsystem::init("opengl");  // init the renderer system for opengl    // other code}void myobject::somefunction(){    mygfxsystem::draw(mydata);   // ask the gfx system to draw your data    // other code}


(again, my example might not be that great but you get the idea)

This topic is closed to new replies.

Advertisement