OpenGX was born during the port of Toy Wars from PC/PSP to Wii/GC platform. During the porting and due to the lack of OpenGL support on GC/Wii I was forced to decide whether to change all OpenGL specific code from Toy Wars (and isolate the platform-specific rendering code) or to implement the GL calls which I needed. The decision wasn't easy. Many render engines are based on a principle of platform independence: the engine makes use of generic render routines which fallback on platform-specific code. This principle is great specially for games which need high-end graphics and lots of shader stuff, but for simple games like TW OpenGL can be thought as a platform independent layer (as can be found on almost any platform). RenderingSo I decided to walk the long way because having an OpenGL wrapper could benefit a lot of future projects which use GL (Linux games?). Similarities between GL and GX Any OpenGL implementation project is tough by nature. The difficulties of understanding the underlying maths, the complex state machine and the render algorithms is huge, but sometimes there are cases in which we are not alone (and this is one of those). I'm talking of course on using external libraries to do the difficult stuff. This can be a software renderer package, an other render API, etc. and in the case of Wii we can use the GX library, which interfaces the console graphics card in other to produce 3D images. GX is pretty similar to the GL, so this is the secret for this project. That's why I call it a wrapper more than a library. First of all we have to look at what we need and what GX offers to us, that's what the following table tries to illustrate.
The GX API lacks (due to hardware limitations) of direct buffer access (in an easy or fast way), a complete GL-equivalent lighting (although it's quite complete) and a buffer/array rendering (only capable of indexed mode and with several limitations). We also we'll need to write a lot of matrix-math code (GU library has several code which we may use), because math code it's isolated from GX. GX design OpenGL is designed as a state machine: there are some calls which can draw stuff on screen and/or change the machine state. When it comes to GX it also has a little state machine which is composed by several GPU and CPU registers. Those registers work directly on hardware by selecting multiplexer inputs and that stuff, so we must think at low level. This GX simplicity lead to the decision of creating a software state for the GL machine so that every state-related stuff is kept on software (memory) rather than on hardware registers and the state is propagated when appropriate. The state can be described in some main areas: matrix transformation stack, lighting parameters, enable/disable flags, render data and texture.
Rendering is the most difficult part, as we have to produce the very same output as a correct OpenGL implementation. The nature of Wii hardware is something similar to the early shading models and it's very lowlevel but, on the other hand it's very customizable and allows complex operations not present in GL API (without using shaders, of course!). To be continued... |