Tag Archives: read-the-other-guy’s-stuff-it’s-better-than-mine

Orientation Matrices for Cube Mapping

I may well be totally wrong, but I don’t think I’ve ever successfully Googled a useful set of orientation matrices for cube mapping. As you already know, a cube map is a set of six images which, when projected on to a cube, provide a decent simulation of a spherical texture map. Two of the most common modes of usage are to provide real-time reflections on the outside of an object (by repeatedly making a map of the environment surrounding that object and then projecting that map back on to the object, as in the reflections you see on e.g. the cars in racing games), and to provide a skybox.

Skyboxes are usually either pre-rendered (pretty but boring), or done through rendering atmospheric scattering for your scene and then projecting some celestial bodies like the moon, stars etc (pretty but computationally intensive). An additional bonus of drawing your own skyboxes is that you can then use them for doing environment/ambient lighting for objects in your scene, either by working out the spherical harmonics (neat but I’m far too dumb to have ever wrapped my head around it) or by techniques which involve downsampling the cube map. This gives you ambient light which changes colour depending on the angle of the sun basically for free.

Therefore cube maps have multiple advantages for rendering your skybox and lighting:
1) render once and reuse (you can make this once per frame, or less often depending on how dynamic the sun is.)
2) you can do atmospheric scattering at a surprisingly low resolution and still have a decent looking result. You basically have to do your atmospheric scattering in the fragment shader if you want to use a “spotlight” effect to render the sun, which gets very expensive in terms of fragment power. I actually do both the sun and the moon, which is even more expensive, so lowering resolution is a major speed-up here.
3) basically free specular and ambient environment mapping of the sky on to everything in your scene. You can either go the very expensive route for downsampling, or just mipmap the thing and get 90% of the quality for 10% of the effort, and hardware acceleration.
4) if you’re blending your scene into the sky for a distance fogging effect – well, you just got the source for that as well!

This is where you usually run into a brick wall because figuring out the correct orientation matrices for rendering the cube map is a pain in the backside. What you’re going to be doing in the end is rendering a box around your camera and texture mapping the cube map on to the inside of the box, which will then act as the skybox. You can simplify this by not applying any rotation to the skybox, so that it’s aligned with the x, y and z axes. Therefore what you need to do is figure out how to make the camera look in six directions: +x, -x, +y, -y, +z and -z. You could do this with gluLookAt, but that’s a whole heck of a lot of lines of code just to look in the direction of an axis. Better to just know what matrices to use: see below. (I’m weird and use +x = east, +y = north, -z = up i.e. inverted right-handed axes.)

Continue reading Orientation Matrices for Cube Mapping

Two dimensional C arrays – care and feeding

C arrays are a little hard to grasp by those of us raised on the Cocoa API, because most of the really convenient stuff (like an array object being able to keep track of its own size) just isn’t there in straight C.  I went into using C arrays, in order to interact with OpenGL, with absolutely no knowledge whatsoever (a common theme of this site!) of how to even use malloc.

Why would you want to use two-dimensional arrays anyway?  In my case, although I’ve written a fair few functions where e.g. a two-dimensional grid of points is mapped to a long one-dimensional array, and I’ve simply remembered what the dimensions of the grid were when accessing the information, sometimes this is simply too much for my poor brain to understand. In this situation I’m forced to represent things as a multidimensional array in order to get the concepts down in a way which works.  I might, therefore, have one array which represents all of the values of the x dimension, containing a series of arrays which represent the y dimension; so the point in the grid at (5, 13) is retrieved by getting the 13th value from the 5th subarray in the parent array.

Fortunately there are people who are much cleverer than me who have come up with a way of handling two-dimensional C-arrays.  Unfortunately I have forgotten the attribution.  However, I had to go forum-diving to find this and I think that it might be helpful for us inexperienced types to have a more easily-searched solution.  If I find the original source again, I will provide a link.

One similar implementation was found here

//make a 2d array of floats
 
float** Make2DFloatArray(long lengthMainArray, long lengthSubArray) {
    float **newArray = (float **) malloc(lengthMainArray * sizeof(float *));
    *newArray = malloc(lengthMainArray * lengthSubArray * sizeof(float));
    for (int i = 0; i < lengthMainArray; i++) {
        newArray[i] = *newArray + i * lengthSubArray;
    }
    return newArray;
}
 
//release a 2d array of floats
 
void free2DFloatArray (float **arrayToFree) {
    free(*arrayToFree);
    free(arrayToFree);
}
 
//access a value in the 2d array
 
float theFloatIWant = my2DFloatArray[indexInMainArray][indexInSubArray];

Hello world!

Those (few) of us who got our start in graphics coding in OS X have probably noticed a few wrinkles in the process:

  • Apple’s OpenGL/GLSL implementation is always a year or two out of date
  • OpenGL tutorials on the internet are always 5 years out of date, and actually written for DirectX anyway
  • Books on the subject cost £50 for a hard-to-search collection of stuff you already knew which is inevitably dependant on some library or other (which they don’t explain) to do all of the magic
  • GLSL is, as Shamus Young so rightly pointed out, folk knowledge
  • As soon as you want to interact with OpenGL, you have to leave your cosy Cocoa haven and delve into straight C – which is moon language to those of us raised on NSExtremelyVerboseFunctionNameWithAttributes:

Hence I’ve made this site to put up some of the more obscure – or so obvious nobody has ever bothered to put up a working implementation for us newbies to pore over – code which took me hours of googling to figure out.  It’s so much easier to learm by breaking a working implementation than to mess about with something originally written in a different language which might not even work in the first place.

In the process, I’m going to build one of those procedural environment things.  This was going to be a simple 2D Artificial Stupidity project, but the graphics sort of took over.

There will be bugs.  There will definitely be memory leaks.  Much of this stuff will be apocryphal, or at least wildly inaccurate.  Your video card will probably crash at some point, and I’m definitely not going to buy you a new one.

Enjoy!