CMSC 435/634: Introduction to Computer Graphics

Assignment 3
Viewing
Due October 12, 2009

The assignment

For the last assignment, you wrote code to generate a polygonal model using L-systems. For this assignment, you will write code to interactively walk around another model. You will become a tourist, walking around the the steets of a city generated with an L-system. You should write a program that renders the city from the point of view of a person at street level, and allows the user to walk around the city. Your program should have the following user interface:

In addition to moving about and looking around at the city, you must also prevent the tourist from walking through walls. This does not have to be particularly efficient, but it has to work right. You can use the following algorithm:

Extra Credit (some mandatory for those taking 634)

City model file format

The model file contains polygons that you should draw on the screen (both roads and buildings). Geometry is defined in terms of quads, so what you'll see in the file are groups of four vertices, each defined by three floating point numbers, separated by spaces. A fifth line in each group defines a color for the quad (which you don't necessarily need to use). The vertices are defined using absolute world-space coordinates, with the city existing mostly in the XZ plane. The file format was designed for ease of use rather than efficiency, so there will be some redundant points. There may also be some overlapping quads, as the file was generated using an L-system.

Example quad:

-0.117647 0 -0.117647    #vertex 1
0.913149 0 -0.117647     #vertex 2
0.913149 0 0.117647      #vertex 3
-0.117647 0 0.117647     #vertex 4
0.5 0.5 0.5              #color
You can find a sample model file in quads.txt. The walls file contains 2D line segments that you can use for collision detection. These correspond to the quads used for the buildings in the previous file, but with the Y-component removed (recall that the city is in the XZ plane). Each line in the file contains four floating point numbers separated by spaces, following the format:
    x1 y1 x2 y2
This defines a separate line segment from the point (x1, y1) to (x2, y2). You can find a sample wall file in walls.txt.

Using OpenGL

As with assignment 2, we will be using FreeGLUT, an implementation of the OpenGL Utility Toolkit (i.e. GLUT), which is installed on the UMBC GL system at:

    /afs/umbc.edu/users/o/l/olano/home/public/freeglut
GLUT is a utility toolkit that is designed to make it easier to use OpenGL with a window manager. It provides functions for handling windowing events (such as mouse clicks, key presses, etc). You will perform your rendering in the draw() callback function, which is called whenever the window is being re-drawn.

The OpenGL libraries are installed on the university GL system. While it is possible to work remotely using ssh, you are encouraged to work locally on one of the OIT lab machines (just reboot into Linux). The sample code from assignment 2 for using GLUT in Linux is located at:

    /afs/umbc.edu/users/r/h/rheingan/pub/435/Proj2

For more information about OpenGL and GLUT, you have several resources available:

Tips on Implementing Movement

This section contains a few tips on how to implement your movement code. There are several functions you want to know about. The first two are glutKeyboardFunc and glutKeyboardUpFunc. These allow you to set a callback function that is called by GLUT when keys change state. To keep track of whether the keys are pressed, use these callbacks to toggle a set of global variables as the keys change state.

The second function you want to know about is called clock(), which is declared in the standard C <time.h> header file. clock() returns the number of clock ticks that have elapsed since your program started. To convert this to seconds, divide by the constant CLOCKS_PER_SEC. Since you are dealing with very small time steps, you will probably need to use floating point for your elapsed time. You can do this using an idle callback function (specified by glutIdleFunc) to provide per-frame movement.

For some reason, the clock() function on linux.gl does not return anything that even remotely resembles elapsed time. I would strongly suggest that you work locally, rather than SSHing to linux.gl. You can do this by booting the OIT lab machines into Linux. Tell us in your readme file where you did your development.

Strategy

  1. Start by implementing just the camera translations. These should be easy. Once those work, add rotation. Save collision detection for last, after you have smooth camera movement.
  2. Beware of numerical precision. Remember that floating point computation is not exact. Your collision detection routine will need to deal with floating point roundoff error in a robust manner, otherwise you'll be able to randomly pass through walls.
  3. If your collision detection doesn't seem to be working right, build yourself a test harness that calls the collision detection function for a fixed (small) city with a variety of movement vectors. This will let you test your code in a controlled fashion.

What to turn in

Submit your assignment as 'Proj3'. Include your source code and makefile. Also include a readme file with a description what hardware/software environment you used to develop your project, and a description of any help you received (or a statement that no help beyond the text and course staff was received). Your readme file should also include any instructions necessary for using your program.

Working at home

If possible, don't. We test things out on the university computers and may or may not be able to help you if things don't work right for you at home. If you do work at home, your final submitted version must be able to run on the gl machines and must be electronically submitted there.