Transformation matrices

In theory

Before we do anything with OpenGL, we need to set up our transformation matrices. Such a matrix is a 4x4 grid of numbers, that can transform coordinates.

This is an example of a transformation matrix that translates a vector 20 units to the right (X axis), 15 units upwards (Y axis) and 4 units into the screen (Z axis).

To apply the transform to a vector (a point), we multiply the vector with the matrix:

We can also multiply two matrices to create a new matrix that contains both transformations. For further details on how matrix multiplication works, see Wikipedia's take on it.

By default, OpenGL has two context-wide matrices:

  • Projection - This matrix specifies how our coordinates are mapped to the window. There are two types of projection matrices:
    • Orthographic - Our world coordinates are 2D positions.
    • Perspective - Our world coordinates are 3D positions, which will be projected into 2D space.
  • Modelview - This matrix allows us to move objects around in the scene, as well as moving the camera. In some cases, this is split up into a model and view matrix.

In practice

Now let's actually use this knowledge. First, let's initialise our projection matrix. To modify it, we must make it the active matrix by calling glMatrixMode(GL_PROJECTION). Since we're just starting off, we'll use a simple orthographic matrix for now. We can manually load one by passing a 4x4 float array into glLoadMatrixf, but thankfully OpenGL provides us with glOrtho. Since both of these functions achieve their goal by multiplying the new matrix with the current matrix, we need to load an identity matrix (no transform) first. Otherwise, a multiplication with zero would take place, which would have no effect on our projection matrix.

But how does glOrtho actually work? Here's its function signature:

glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_value, GLdouble far_value);

Left, right, bottom and top are the boundaries of our drawing surface (our window). If we want a cartesian coordinate system, where is in the top left of the window, we'd use these values:

Parameter Value
left 0.0
right 640.0
bottom 480.0
top 0.0
near_value -1.0
far_value 1.0

Keep in mind that 640 and 480 are the width and height of our window respectively. The parameters near_value and far_value specify bounds on the z axis, beyond which no objects may be rendered. Since we don't need the Z axis in 2D space, -1 to 1 makes sense.

Our full projection matrix init looks like this:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 640.0, 480.0, 0.0, -1.0, 1.0);

That was complex. But thankfully, initialising our modelview matrix is much easier:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

results matching ""

    No results matching ""