When we draw a triangle as follow,
there is actually one important process going on before each vertex is projected (like we did in our Canvas class): scaling, rotating, shearing (we do not use shearing though), and translating each vertex.glBegin(GL_TRIANGLES); { glVertex3f( -1, 0, 0 ); glVertex3f( 1, 0, 0 ); glVertex3f( 0, 1, 0 ); } glEnd();
Here is the draw triangle code from yesterday's lecture,
The translation basically move the triangle inside the viewing volume so that it shows up on the viewport.glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0,0,-2); glBegin(GL_TRIANGLES); { glVertex3f( -1, 0, 0 ); // the vertex is actually (-1, 0, 0) + (0, 0, -2) = (-1, 0, -2) before projected onto the canvas. glVertex3f( 1, 0, 0 ); // (1,0,0) + (0, 0, -2) = (1, 0, -2). glVertex3f( 0, 1, 0 ); // (0,1,0) + (0, 0, -2) = (0, 1, -2). }
Now, suppose changing the above code into,
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0,0,-2); glRoate3f(45, 0f, 1f, 0f); glBegin(GL_TRIANGLES); { glVertex3f( -1, 0, 0 ); // the vertex is actually (-1*0.707, 0, 1*0.707) + (0, 0, -2) = (-0.707, 0, -1.293) before projected onto the canvas. glVertex3f( 1, 0, 0 ); // (1*0.707, 0, -1*0.707) + (0, 0, -2) = (0.707, 0, -2.707). glVertex3f( 0, 1, 0 ); // (0,1,0) + (0, 0, -2) = (0, 1, -2). }
So the location of the triangle before projection is (-.7, 0, -1.3), (.7, 0, -2.7) and (0, 1, -2).
Now try to find the location of the triangle if translation is done first, and then followed by rotation, as follow,
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRoate3f(45, 0f, 1f, 0f); glTranslatef(0,0,-2); glBegin(GL_TRIANGLES); { glVertex3f( -1, 0, 0 ); glVertex3f( 1, 0, 0 ); glVertex3f( 0, 1, 0 ); }
A scaling is added to the following code. Again try to find the final vertex positions.
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRoate3f(45, 0f, 1f, 0f); glTranslatef(0,0,-2); glScalef(.5, 1, 1); glBegin(GL_TRIANGLES); { glVertex3f( -1, 0, 0 ); glVertex3f( 1, 0, 0 ); glVertex3f( 0, 1, 0 ); }
Here is an example program from the red book, model.c. Try to backward trace and find out the transformation applied onto each vertex.// Starting from glVertex*(), and tracing BACKWARD all the transform commands issued, // the transformations are applied to the vertex in that order, and // this process stops right before the first glLoadIdentity().
void display(void) { /* 0 */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* 1 */ glMatrixMode(GL_MODELVIEW); /* 2 */ glLoadIdentity(); /* 3 */ glTranslatef(0,0,-2); /* 4 */ glPushMatrix(); /* 5 */ glTranslatef(1.0, 0, 0); /* 6 */ glScalef(.5, 1, 1); /* 7 */ glutSolidCube (1.0); /* 8 */ glPopMatrix(); /* 9 */ glTranslatef(-1.0, .0, 0); /* 10*/ glScalef(.5, 1, 1); /* This cube is scaled by line 10, translated by line 9, and skipping all the Push&Pop blocks, translated by line 3. This transformation chain stops right there, since next is line 2, glLoadIdentity(). */ /* 11*/ glutSolidCube (1.0); /* 12*/ glutSwapBuffers(); }
The above example simply tells us the glPushMatrix() and glPopMatrix() block can be used to make any transformation LOCAL, i.e, it does not have any effect outside of the block.
Now try to use the callback functions to read in the user's input, and transforming the model(s) based on that. You can either use keyboard or mouse motion callback function.
Submit your source code to zh2001 AT columbia DOT edu, cc copy xchen AT cs DOT utah DOT edu, before the end of the afternoon class.
1.3.6