CS 424: Computer Graphics, Fall 2017
Lab 6: Light and Material in OpenGL 1.1

This lab asks you to make some 3D objects and place them on a "stage." The user can rotate the stage about the y-axis by dragging the mouse horizontally. The scene uses lighting, and the objects will need materials. Initially, only basic lighting is turned on. As part of the lab, you will have to improve the lighting. Some of the objects will be GLUT shapes, which come with the necessary normal vectors. But some will be polyhedra that you need to draw yourself, using data from a collection of polyhedron objects.

You can do this lab in either Java or C. To do the lab in Java, you will need the files Lab6.java and Polyhedron.java, which you can find in /classes/cs424/lab6-files-java. To do the lab in C, you will need the files lab6.c, polyhedron.c, and polyhedron.h, which you can find in /classes/cs424/lab6-files-c. You will only need to work on one file, Lab6.java or lab6.c. If you choose to work in C, note the compilation command that is given in the comment at the beginning of lab6.c.

This lab is due next Friday, October 13, by 3:00 PM. Submit either the file Lab6.java or the file lab6.c to your homework folder in /classes/cs424/homework.

Working with Materials

The program has a two dimensional array named materials that contains material properties that are supposed to imitate some actual common materials such as bronze and green plastic. I would like you to use some of these materials on your objects.

Each row of the array specifies a material. A row is a 13-element array of floats. The meaning of the data is described in a comment in the program. It will be convenient to have a subroutine that takes a 13-element array of floats and uses the data from the array to set the OpenGL material properties. (Actually, the code for using an array of this form in both C and Java can be found in Subsection 4.2.1.)

Add Some GLUT Objects

To begin, use GLUT to draw several objects on the stage. The objects should look like they are standing on the stage, not floating above it. In some cases, you might want an object that actually extends inside the stage. For example, you can have an object that looks like a hemisphere by drawing a complete sphere whose equator lies along the stage. The top of the stage lies in the xz-plane, y = 0.

There are more GLUT shapes than we have covered in lab or class. Some of them are described near the end of Subsection 3.6.1. The full lists for JOGL and for FreeGLUT can be found online. (Don't miss the teapot and torus!)

At least one object should be a GLUT wireframe object that is drawn with lighting disabled. Remember that when lighting is disabled, color is set by glColor*. Also, note that it is possible to increase the line width by calling glLineWidth(w), where w is specified in pixels. GLUT has commands for drawing wireframes, such as glutWireSphere() and glutWireCone(). The wireframe versions have the same parameters as the solid versions.

Aside from the wireframes, each of the other GLUT objects should have its own material.

Add Some Polyhedra

The file Polyhedron.java (for Java)—or the files polyhedron.c and polyhedron.h (for C)—defines the following variables of type Polyhedron that represent various polyhedra:

dodecahedron
icosahedron
octahedron
rhombicDodecahedron
socerBall
stellatedDodecahedron
stellatedIcosahedron
stellatedOctahedron
tetrahedron
truncatedIcosahedron
truncatedRhombicDodecahedron

You can view these polyhedra, without lighting, in the demo, polyhedron-viewer, from Subsection 3.4.1.

An object, poly, of type Polyhedron has properties poly.vertices, poly.faces, and poly.faceNormals that define the polyhedron. Read the comment at the start of Polyhedron.java or polyhedron.h for more information. (These properties have different forms in Java and in C; in Java, they are two-dimensional arrays; in C, they are one-dimensional. If you are working in C, in particular, be sure that you understand the data format. Note that in C, the lengths of the arrays are given as additional Polyhedron properties. In Java, of course, the length is a property of the array itself.)

The polyhedra are centered at (0,0,0). Note that there is also a numeric property poly.maxVertexLength that says how big the polyhedron is; this might help you decide by how much the polyhedron needs to be scaled when you add it to the stage.

You should write a subroutine that takes an object of type Polyhedron as parameter and renders the polyhedron. You can use glBegin/glEnd to draw each face. For lighting to work, you need to provide normal vectors. The normal vector that you need for each face can be found in the faceNormals property of the object. Note that the same normal is used for all vertices of a face, since the faces of a polyhedron are flat.

Once you have your subroutine, you should use it to add several polyhedra to the stage, each with its own material.

(If you have the time, you might want to draw the edges of at least some of the polyhedra as well as the faces. To get the edges to look really good, you need to understand "polygon offset," which is covered in Subsection 3.4.1.)

Improve the Lighting

We have not yet covered lights in class. We will do so the day after the lab, and you can wait until after that to do this part of the lab.

The program that you are working on for the lab has only basic lighting. That is, the default GL_LIGHT0 is turned on. This light, by default, has diffuse and specular color both set to (1,1,1,1), and has position set to (0,0,1,0).

You should improve the lighting of the scene. Do not try to make moving lights. Set their positions in the initialization method, the same place where lighting is enabled. Use from two to four lights, including GL_LIGHT0. You might consider adding a point light above the stage and maybe one or two more point lights in front of the stage You might or might not want to keep the default position for light zero. The light positions are set in eye coordinates, with the viewer at (0,0,0), looking in the direction of the negative z-axis.

You will have to set the light colors for the new lights that you add. (The default color is black; that is, if you don't change the color, the light gives off no light at all.) You will not be able to make all of your light colors equal to (1,1,1,1). The problem is that if you have too much light in a scene, the material colors of your objects become saturated and washed out. To get the scene to look good, you will need RGB color components for your lights that are substantially less than 1.0.

Don't Forget Your Midterm Project!

Remember that you should continue to work on the midterm project. Now that we have encountered light and material in OpenGL 1.1, you can think about how you will add material properties to your scene graph. Remember that you don't need to follow the OpenGL API exactly. For example, you might decide to always use the same value for the ambient and diffuse material properties. You might also think about what kind of support for lighting you will provide in your API, if any. (You could leave setting up the lighting to the user of your API.) And you might add some polyhedra to the set of basic objects.