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 GLlibs.zip 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):
- "mtllib %s": A reference to a .mtl material library file in the same directory as the .obj
- "usemtl %s": The material (from the mtl file) to use for the upcoming geometry
- "v %f %f %f": 3D vertex position for a vertex
- "vt %f %f": 2D texture coordinate for a vertex
- "vn %f %f %f": 3D normal for a vertex
- "f %d/%d/%d %d/%d/%d ...": Describes a polygonal face, where each "%d/%d/%d" is one vertex.
- The three integers are which vertex position (v), texture coordinate (vt), and normal (vn) to use.
- Each counts independently from 1, so 3/2/1 would be the 3rd 'v' line for the vertex position, 2nd 'vt' line for the texture coordinate, and 1st 'vn' line for the normal.
- If there are more than three vertices in the "f" line, split them into a triangle fan.
The subset of the mtl files you need to support consists of:
- "newmtl %s": The name of a new material, to be defined in the next few lines of the file
- "Ka %f %f %f": The ambient color for the current material
- "Kd %f %f %f": The diffuse color for the current material
- "Ks %f %f %f": The specular color for the current material
- "Ns %f": The specular exponent for the current material
- "map_Kd %s": Multiply Kd by the contents of an image texture map
- The file name is relative to the directory containing the mtl file
- All of your textures will be in ppm format.
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.
Sample obj files
You can find some sample obj and mtl files in your GLapp/data directory. These are:
- For the base assignment, castle/castle.obj, castle/castle.mtl, and associated ppm textures.
- For the extra credit, sphere.obj, sphere.mtl, and the paving-color.ppm and paving-props.ppm texture files
- For the 634 part, teapot/teapot.obj and teapot/teapot.mtl
- As a simple file easily hand-edited for testing, hex.obj and hex.mtl
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.