Next we'll draw a triangle on the plane z = 0. This triangle can be specified by the three points as shown in figure 1.
In code this looks like:
/* draw a triangle */ glBegin(GL_TRIANGLES); glVertex3f(-2.0f, -1.0f, 0.0f); glVertex3f(0.0f, 2.0f, 0.0f); glVertex3f(2.0f, -1.0f, 0.0f); glEnd();
Add this to the the display callback function (_Draw). Compile and run the program. Oh no! No triangle! What's wrong? (read on)
The correct OpenGL commands have now been sent to draw a triangle on the plane z = 0. However, nothing is visible. This is because the camera perspective and viewport transformations have not been set. Clearly, these transformations will change whenever the window is resized because the viewport should match the new window width and height and the perspective transformation should represent the new window aspect ratio. Modify the reshape callback to update these transformations:
static void _Reshape(int width, int height)
{
/* set the viewport to the window width and height */
glViewport(0, 0, width, height);
/* load a projection matrix that matches the window aspect ratio */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)width/(double)height, 1.0, 100.0);
/* reset the modelview matrix */
glMatrixMode(GL_MODELVIEW);
}
The important functions here are glViewport() and
gluPerspective(). The gluPerspective()
functions is part of GLU, the OpenGL Utility Library. See their man
pages for more details (ie. type man glViewport in a
terminal window). Still no triangle? Hmmmm...
The triangle is on the plane z = 0, but the default modelview matrix
is the identity matrix. This represents a camera placed on the origin
facing in the direction of -z. Since the near plane (set by the
gluPerspective() function) is one unit in front of the
camera, everything closer than the plane z = -1 is clipped away. This
includes our triangle! So we can either move the triangle or move the
camera. Choose a method to make the triangle visible, update your
code where appropriate, and enjoy the view of your triangle.
If you choose to move the triangle, you can do so by changing the triangle's z coordinates. You can do this by modifing the input when defining the triangle:
/* draw a triangle */ glBegin(GL_TRIANGLES); glVertex3f(-2.0f, -1.0f, -10.0f); glVertex3f(0.0f, 2.0f, -10.0f); glVertex3f(2.0f, -1.0f, -10.0f); glEnd();
You can also do this by modifying the modelview matrix so that the triangle is rendered relative to a different coordinate space:
glTranslatef(0.0f, 0.0f, -10.0f);
The complementary operation to moving the triangle away from the
camera is to move the camera away from the triangle. To move the
camera we can modify the modelview matrix using the
gluLookAt function. Here is the code to place the camera
at the point (0, 0, 10), looking at the origin (0, 0, 0), oriented
such that the +y is up:
gluLookAt(0.0, 0.0, 10.0, /* eye point */
0.0, 0.0, 0.0, /* reference point */
0.0, 1.0, 0.0); /* up vector */
If you choose to modify the modelview matrix rather than modify the
calls to glVertex you need to decide where to do so. If
the modelview matrix needs to be updated each time the triangle is
rendered you should do so in the _Draw function. If it needs to be
updated on window resize, do so in the _Reshape function. Otherwise,
if it does not change and only needs to be set once, set it in the
_Init function.
If all has gone well, you should now have a white triangle in the
middle of a window with a background colour of your choosing. You can
change the colour of the triangle by using a call to the
glColor() function:
/* set vertex colour to blue */ glColor3f(0.0f, 0.0f, 1.0f); /* draw a triangle */ glBegin(GL_TRIANGLES); glVertex3f(-2.0f, -1.0f, -10.0f); glVertex3f(0.0f, 2.0f, -10.0f); glVertex3f(2.0f, -1.0f, -10.0f); glEnd();
In this example code, the vertex colour is set to blue and then the
triangle is rendered. With each glVertex call the current
vertex colour (blue) is used. You can also change the vertex colour
between glVertex cals. This results in each vertex having
a seperate colour. These colours are blended over the triangle. Try:
/* draw a triangle */ glBegin(GL_TRIANGLES); /* red vertex */ glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-2.0f, -1.0f, 0.0f); /* green vertex */ glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(0.0f, 2.0f, 0.0f); /* blue vertex */ glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(2.0f, -1.0f, 0.0f); glEnd();
Set the vertex colours of your triangle to something that suits you. The end result should look something like this (without the jpeg compression artefacts):
Make sure that your program displays a triangle with different vertex colours before continuing. If it does not please ask for assistance from a demonstrator. If you still can't get your program to work, you can download a copy with all changes up to this point here.
Next: Animating a Teapot