OpenGL Coordinate System and Matrix Math

Written by Sean R. Owens (sean at guild dot net). Share and enjoy. http://darksleep.com/player
For other fine writings on Java and other subjects, check out notablog at http://darksleep.com/notablog

These are a summary of my notes on learning OpenGL and associated matrix math, that I prepared for a friend of mine. They may be of some use to you.

Something thing that confused the HECK out of me for a long time is OpenGL's coordinate system. In general when I think of x/y/z coordinate systems, I start with a flat piece of imaginary paper with x and y on it, like we had in math class. Then I lay that flat in front of me on the table. X goes from negative on the left to positive on the right, Y goes from negative towards me, to positive away from me. I add a Z dimension that ends up being 'altitude', i.e. negative Z is towards the floor, positive Z is towards the ceiling.

This is _not_ how OpenGL works. Buh. In OpenGL, take that piece of paper with X and Y and tape it to your monitor. X and Y are the same as before. Now add Z as negative going towards you and positive going away from you.

It's easy enough to grasp once you realize your assumptions were wrong, but there's still one gotcha. If I took that paper taped to the monitor and laid it flat on the table, the coordinate system it still wouldn't match my initial assumptions. The difference would be that in my assumed coordinate system, up is positive Z, while in OpenGL's assumed coordinate system, down is positive Z. OpenGL is a "Left Hand Coordinate System" and my assumed coordinate system is a "Right Hand Coordinate System" and never the two shall meet.

Here are my notes to myself from some time ago;

Thu Dec 18 21:04:06 EST 2008

One of the things that's been causing me confusion is the fact that OpenGL uses a Right Handed Coordinate system. I read this a while ago but the ramifications didn't sink in until just now.

The easiest way to explain Left Handed/Right Handed coordinate systems is to imagine holding your hand (your left, for this example) like you are pretending it is a pistol. Your thumb points up, your forefinger points forward, and then you stick out one or more of the rest of your fingers to point toward your other side, toward the right. Your thumb corresponds to one axis, your forefinger to another, and the rest of your fingers to the third. (It doesn't matter which axis any particular finger corresponds to.) If you use your left hand, it's a left handed coordinate system (LHS), if you use your right, it's a right handed coordinate system (RHS).

What I'd forgotten was, you can't get from a LHS to an RHS (or vice versa) by any combination of rotations. I.e. if you had in front of you a model of a LHS built from wooden rods, with X, Y and Z axes painted red, green, and blue, and you had a similar model of a RHS, you can't get them to match up completely no matter how you turn them over or around. You'll always end up with at least one axis going in opposite directions, i.e one model will have positive X pointing in one direction, the other will have positive X pointing in the opposite direction. If you rotate the model to make the LHS X match the RHS X then you'll just end up with the same problem with the Y or Z axes.

There _is_ a way to 'fix' it however. The only way you can convert from LHS to RHS is by 'mirroring', which isn't possible in the real world, but luckily, is possible in the math world;

http://www.opengl.org/resources/faq/technical/transformations.htm

9.150 Can I make OpenGL use a left-handed coordinate space?

      OpenGL doesn't have a mode switch to change from right- to
      left-handed coordinates. However, you can easily obtain a
      left-handed coordinate system by multiplying a negative Z scale
      onto the ModelView matrix. For example:
This article has some basic stuff on the coordinate system if what I just copied above doesn't make sense.

http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx

Also, for 3d in general and for OpenGL in particular, you're going to end up bumping up against matrix math a lot. I'd forgotten most of what I learned way long ago and it wasn't all that much then, but thankfully you don't really need to understand it all that well. You just have to use it. And not get frightened/confused by the terminology. Most 3D and OpenGL programming tutorials of any sort end up having a subsection on matrix math, or just assuming you already know it.

So just skim over these to get a feel for it, don't worry if it doesn't immediately sink in. Skim over the first set at least, real quick, you can come back to these later for review;

This one was pretty good - don't be fooled by the geocities hosting; start with the 2D and work your way up.

http://www.geocities.com/SiliconValley/2151/math2d.html
http://www.geocities.com/SiliconValley/2151/math3d.html
http://www.geocities.com/SiliconValley/2151/matrices.html

also;

http://www.lighthouse3d.com/opengl/maths/

I thought this tutorial was a fairly nice, as far as it goes, intro to matrices and 3d and transformations;

http://triplebuffer.devmaster.net/file.php?id=5&page=0

This is a tutorial on matrices with more of a slant towards OpenGL;

http://www.sjbaker.org/steve/omniv/matrices_can_be_your_friends.html

One thing that I've run up against is being quite confused about 'homogenous' coordinates/matrices, cause it's mentioned quite often. This thread explains them, well enough at least for our purposes;

http://www.devmaster.net/forums/showthread.php?t=2092

more;

http://www.riemers.net/eng/ExtraReading/homogenous_matrices.php

also;

http://en.wikipedia.org/wiki/Homogeneous_coordinate_system

A homogeneous coordinate system is a coordinate system in which there is an extra dimension, used most commonly in computer science to specify whether the given coordinates represent a vector (if the last coordinate is zero) or a point (if the last coordinate is non-zero). A homogeneous coordinate system is used by OpenGL for representing position.

http://en.wikipedia.org/wiki/Homogeneous_coordinates#Use_in_computer_graphics

Use in computer graphics

    See also Transformation matrix#Other kinds of transformations

Homogeneous coordinates are ubiquitous in computer graphics because
they solve the problem of representing a translation and projection as
a matrix operation.

Homogeneous coordinates allow all affine transformations to be
represented by a matrix operation.

A translation in R2 : (x,y) -> (x+a, y+b) can be represented as
R2 means 2D space, so these examples are 2D. 3D examples would have 4 columns/rows, etc.
| 1 0 a |   | x |   | x+a |
| 0 1 b | * | y | = | y+b |
| 0 0 1 |   | 1 |   |  1  |

where column vectors are the homogeneous coordinates of the two
points. All the linear transformations such as rotation and reflection
about the origin can also be represented, by matrices of the form

| a b 0 |
| c d 0 |
| 0 0 1 |

Furthermore all projective transformations can be represented by other
matrices. This representation simplifies calculation in computer
graphics as all necessary transformations can be performed by matrix
multiplications. As a result, a series of affine transformations can
be combined simply by multiplying successive matrices together. This
is at the heart of real-time graphics systems such as OpenGL and
DirectX which can use modern graphics cards to perform operations with
homogeneous coordinates.

Last modified: Wed May 27 19:15:49 EDT 2009