Home‎ > ‎GC/Wii dev‎ > ‎

OpenGX

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).
So 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.

  GL GX
Matrix stack and operations
 X 
Transformation operations
 X X
Immediate mode render
 X X
Buffer render mode
 XLimited
Blending
 X X
Buffer access (Z, Alpha, Color)
 X Limited
Texturing
 X X
Lighting
 X Limited

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.

  • Matrix state: The matrix transformation stack is kept in memory and all the operations are performed by the CPU. Just before rendering the matrices are copied to the GPU registers.
  • Lighting: The lighting is kept on memory and during rendering the right pipeline parameters and stages are chosen to produce a lit (or unlit) result.
  • Enable flags: Every enable/disable bit is propagated to hardware before rendering or any other operation that may be affected (buffer clearing for instance).
  • Render data: The render data (data pointers) are not used by hardware since the GX API only accepts direct data (immediate mode). GL immediate mode is emulated by using an intermediate buffer and using pointers.
  • Texture: The most tricky part. The data (pixels) is stored in memory as well as other GX control structures. Texture operations are flushed immediately so textures are always available and do not need any update. This is good because textures are usually loaded at start and used a lot during the renderings.
Rendering

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...