castle model

The Assignment

For this assignment, you will be loading a subset of the common OBJ 3D object file format into an interactive OpenGL application. The sample application already has code to orbit the view around an object. Take the file name of an obj file as a command line argument, load the file as a set of objects (one per material), and use the bounding box of all of the geometry in the obj file to automatically set the viewing distance and the near and far distances (3rd and 4th parameters to glm::perspective()) to see the full model.

Provided Code

To get you started, a simple OpenGL application has been committed to the GLapp directory in your git repository. This application renders two objects: a textured plane with a sphere floating over it. It uses three external libraries that should work on Windows, Mac, and Linux: GLFW provides window creation and input handling; GLEW manages the OpenGL functions and extensions; and GLM provides vector and matrix types and functions.

For Windows, I have precompiled all three libraries into a zip, together with a batch script that will set the environment variables necessary for CMake to be able to find them. You must download the file, extract the contents, run the script, and restart CMake before you can use CMake to generate the GLapp.sln file.

For Linux, you should be able to find all three packages in the package manager for your Linux distribution. On Mac, I recommend installing them with the homebrew package manager.

You will need a computer capable of running an interactive application with at least OpenGL 3.0. If yours will not work, we have a limited number Windows PCs in the GAIM lab (ENG 005) that you can use.

Obj Format

OBJ is a simple text format broken into lines. The subset of this format you need to implement consists of (where %s is a string token, %f is a float, an %d is an integer):

The subset of the mtl files you need to support consists of:

If you ignore any lines you do not support, you will automatically correctly handle comments lines that start with a '#'

The obj format has separate indices for each of v, vt and vn. You will need a unique element in the GPU vertex array if any of the v, vt or vn indices differ, but should share the same vertex array element if all three indices are the same. You can compute a mapping from the v/vt/vn tuple to GPU vertex-array index using the std::map data structure.

Kd only Ka/Kd/Ks/Ns
fancy sphere fancy sphere

Extra Credit

Also support textures for the other material parameters: "map_Ka", "map_Ks", and "map_Ns". In each case, the map will multiply the existing Ka, Ks, or Ns value. With the sample files provided, you'll also need to support the -imfchan map option to specify a specific channel (r, g, or b) to use. Probably the biggest part of this extra credit will be extending the C++ code and object.frag code to support additional textures.


634 students

In the full format, "f" lines are allowed to leave off the vt or vn indices, allowing one of "v", "v/vt", or v//vn" in addition to the fully-specified "v/vt/vn". You should extend your code to support any of these. You can assume any one sub-object (set of "f" lines associated with one "usemtl") will all use the same set of v, vt, and/or vn.

If the vn index is missing, you will need to estimate it based on a weighted average of the adjacent triangle normals for all of the faces sharing that vertex within one usemtl block, using a weight for each triangle normal of 1/TriangleArea. Since the un-normalized triangle normal, triNormal, has a length proportional to the triangle area, you can get the appropriately weighted contribution by accumulating triNormal/dot(triNormal,triNormal). See Nelson Max, "Weights for computing vertex normals from facet normals", Journal of Graphics Tools, v4n2, 1999.

Sample obj files

You can find some sample obj and mtl files in your GLapp/data directory. These are:

What to turn in

Do your development in the GLapp directory so we can find it. Also include an assn3.txt file at the top level of your repository telling us about your assignment. Tell us what works, and what does not. Also tell us what (if any) help you received from books, web sites, or people other than the instructor and TA.

Turn in this assignment electronically by pushing your source code to your class git repository by 11:59 PM on the day of the deadline and tagging the commit assn3. See the assn0 project description if you accidentally tag the wrong commit and need to retag.

You must make multiple commits along the way with useful checkin messages. We will be looking at your development process, so a complete and perfectly working assignment submitted in a single checkin one minute before the deadline will NOT get full credit. Individual checkins of complete files one at a time will not count as incremental commits. Do be sure to check in all of your source code, but no build files, log files, generated images, zip files, libraries, or other non-code content.