Software 3D Algorithms Revisited

This will be a very nerdy blog post describing some technical aspects of Spandex Force. Sorry in advance.

Many moons ago I complained about BlitzMax and 3D, and described how I solved that problem. Well, it turns out that I’m a moron and the solution described didn’t solve anything at all. This is essentially what I wanted to acheive:

Well, when I switched to a more detailed texture everything got jagged and crappy. Which I should have foreseen if I hadn’t felt so proud of myself for working around my limitations. I know, I suck. Anyway, I needed a better solution.

Someone in the old post mentioned that you can do 3D in BlitzMax by using textured polygons, but I don’t know if he’s ever tried. Using the common textured poly functions result in affine texture mapping, which is completely useless for depth effects. So, the only solution left was to go for proper 3D.

This is surprisingly simple in BlitzMax as long as you know how to do it. (Duh!) All you have to do is set up the projection matrix properly, and then do the primitive drawing commands. I won’t paste the dull code here, but it involves some trigonometry and a glFrustum() call (for OpenGL). That took care of the background itself.

But wait, that’s not all! What about the little objects on top of the background? Well, I wanted a billboard effect (the images should always face the screen) so I could either do a lot of rotations and draw everything in 3D…or draw the icons in 2D afterwards. I chose the latter approach and was thrilled when I noticed that OpenGL has a function called gluProject() which would let me find the screen coordinates from 3D space coordinates. Yay!


All for this little minigame!

Time for a short interlude. “Why are you mucking around with OpenGL like this,” the eager reader asks. “Isn’t DirectX the standard for Windows?” Sure it is, but I also want my game to run on Mac and Linux. So in my first approach I chose an OpenGL-only solution. But, as the experienced game developers out there could have told me, that just wouldn’t do. OpenGL works most of the time, but there are severe compatibility problems with out-of-the-box XP and Vista installations!

I was aware of this limitation, but I just didn’t know how to get around it. See, the magical gluProject() function has no corresponding function in DirectX. After a lot of messing around with matrices I managed to make the DirectX projection matrix similar to the OpenGL one, so the background could be drawn in both modes. But I still had no way to draw the icons correctly. I tried lots of various interpolative methods but everything looked pretty crappy.

Then it struck me like Mjölner from a clear sky.

In my old blog post I ranted about how old methods can be utilized to good effect even today, and there was one old method that I had overlooked. Can you see what I’d missed?

Lookup tables!

When running the game in OpenGL I could create a lookup table for the projected X and Y coordinates of the icons. This table could then be used for both the OpenGL and DirectX versions of the game to create identical results for the 2D icons. It worked perfectly, and this enabled me to have DirectX as the default renderer in Spandex Force from v1.1 and onwards.

Many times I thought about skipping the Catch ‘n Match minigame completely in order to have DirectX support, or shipping the game with compatibility problems. I’m happy that things worked out in the end!

Leave a Reply

Copyright © 2009 KarjaSoft