Project 1: Rendering 3D Objects Using OpenGL and GLUT
Fall 2005, CS 354, Computer Graphics
Assigned: September 6, 2005
Due: September 27, 11:59pm



Goal
In this project you shall draw simple objects in three dimensions and modify their rendering and view, as you change parameters using a keyboard and a mouse.  You shall learn about the graphics library OpenGL and also about GLUT, an OpenGL user interface toolkit.


Project Specifications

The starter code that has been provided implements a canvas that allows the user to switch between various rendering modes for various objects.  The starter code already has support for rendering a unit cube using three different methods.  For this project, you will be adding to the functionality of the canvas so that it can render a cone using three analogous methods, as well as rendering the cone from a user-controllable triangulation, and finally rendering more complex 3D objects.

For grading purposes, your program should compile and run on the Taylor basement Linux machines , although you are free to develop on whatever platform you wish.


Getting Started
Download the zip file for the starter code and use the "unzip" command.  The program is written in plain C, although you may want to rename the .c files to .cpp if you are more comfortable using C++.  If you are using a machine with graphics hardware (such as the ones in Taylor basement), make sure the non-Mesa libraries are being used in the Makefile.  If you are using a machine without a graphics card, make sure the Mesa libraries are being used (Mesa is a software-only version of OpenGL, so that any machine can run it).  To compile, type "make". This will produce the executable "canvas", which you can run by typing "./canvas". You will see a cube on a black background. Play around with this cube and cycle through the various display modes (or in other words, scenes) using the keyboard and mouse.


Keyboard Commands
Keyboard commands are interpreted by the function myKeyHandler() in canvas.c.

d - switch display modes (the Modes listed here are, in order, Display Mode 1, Display Mode 2, etc.):

  1. Draw a cube using GLUT
  2. Draw a cube using quadrilaterals
  3. Draw a cube using quadrilateral arrays
  4. Draw a cone using GLUT *
  5. Draw a cone using triangles *
  6. Draw a cone using triangle arrays*
  7. Draw a cone using a user-specified triangulation *
  8. Draw VRML2.0 objects *
  9. Draw a freeform scene *

Items 1 - 3 are already implemented in the starter code as a programming reference and should not need to be changed.  Items 4-9 will be implemented for this project.

D - go through the display mode list backwards.
s - toggle display styles between solid and wire frame.  Solid and wire-frame styles apply only to GLUT-based display modes
S - same as s
, and < - rotate the model along its x axis
. and > - rotate the model along its y axis
/ and ? - rotate the model along its z axis
= and + - zoom in and out
c - reset the model to its original orientation and zoom
t - run the Performance Test for the current display mode.  The test returns the number of seconds needed for rendering 3 rotations of the model.
z - restore the window to its default size.  (Needed before running the Performance Test for controlled testing).
q - quit the program

Mouse Commands
left button - Hold, then move the mouse to control rotations about the model's y-axis and x-axis
middle button - Hold, then move the mouse to control rotations about the model's y-axis and z-axis
right button - Hold, then move the mouse to zoom in and out

This program uses the OpenGL graphics library to draw to the screen and the GLUT window manager for the user interface. Try to understand how the interface is being made in the main() function in canvas.c.  Next, try to understand how the different cubes are being displayed using various OpenGL and GLUT functions.  The cube in Display Mode 1 is being sent directly to the renderer by either the function glutSolidCube() or glutWireCube(). Refer to an OpenGL reference book or to the links provided at the end of this document to understand what the various functions are doing. For this project, you may ignore lighting and shading functions.


A Note on VRML2.0
VRML2.0(Virtual Reality Modeling Language) is used to specify 3D geometric objects.  For this assignment, Display Mode 8 uses data extracted from VRML files for a cube, dodecahedron, icosahedron, and pyramid.  You will not be using actual VRML files in this assignment, but rather, the data extracted from VRML files.  The 4 objects just mentioned will be collectively referred to as  VRML objects.


