Porting OpenGL games to the Nintendo Wii: cho.mono
More than one year has passed since my last blog post, and I'm a bit ashamed to confess that today's post is again about porting games to the Nintendo Wii — I always tell to myself that I'm soon going to move to something else, possibly less geeky than this (by the way, there is something else I could write about, but I'll leave it for another post!), but the problems posed by porting games to an old console are just way too stimulating, and my brain gets attracted to them in a way that I cannot resist.
Anyway, have you ever heard of OpenGX? It's a project aiming to write an OpenGL driver for the Nintendo GameCube and Wii's GX API: while these consoles have good (at the time, at least) 3D capabilities, they were programmed via an API not even remotely close to OpenGL, so back in 2013 one developer by the name of David Guillen Fandos started a project to investigate the possibility of wrapping the GX API in OpenGL. The project was abandoned after reaching a very basic state, but it's author was diligent enough to write a PDF file describing its design and some implementation details. Having bumped into this document, I was inspired by it and felt it was a pity that such a project had died -- especially given the fact that this didn't happen because of some technical infeasibility. So exactly one year ago, in the spring of 2024, I picked it up and tried porting the game BillardGL to the Wii; I had to add quite a few things to OpenGX, and adjusting the lighting pipeline, but after less than one month the port of BillardGL was ready. In the following months, I ported several other OpenGL 1.x games, gradually enhancing and expanding OpenGX, until I got most of OpenGL 1.4 supported.

Should I have stopped there? Probably. Because indeed the Wii's GPU, despite allowing a good degree of complexity in setting up its shading engine (called TEV, Texture Environment), does not support the modern GL shading language, and trying to have the CPU compile the shaders into something that GX could understand is a task doomed to fail, in part because this would eat up all the computing power, but especially because there simply isn't an algorithm that could translate GLSL into GX commands. Is this the end of the journey then?
Well, the fact that OpenGL 2.0+ shaders can not be machine-translated into GX
commands does not mean that this task is impossible: we've still got the human
brain to use! The idea is the following: let the deveoper who is porting the
game write the GX code corresponding to the GLSL code by hand. Saying it like
this might feel like this is no better than saying “Just port the whole
rendering backend to GX!” but as a matter of facts, there's a big difference:
with this approach all the rest of the OpenGL code stays untouched, and the way
I have design this shader substitution to work in OpenGX allows one to keep
the GX code isolated in its own source file, without having to change a single
line of the program, save from adding a line near the beginning (in main()
,
typically) to install the GX hooks. This means that your program will still
call glUniform*()
, glVertexAttribPointer()
and so on to setup the rendering
pipeline, but when the program will get to execute glDrawArrays()
OpenGX will
pass control to the hooks previously installed, which will receive the uniforms
and the attributes, and setup the pipeline using GX commands. It might seem
complicated, but it really
isn't
(well, if you can deal with the GX API), and it's even more efficient than the
fixed pipeline of OpenGL 1.x, since here the GX commands are reduced to the
bare minimum required by the shader, whereas in the fixed pipeline we have to
follow predefined steps.
The first (and for the time being, the last) OpenGL 2.0+ game I've ported to the Wii is chro.mono, a nice puzzle game from 2013 whose source code has been released in 2021. It uses the FBO feature from OpenGL 3.0, so I had to implement it in OpenGX as well. I'm quite satisfied with the result, not only because the game runs at 60 FPS, but because it shows how rather complex shaders (the game has more than a dozen of them) can be realized in GX; to tell the truth, in couple of cases I had to implement the fragment shader by converting its code to C and drawing to a temporary texture, but luckily these shaders are used only during program startup to draw to an FBO and don't negatively affect the game performance. You can download it from here.
Summing up, if you get really bored and would like to engage in something unusual (read: useless), porting games to older consoles would definitely keep you active for some time. Unfortunately there aren't that many OpenGL games which are open source, so the candidates for porting are not that many (by the way, feel free to suggest in the comments — well, not for me, but maybe someone else will do it).