Game Engine Design: The Renderer (C++)

So what exactly is a Renderer? In the design of a game engine, the job of the renderer is to handle all aspects of a game’s rendering, whether it be in 2D or 3D. More specifically, your engine talks to the renderer when you want something to be displayed on screen.
In code, you want to develop a Renderer class that basically bridges your game with the graphics API that places images onto the screen. In a 2D engine, the renderer should be able to do simple things such as displaying rectangles textures (also known as “quads”), clearing the screen, and such. In a 3D engine, the renderer handles such tasks as rendering triangles, managing vertex and index buffers, and possibly matrix stacks.
The most platform-dependent portion of any game engine is the renderer. The renderer must talk to the specific operating system’s graphics API in order to display the game onto the screen. Each OS/graphicsAPI has their own way of rendering as well as setting-up/shutting-down the rendering subsystem.
If you are trying to make your game engine portable and more platform-dependent (which is recommended), it is wise to have an IRenderer interface class which other renderer classes can derive from. It abstracts the methods that all rendering systems should have and places in snugly within an interface.
For example, whether you want to use OpenGL, DirectX, Win32GDI, or whatever graphics API, you can create classes RendererOGL and RendererD3D which will define all the virtual functions in declared in Renderer:
class IRenderer { public: IRenderer(); virtual ~IRenderer(); // Binds your window to the Renderer virtual void Init() = 0; // Shutdown all systems that Renderer uses virtual void Shutdown() = 0; // Must overload in your derived Renderer classes virtual void Render(..) = 0; virtual void ClearScreen() = 0; // ...other methods }; class RendererOGL : public IRenderer { public: RendererOGL(); ~RendererOGL(); // Initialize OpenGL void Init(); void Shutdown(); void Render(...); void ClearScreen(); ///... };
The game talks to the Renderer thru the IRenderer class and will call the appropriate Renderer’s methods since the functions are virtual. The methods of the derived classes will encapsulate all the code that is specific to the graphics API.
To use a specific renderer, we use a polymorphic constructor:
// Polymorphism! IRenderer *pRenderer = new RendererOGL(); pRenderer->Init();
Suppose you want your game to be portable on several platforms: PC, Mac, PS3, Xbox, etc. Using this method allows you to abstract all the rendering functionality away from the core of your game engine. And if you ever wanted to switch your game engine’s renderer to another graphics API such as Direct3D, you can simply switch the IRenderer to “point” at another implementation:
//IRenderer *pRenderer = new RendererOGL(); IRenderer *pRenderer = new RendererD3D(); pRenderer->Init();
As you can see, switching an entire rendering platform is merely a line of code. And if you strive for platform independence in your game engine’s rendering subsystem, your game will be able to survive beyond the lifetime of it’s operating system.
Comments ( 1 Comment )
Awesome! This is exactly what I’ve been looking for! What an excellent idea! However, the hard part is implementing it. But thanks!