Programming Checklist
The following is a a list of what needs to implemented in this project.

  1. Under Display Mode 4, draw a cone using GLUT.  The GLUT cone should have a radius of 1.0 and a height of 1.0 and should be completely blue a.k.a. glColor3f(0.0f, 0.0f, 1.0f).  This mode needs to support the 's' toggle switch, so that the user can switch between a solid cone and a wire-frame cone, just like in Display Mode 1.  When making the function call to GLUT, pick whatever values look good for the number of slices and the number of stacks.

 

  1. Under Display Mode 5, draw a cone by iterating through the triangles in the vertex, index, and color arrays for a cone in drawing.c.  You will be using glBegin(GL_TRIANGLES), and rendering each triangle in the order it is specified in the arrays, along with the colors of each vertex.  Refer to Display Mode 2.

 

  1. Under Display Mode 6, draw a cone using array pointers.  You will need to use glEnableClientState(GL_VERTEX_ARRAY) and similar functions in order to pass the vertex, index, and color arrays for a cone to the renderer.  Refer to Display Mode 3.

 

  1. Under Display Mode 7, you will implement a calculated triangulation for the entire surface of a cone and add the appropriate key bindings so that the user can control the triangulation.  The arguments to this calculated triangulation will be the radius of the base (r), the height of the cone (h), and the number of equally sized triangles used to triangulate the base of the cone (n).  Each of the n triangles in the base should share a common vertex with all n-1 other triangles, namely, the center of the base.  From here, you should be able to compute a triangulation for the lateral area of the cone using another n triangles, thus bringing the total number of triangles to 2n.

    For this display mode,  calculate the triangles using your knowledge of geometry and draw the set of triangles to the screen using some form of glBegin().  You should not use any GLUT built-in functions.   You may render each triangle as you calculate its position; there is no need to create a vertex array or an index array unless that makes your algorithm easier.  Also, there is no need to create a vertex color array (just render the entire cone in blue a.k.a. glColor3f(0.0f, 0.0f, 1.0f)).  Use the following initial values and key bindings.  For each key binding, print to stdout a brief description of what changed each time the user presses the key (ex: print "Radius increased by 0.1" when the user presses 'i').

 

    • r - Initially set to 1.0.  Set 'i' to increase r by 0.1, and set 'I' to decrease r by 0.1.  Your program must make sure that r is kept greater than or equal to 0.1.
    • h - Initially set to 1.0.  Set 'o' to increase h by 0.1, and set 'O' to decrease h by 0.1.  Your program must make sure that h is kept greater than or equal to 0.1.
    • n - Initially set to 8.  Set 'p' to increase n by 1 and set 'P' to decrease n by 1.  Your program must make sure that n is kept greater than or equal to 3.

 

  1. Under Display Mode 8, render (one at a time) the 4 VRML objects given in the vertex and index arrays in vrml.c by iterating through the arrays and rendering the faces of the object one at a time.  Use glColor3f(1.0f, 1.0f, 0.0f) to color each of these objects.  The VRML objects are specified in the almost the exact same way as the cone for Display Mode 4, except in the VRML index arrays, each face is terminated by a -1.  For instance, an index sequence of (0, 1, 2, -1, 3, 2, 1, -1) translates to two triangles, where the first triangle is composed of vertices (0, 1, 2) in the vertex array and the second triangle is composed of vertices (3, 2, 1) in the vertex array.
     
    Since VRML faces are not restricted to triangles and quads, you will need to use glBegin(GL_POLYGON) or glBegin(GL_LINE_LOOP) to render the faces of the objects.  It may be difficult to actually see the geometry of the VRML objects if the faces are shaded in using glBegin(GL_POLYGON).  To fix this, replace glBegin(GL_POLYGON) with glBegin(GL_LINE_LOOP) so that the outline of each face is rendered instead.  glBegin(GL_LINE_LOOP) is used just like how glBegin(GL_POLYGON) and glBegin(GL_TRIANGLES) are used.  Submit the version which uses glBegin(GL_LINE_LOOP), but be sure to take a look at the glBegin(GL_POLYGON) version so that you are familiar with its drawback.  Note that the coordinates of the VRML objects are not normalized to be within the default viewing frustum, so you may need to zoom in or zoom out to get a good look at them.
     
    Add the following key binding: 'v' will be set to switch to the next VRML object in this order: VRML cube, dodecahedron, icosahedron, pyramid, back to cube, dodecahedron, and so on.  On startup, the default VRML object should be the VRML cube. Print a confirmation of the current VRML object to stdout each time the user presses 'v'.

 

  1. Under Display Mode 9, use what you've learned about OpenGL and Glut to render any scene of your own design, using either material from this project or additional material from the references.  The goal of this section is to experiment with OpenGL.  Some suggestion include rendering a block pyramid using GLUT cubes or drawing a simple face using GLUT spheres and GLUT cones.  The starter code has a brief example that shows how to use glPushMatrix() and glPopMatrix() to render multiple objects in a scene.

 

  1. Finally, run the Performance Test on Display Modes 1 - 7 and record the running times for each Display Mode.  For Display Modes using GLUT, two tests should be performed: one for the solid display style and one for the wire frame display style.  There should be a total of 9 tests.  Arrange the results in an ASCII table (no tabs, please) in your Group's README file, and answer the following questions in the same file: Which Display Mode(s) for the cone ran fastest and which ran slowest, or did they all run at about the same speed?  Based on what you have learned, write a one or two sentence explanation for the observed running times.

  2. Note: In the function print_disp_style() in drawing.c, the two printf statements were reversed.  They should be switched around in your code before you submit so that the correct update is printed.


