Higher Level Classes

Camera

A Camera is a view of the 3D scene, consisting of a projection and a viewing transformation. The projection details are implemented by the PerspCamera and OrthoCamera classes. The viewing transformation consists of a position (translation) and rotations about X and Y.

The main code wrapped by Camera's apply() function is:

applyProjection();
glLoadIdentity();
glRotatef(-xRot, 1.0, 0.0, 0.0);
glRotatef(-yRot, 0.0, 1.0, 0.0);
glTranslatef(-pos[0], -pos[1], -pos[2]);

Camera includes basic functions for setting the position and rotations, and also several functions intended to make updating them simpler.

The turn(angle) and pitch(angle) functions add the given number of degrees to the Y or X rotation. moveForward(distance), moveLeft(distance), and moveUp(distance) move the camera the given number of units forward, left, or up (backward, right, and down can be done using negative distances). These directions are defined based on the direction the camera is currently pointing, rather than just being X, Y, or Z. The functions forward(), left(), and up() return unit vectors pointing in the given directions.

PerspCamera

PerspCamera represents a perspective projection. It keeps track of the "fovy" (field-of-view in Y), aspect ratio, and near & far clipping distances. It wraps the code:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fovy, aspect, near, far);
glMatrixMode(GL_MODELVIEW);

The convenience function zoom(degrees) can be used to change the field of view by the given amount; it will make sure that the field of view stays within the valid range of 0 to 180 degrees.

OrthoCamera

OrthoCamera represents an orthographic projection. It keeps track of left, right, bottom, & top edges, and near & far clipping distances. It wraps the code:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(left, right, bottom, top, near, far);
glMatrixMode(GL_MODELVIEW);

The default settings for OrthoCamera is a projection covering (0,0) to (1,1), with near & far distances of -1 and 1.

Object

Object is a generic class to represent any object that will be drawn in a scene. Subclasses can be created for specific types of geometry (such as the QuadricObject class). Object includes three major features:

Drawing properties

setTransform(), setMaterial(), setTexture(), and setTransparency() are used to assign the corresponding "properties" to an Object. The apply() methods are automatically called for each of these properties when the Object is drawn by its drawAll() function.

Callbacks

setDrawCallback(func, data) defines a callback function that will execute whenever the Object is drawn. This can be used to wrap any OpenGL geometry code (glBegin, glVertex, ..., glEnd) into an Object. The callback function must be of the form:

void myFunction(Object& object, void *data)
    {
    ...
    }

(where "myFunction" is replaced by the name of your function). object will be the Object for which the callback is being called, in case you need to get data from it; data is a generic pointer that you can pass to setDrawCallback(), to have additional data sent to your callback function.

setUpdateCallback(func, data) defines a callback function that will execute whenever the Object's update() function is called. This can be used to add behaviors to an Object, without needing to call the behavior function directly in your main code. The update callback function should be of the same form as a draw callback function (void myFunction(Object&, void *)

Attaching objects

object1.attach(object2) will "attach" object2 to object1, which means that whenever drawAll() is called for object1, object2 will also be drawn, with object1's transformation applied to it. Similarly, object2's update function will be called whenever updateAll() is called for object1.

Any number of levels of attachment can be made. If a series of objects are attached together as follows:

topObject.attach(object2);
object2.attach(object3);
object2.attach(object4);
object3.attach(object5);

then calling topObject.drawAll() will cause all of the objects to be drawn, and topObject.updateAll() will cause all of them to be updated. The sequence of drawing calls will look roughly like:

    topObject.transform.pushApply()
        topObject.draw()
        object2.transform.pushApply()
            object2.draw()
            object3.transform.pushApply()
                object3.draw()
                object5.transform.pushApply()
                    object5.draw()
                object5.transform.pop()
            object3.transform.pop()
            object4.transform.pushApply()
                object4.draw()
            object4.transform.pop()
        object2.transform.pop()
    topObject.transform.pop()

This forms a very simple scene graph, a representation of a complete scene as a hierarchy.

QuadricObject

QuadricObject draws a GLU quadric - a sphere, cylinder, disk, or partial disk.