# CMSC 435/634: Introduction to Computer Graphics

## Assignment 3 Viewing Due October 12, 2011

### The Assignment

For this assignment, you are given a program that uses OpenGL to render a hilly terrain. You will modify this program to interactively walk around over the landscape using keyboard and mouse controls. Motion will use four keys: holding 'w' will move you forward in whatever direction you are currently facing, holding 'a' will slide you to the left, 's' will move you backwards, and 'd' will slide you to the right. Moving the mouse left and right should turn your view and motion direction left and right. Moving the mouse up and down should tip the view up and down. During any motion, you should remain a constant height above the landscape. All motions should be computed in terms of rates (per second or per millisecond), then scaled by the elapsed time between frames.

To figure out the height of your viewpoint, consider just the horizontal position of your character. From that position, you will compute which triangle you are in, and your barycentric position within that triangle. Use barycentric interpolation of the vertex elevations to compute the surface height at your position, then add a constant offset to place you above the surface.

Make the landscape effectively infinite by rendering eight extra offset copies of the base terrain. Hide the repetition by turning on fog with glEnable(GL_FOG), and using gl_Fog() to set the fog parameters (the man glFog command will give you the options). Use the 'f' key to toggle the fog on and off (for debugging, and so we can check your work). If your character walks off any edge, move their position back to the opposite edge. This jump should not be visible when the fog is enabled, since the terrain edges match and the distant changes will be hidden.

Set your near clipping plane to just close enough to not visibly clip the terrain. Set your far clipping plane to just past where the landscape disappears in the fog.

### 634 only

Have two modes, toggled with the 'm' key. One that uses OpenGL matrix operations, and one where you do all of the matrix operations yourself, using only glLoadMatrix for both the GL_PERSPECTIVE and GL_MODELVIEW matrix, where you create all of the transformation matrices and do the matrix/matrix multiplies yourself.

### Extra credit

For 10 points, add velocity, drag and gravity.The character should continue moving as long as the velocity is non-zero. The acceleration from gravity should be dependent on the direction of motion, so should make it slower to go up hill and faster to go down hill. Drag is a constant backwards braking acceleration, eventually slowing the character to a stop. With the extra credit, you should be able to climb up a high hill, then sled down it and over the other nearby hills until drag slows you to a stop.

### Strategy

Plan ahead first. Know how you are going to find the position and view vector. Once you have a plan, implement in stages that each produce a visible, testable result. While it is not part of the assignment, it may be useful to add extra keys for debugging. For example, a key that switches between the perspective view and a top-down view with a gluSphere() at the current position could help debug your position code.

You may find the following OpenGL calls helpful to complete the assignment:

• Reset the current matrix to a 4x4 identity matrix: glLoadIdentity()
• Set up perspective: glFrustum(left, right, bottom, top, near, far) or gluPerspective(fov,aspect,near,far)
• Look-at transform from point eye to center point, with up vector projecting vertically on the screen: gluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ)
• Translate: glTranslatef(x,y,z)
• Rotate around an axis through the origin: glRotatef(degrees, axis_x, axis_y, axis_z)
• Apply an arbitrary 4x4 transformation matrix: glMultMatrix(matrix)
• Push and pop matrix state: glPushMatrix(), glPopMatrix()
• Replace the current matrix with one of your own devising: glLoadMatrix(matrix)

### Development options

The sample code will run on the UMBC gl systems using the OpenGL and freeglut libraries. You will want to be logged directly into a linux machine at the console to develop this way. Since the program is interactive, you won't be able to use a remote terminal that can't display graphics windows, and using a remote X server will definitely be too slow.

If you have Linux installed on your own PC, you should already have OpenGL libraries. You may need to also install the glut or freeglut library, either from your distibution's pre-built packages or from the source online. If you do not have OpenGL libraries already installed, you can download both MesaGL and GLUT from mesa3d.org.

The sample code will also run on a Mac using the provided Makefile from the command line, or the provided xcode project. If you use xcode, you will need to set the working directory so it can find the ppm files. Right click on the executable, choose Get Info, and change the working directory from "Build Projects directory" to "Project directory".

For windows, install freeglut binaries by copying files into the locations described in the package readme, then copy these Visual Studio 2008 project and solution files into your assn3 directory. Some people like to put the Visual Studio files into a subdirectory. If you do this, you'll need to set the working directory in the Debug panel of the project properties so it can find the ppm files.

If you use your own system, you may find it useful to check out your cvs directory directly on your own computer. You can either use a command-line cvs client, a GUI client, or one that's integrated into the OS. For Mac or Linux, I usually use the command line client, but for Windows I use TortoiseCVS. In either case, use ssh to access the repository, by adding <user>@gl.umbc.edu: to the beginning of the repository path. For example, to check out a copy on my Mac, I'd use

cvs -d olano@gl.umbc.edu:/afs/umbc.edu/users/o/l/olano/pub/435fa11 checkout -d my435 olano