Code Map

canvas.c - Handles basic GLUT initialization, keyboard input, camera control, and window resizing and reshaping.
drawing.c, drawing.h - Handles the drawing algorithms for each display mode and contains the raw data (vertex array, index array, color array) for cubes and cones.  New display modes should be implemented here.
vrml.c, vrml.h - Handles the drawing of vrml objects and contains their raw data.  The various components of the vrml display mode should be implemented here.
mouse.c, mouse.h - Handles mouse input.  These files should not need to be changed.
Makefile - standard Unix makefile (not used if you are using Visual C++)
README - answers to questions in the Coding (team) portion of Project 1
project1.txt - answers to questions in the Written (individual) portion of Project 1

Written Questions for Each Team Member (20% of the project grade)
Each team member should write up the answers to these questions on their own and submit their work separately, as described in the next section.

1.  What are advantages and disadvantages of having vertices explicitly as opposed to vertex indices in object representations ?

2.  How many matrix modes are there in OpenGL and what are their use ?

3.  What are the differences between view-ports and the viewing frustum?

4.  What is the role of GLUT, and where in OpenGL do you use it ?

5.  What are the differences between a single frame buffer and a double frame buffer?

6.  The line equation representation y=mx+b is not good for displaying a line on the screen, why?


What and How to Submit

Your program should compile and run on the Taylor or Painter basement machines. Once you have verified this,  submit the following files:

     Makefile
     Source code  (.c and .h files)
     README

The README file should be a plain text file and it should clearly contain: the names of everyone in the Group, an ASCII table of the Performance Test results (please do NOT use the tab character in your table), and the answers to the Performance Test questions.  In addition, if appropriate, you may also write about what extra things you did for the project, any special compilation instructions, what new ideas you came up with, etc; please keep such a  discussion short and to the point.

Change into your source code directory and submit using:

turnin -submit smpark cs354_project1_code *

to submit everything in the directory, or replace * with the names of the specific files and directories you wish to submit.  Please submit only one copy of the code for each group (it does not matter which group member submits the code).

For the answers to the "Written Questions for Each Team Member", each team member should independently work on and write up the answers in a file called:

     project1.txt.

The file should also be a plain text file which should contain the answer to the above "Written Questions for Each Team Member."  This is the only file that needs to be submitted for the Written portion of Project 1.

Each team member will need to submit his or her own writeup file using:

turnin -submit smpark cs354_project1_written project1.txt


Here is a short note on how to use the "turnin" program.

Refer the "Grading" section  in the Syllabus on the course home page for grading and late policy.



Helpful OpenGL and GLUT References

Neider, Davis and Woo, "OpenGL Programming Guide" Second Edition, Addison-Wesley

OpenGL Online Quick Reference by David Mount (be sure to read about the OpenGL Basic Drawing section, paying attention to the glBegin() function)
http://www.cs.umd.edu/users/mount/427/OpenGL/ogl_ref/ogl_ref.html

GLUT Online Tutorial (see Introduction->Setup, Introduction->Initialization, Introduction->Animation, and Input->Keyboard).
http://www.lighthouse3d.com/opengl/glut/