INT32GP Graphics Programming: Tutorial #10
3D Orthogonal Projection

B1.11 3:00 pm Tue 27 Aug 02
B1.11 12 midday Wed 28 Aug 02
Start with teapot1.c. This program introduces you to 3D. In this tutorial you will add to this program, which needs to be improved.
  1. The program renders a glut geometric object - teapot - around the origin (middle of the screen). The parameter (0.5) specifies the relative size of the teapot. Write code to toggle between a wire frame teapot and a solid teapot glutSolidTeapot(size).
    void renderView(){
       glColor3fv(colour[red]);
       glTranslated(t[teapot][x],t[teapot][y],t[teapot][z]);
       glutWireTeapot(0.5);
    }
    
    Hint - set up a global variable (eg. wireframe) that can be controlled via the keyboard.
  2. Try other glut geometric objects from the GLUT API. Here are some examples.
       glutWireSphere(0.5,9,9);
       glutWireCube(0.5);
       glutWireCone(0.2,0.3,9,9);
       glutWireTorus(0.2,0.5,9,9);
  3. Add a keyboard feature to select which type of glut object to display.
  4. Try the arrow and page up and down keys. They control a translation. Note where this translation is applied in void renderView().
    /*
    ** manage model transforms
    */
    enum {teapot,models};
    GLdouble t[][3]={
       {0.1,0.0,0.0}
    };
    
    void specialKeys(int key,int xMouse,int yMouse){
       int i;
       for(i=0;i<=z;i++)
          t[teapot][i]=0.0;
       switch(key){
          case GLUT_KEY_PAGE_UP  : t[teapot][z]= 0.1;break;
          case GLUT_KEY_PAGE_DOWN: t[teapot][z]=-0.1;break;
          case GLUT_KEY_RIGHT    : t[teapot][x]= 0.1;break;
          case GLUT_KEY_LEFT     : t[teapot][x]=-0.1;break;
          case GLUT_KEY_UP       : t[teapot][y]= 0.1;break;
          case GLUT_KEY_DOWN     : t[teapot][y]=-0.1;break;
       }
       glutPostRedisplay();
    }
  5. Do you think the program needs double buffering? Try it. You need the following lines somewhere in your code. See Lecture #08 for more information.
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    
    glutSwapBuffers(); 
  6. This program mindlessly uses some OpenGL defaults. There is no code to control the PROJECTION or MODELVIEW matrix. We should add the following lines. The question is where? (Unless you modify the code in void specialKeys(int key,int xMouse,int yMouse) answering this question correctly may cause unwanted side-effects).
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
    
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
  7. Try loading the identity matrix into GL_MODELVIEW at the top of the following function. What happens? Now try loading the identity matrix into GL_PROJECTION at the top of the following function and load the GL_MODELVIEW code at the bottom.
    void reshapeWindow(int w, int h){
       glViewport(0,0,(GLsizei)w,(GLsizei)h);
       /*
       ** specify orthogonal 3D projection
       ** and set world coordinates
       */
       glOrtho(world[xLeft],world[xRight],
               world[yBottom],world[yTop],
               world[zNear],world[zFar]);
       /*
       ** set up camera
       */
       gluLookAt(eye[x], eye[y],eye[z],
                 centre[x],centre[y],centre[z],
                 up[x],up[y],up[z]);
    }
  8. Consider the code that sets up the "camera". Try changing the values. The "eye" is the position of the camera. In this example the camera is looking from the front down at the scene from the right. Try placing it behind the object. The camera is looking at the origin (centre). When you change these values make sure you are looking at some part of the object. The "up" variables decide which axis is up - Y in the example.
    /*
    ** manage camera
    */
    GLdouble eye[]={
       2.0,2.0,2.0
    };
    GLdouble centre[]={
       0.0,0.0,0.0
    };
    GLdouble up[]={
       0.0,1.0,0.0
    };
  9. Notice that the object moves in response to events (such as clicking a mouse key in the window) other than the special keys. Why is this? We can control this behaviour by loading the GL_MODELVIEW matrix with the identity matrix at the beginning of display(). Then edit void specialKeys(int key,int xMouse,int yMouse) to increment or decrement t[x],t[y],t[z]. Can you explain why?
  10. Does your program still have unwanted behaviour? Ask for help.
  11. Experiment with the following OpenGL transform functions.
    glTranslated(tx,ty,tz);
    glRotated(ra,rx,ry,rz);
    glScaled(sx,sy,sz);
  12. Move the camera around in response to keyboard input.
Fran Soddell email:F.Soddell@bendigo.latrobe.edu.au
last updated 27 August 2002