Open GL Super Bible

Previous Table of Contents Next


Advanced Matrix Manipulation

You donít have to use the high-level functions to produce your transformations. We recommend that you do, however, because those functions often are highly optimized for their particular purpose, whereas the low-level functions are designed for general use. Two of these high-level functions make it possible for you to load your own matrix and multiply it into either the Modelview or Projection matrix stacks.

Loading a Matrix

You can load an arbitrary matrix into the Projection, Modelview, or Texture matrix stacks. First, declare an array to hold the 16 values of a 4 x 4 matrix. Make the desired matrix stack the current one, and call glLoadMatrix.

The matrix is stored in column-major order, which simply means that each column is traversed first from top to bottom. Figure 7-28 shows the matrix elements in numbered order. The following code shows an array being loaded with the Identity matrix, then being loaded into the Modelview matrix stack. This is equivalent to calling glLoadIdentity using the higher-level functions.

// Equivalent, but more flexible
glFloat m[] = { 1.0f, 0.0f, 0.0f, 0.0f,
                   0.0f, 1.0f, 0.0f, 0.0f,
                   0.0f, 0.0f, 1.0f, 0.0f,
                   0.0f, 0.0f, 0.0f, 1.0f };

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(m);


Figure 7-28  Column-major matrix ordering

Performing Your Own Transformations

You can load an array with an arbitrary matrix if you want, and multiply it, too, into one of the three matrix stacks. The following code shows a Transformation matrix that translates 10 units along the x-axis. This matrix is then multiplied into the Modelview matrix. You can also achieve this affect by calling glTranslatef.

     // Define the Translation matrix
     glFloat m[] = { 1.0f, 0.0f, 0.0f, 10.0f,
                        0.0f, 1.0f, 0.0f, 0.0f,
                        0.0f, 0.0f, 1.0f, 0.0f,
                        0.0f, 0.0f, 0.0f, 1.0f };

     // Multiply the translation matrix by the current modelview
     // matrix. The new matrix becomes the modelview matrix
     glMatrixMode(GL_MODELVIEW);
     glMultMatrixf(m);

Other Transformations

Thereís no particular advantage in duplicating the functionality of gLoadIdentity or glTranslatef by specifying a matrix. The real reason for allowing manipulation of arbitrary matrices is to allow for complex matrix transformations. One such use is for drawing shadows, and youíll see that in action in Chapter 9. Some other uses are wrapping one object around another object, and certain lens effects. For information on these advanced uses, see Appendix B.

Summary

In this chapter, youíve learned concepts crucial to using OpenGL for creation of 3D scenes. Even if you canít juggle matrices in your head, you now know what matrices are and how they are used to perform the various transformations. Youíve also learned how to manipulate the Modelview and Projection matrix stacks to place your objects in the scene and to determine how they are viewed on screen.

Finally, we also showed you the functions needed to perform your own matrix magic if you are so inclined. These functions allow you to create your own matrices and load them into the matrix stack, or multiply them by the current matrix first.

The tank/robot simulation at this point in the book will now allow you to move around in a three-dimensional world and explore objects placed all around. If you study the simulation code thus far, you will find excellent use of perspective projections, as well as the gluLookAt utility function that provides a simple way to specify your viewing transformation. Your 3D world is made of wire for now, but that will be changing very soon.

Reference Section

glFrustum

Purpose
Multiplies the current matrix by a Perspective matrix.
Include File
<gl.h>
Syntax
void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
Description
This function creates a Perspective matrix that produces a perspective projection. The eye is assumed to be located at (0,0,0), with -far being the location of the far clipping plane, and -near specifying the location of the near clipping plane. This function can adversely affect the precision of the depth buffer if the ratio of far to near (far/near) is large.

Parameters

left, right
GLdouble: Coordinates for the left and right clipping planes.
bottom, top
GLdouble: Coordinates for the bottom and top clipping planes.
near, far
GLdouble: Distance to the near and far clipping planes. Both of these values must be positive.
Returns
None.

Example

The code below sets up a Perspective matrix that defines a viewing volume from 0 to Ė100 on the z-axis. The x and y extents are 100 units in the positive and negative directions.

    glLoadMatrix(GL_PROJECTION);
    glLoadIdentify();
    glFrustum(-100.0f, 100.0f, -100.0f, 100.0f, 0.0f, 100.0f);
See Also
glOrtho, glMatrixMode, glMultMatrix, glViewport


Previous Table of Contents Next