# CMSC 435/634: Introduction to Computer Graphics

## Assignment 3 Viewing Due October 10, 2012

### 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 drive over the landscape using keyboard and mouse controls. Motion will use four keys: holding 'w' will accelerate you in whatever direction your car is currently pointing, 's' will accelerate you backwards (first slowing you down, then going into reverse). 'a' and 'd' will turn your car to the left and right. Moving the mouse left, right, up and down should rotate your view relative to your current driving direction, but not change your direction of motion. 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 vehicle. 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 5 points, tip your car to always be aligned with the surface. You will need to interpolate the normals from each vertex using barycentric coordinates to find the normal within the triangle.

For 5 points, add gravity and drag. Gravity should not change the direction of your car, but you should slow down going uphill and speed up going downhill. With drag, your car should eventually slow to a stop if you are not actively accelerating.

### 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 glutSolidSphere() 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. Where to do this varies depending on your version of xcode, but if you google "working directory xcode <version>", you'll find penty of pages that tell you what you'll need to do.

For windows, install freeglut binaries by copying files into the locations described in the package readme, and use the provided Visual Studio 2008 project and solution files. If you are using a newer version of Visual Studio, it should successfully convert these for you. You may 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. This will allow you to work locally, then check changes back in directly without having to copy the files back onto the gl systems. 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 any 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/435 checkout -d my435 olano

### What to turn in

Turn in this assignment electronically by checking your source code into your assn3 CVS directory by 11:59 PM on the day of the deadline. Do your development in the assn3 directory so we can find it. As always, double check that you have submitted everything we need to build and run your submission, but not any generated files. In particular, no executables, or any of the other files xcode or visual studio generate beyond the ones already checked in.

For grading, be sure your program does run on Linux, and be sure to include a Makefile that will build your project when we run 'make'. Also, include a readme.txt file telling us about your assignment. Do not forget to tell us what (if any) help did you receive from books, web sites or people other than the instructor and TA, details about how you implemented the extra credit (if attempted).