Building A Cube
Suppose we wish to build a cube whose each edge is 1 inch long. We want this cube to be positioned in the center of the 2 inch Cartesian coordinate cube. This is shown in the following figure.
Let us now turn our attention to the new things that have been used in this program.
We have defined the shape of the cube in the myview::drawcube( ) function. This function has been called from myview::OnDraw( ). While defining the shape we have built it face by face. Hence there are six sets of vertices representing six sides of the cube. We have set up a different color for each face. Note that the vertices for each polygon are defined such that the fronts of the polygons form the outside of the cube, whereas, the backs are inside the cube. In other words the vertices of front facing polygons are defined counterclockwise, whereas, the vertices of back facing polygons are defined clockwise.
Making The Cube More Realistic
By default OpenGL displays a 3-D object using orthographic (parallel) projection. That is, though the back of the cube is farther away it is shown to be of the same size as the front of the cube. If we are to make the cube more realistic, we have to display it using perspective projection. This can be done in three steps:
Step 1: Applying The Projection Transformation
To use the perspective projection we need to perform the projection transformation. This is done in our program through the statements:
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity( ) ;
glFrustum ( -1.0, 1.0, -1.0, 1.0, 2.0, 7.0 ) ;
Here the first statement selects the OpenGL's projection matrix to apply the perspective projection to the cube being displayed. The glLoadIdentity( ) function loads the currently selected matrix with the identity matrix. This ensures that the matrix starts off fresh, without values that may affect the calculations to come.
The next step in applying perspective projection is to call the glFrustum( ) function to tell OpenGL the limits of the viewing volume, which is the 3-D area in which our objects exist. The glFrustum( ) function creates a perspective matrix and multiples it with the currently selected matrix. The six arguments passed to this function define the left, right, bottom, top near, and far coordinates of the viewing volume, as shown in the following figure.
The near and far arguments represent the distance from the "eye" and hence must be positive values. The eye is the point from which we're currently viewing the scene, which, unless we change it, is at ( 0, 0, 0 ), the origin of the 3-D Cartesian grid. Anything that lies outside the viewing volume would not be visible.
We can think of the near viewing plane as being the client area of the window in which the scene will appear. Specifically, the near plane's left and bottom coordinates get mapped to the window's lower left corner, and the right and top coordinates get mapped to the window's upper right corner.
Step 2: Applying The Modelview Transformation
In Step 1 we have defined the viewing volume. Our cube, however, is still outside of the viewing volume. This situation is shown in the following figure.
To get the cube inside the viewing volume we will have to move it along the z-axis such that it is completely accommodated in the viewing volume. The following statements accomplish this task:
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity( ) ;
glTranslatef ( 0.0f, 0.0f, -3.5f ) ;
The first line tells OpenGL that we now want to work with the modelview matrix. The second line initializes the modelview matrix to the identity matrix, and the third line translates the cube three and a half units down the Z axis. The glTranslatef( ) function creates a translation matrix and multiplies it with the currently selected matrix. Its three arguments specify the amount of translation on the X,Y, and Z axes, respectively.
Step 3: Rotating The Cube
We have now managed to get the cube inside the viewing volume. However, at this stage only its front face would be visible. To be able to see its other faces we will have to rotate it along the three axes. This has been achieved through the statements:
glRotatef ( 20.0, 1.0f, 0.0f, 0.0f ) ;glRotatef ( 30.0, 0.0f, 1.0f, 0.0f ) ;glRotatef ( 10.0, 0.0f, 0.0f, 1.0f ) ;
The glRotatef( ) function creates a rotation matrix and multiplies it with the currently selected matrix. Its four arguments specify the counterclockwise angle of the rotation and the X,Y,Z coordinates of a vector about which to rotate. To specify rotation around a specific axis, we have to make the argument for that axis 1.0 and the arguments for the other axes 0.0.
On rotation, the three faces of the cube would now be visible. The resulting cube is shown in the following figure.
You may run the program and find out for yourself why OpenGL is such a hot thing today. From each corner of the cube three colors seem to ooze out and then blend with other colors to create an impressive effect. The entire program is available for download.