About 3D APIs

There are two main 3D API available today: Direct3D and OpenGL. I won't enter in a debate to know whichever is better. They both provide an interface to the same underlying hardware, with the differences being the quality and simplicity of the interface, and the implementations (the drivers), rather than the feature set.

On one hand you have Direct3D, pushed by Microsoft, with a rather nice interface (in its 9th and 10th versions), but suffering from a severe draw call issue. Draw calls on certain Direct3D platforms force a kernel context switch, which has an ultimate performance cost. The other downside is that the API tends to change a lot from one version to the other, which isn't too nice since it means rewriting a lot of code to take advantage of any new version in an existing engine. It's available on Windows and the Xbox 360.

On the the other hand you have OpenGL, lead by the Khronos Group (And formerly by the Architecture Review Board [ARB]), and exist in different flavours, such as the ES (Embedded Systems) version, or the standard OpenGL for workstations.

OpenGL 2.1 has many functions, and many ways of doing the same thing, making its implementation difficult, and the engine writer's task uneasy, as there is a need to look for the optimal path, which evolves with time and new extensions. Or new hardware, since extensions are meant to make hardware features available in the API, without breaking the existing interface.

Hopefuly, OpenGL 3.0 (Codenamed Longs Peak) is just around the corner, with a completely new streamlined interface, sometimes referred to as "Lean & Mean". It's available on Mac OS X, Windows, the PS3 (as an OpenGL ES-like API), and the Wii (as an OpenGL-like API).

There's the option of deciding to follow one of the API and use its strengths in the engine. While it allows to take advantage of specific utility features provided by the chosen API, it also means restricting the systems the engine will run on, and so the number of potential users of the engine.

A more interesting approach, is to choose neither of them, and to write an abstraction layer which will hide all API specific code inside a module, making the engine API agnostic. With such a layer, the engine will be able to use the best API for a given system, to ensure high performance. The drawback of having an abstract renderer interface is that it must target least common denominator of the APIs it'll be hiding, or the engine will need some tweaks to target some platforms. Still, since the code is nicely encapsulated, changes, even engine broad, will be much easier to deal with.

Since, for various reasons, someone using the engine might want to ship more than one 'Renderer' (the API specific module), it's a good idea to make it a plug-in, in Windows' naming it'll be a DLL (Dynamic Linked Library), for unix people it'll be a so (shared object).

Part One Closedown

That's all for this introduction article, hope you enjoyed it. Next time, I'll talk about scene management, encompassing the three updating, culling and rendering processes, which are the beginnings of tying some key concepts together as far as a rendering engine goes.


If you'd like to comment on this article, you may do so here.