CS 424: Computer Graphics, Fall 2017
Lab 5: Starting the Midterm Project
This week's Thursday lab period will give you a chance to start planning and working on the midterm programming project. The project is a larger and longer-term project than the sort of short exercises that we usually do in lab.
No work will be collected or graded for Lab 5. The completed midterm project will be due on October 30 and will count for 10% of your final grade for the course. Lab 8 On October 19 will also be used for working on the midterm project.
The Midterm Project
You are strongly encouraged, but not required, to work with a partner on the midterm project. Ideally, you should find a partner before coming to the lab on Thursday.
The project is to design and implement a scene graph API for OpenGL 1.1. Your scene graph library will let programmers create 3D scenes by constructing a data structure that represents the content of the scene. Your API will define the classes that are used to create the data structure. In addition to the library, you should write several example programs that demonstrate its capabilities. Deciding exactly what capabilities to include is part of the project.
You can spend the Lab 5 period thinking about the overall design of the API, deciding how you will coordinate with your partner (if you have one), and maybe getting started on the programming. To start, the scene graph will be mostly geometry — that is, basic geometric objects and transformations. As we work through the next month of the course, we will encounter more things that might be added to the scene graph, including materials, textures, lights, and cameras. Note that you can take some ideas from my simple 2D scene graph API, but you should not just duplicate it in 3D.
You will probably want to work in Java. If you know C++, you can consider using that. It would be difficult to do the project in plain C, unless you know C very well. A scene graph is a linked, hierarchical data structure containing nodes of several different kinds. In Java and C++, you can define classes to represent the different kinds of scene graph node. It is more difficult in C, where you would need to do rather technical work with pointers, structs, and memory allocation. (Still, if you are interested in knowing how it would be done in C, come in and discuss it with me.)
Assuming that you are working in Java, I suggest that you create a package to hold the classes that define the scene graph. Each class or interface should be in its own file. You should include appropriate Javadoc-style comments in the code. It would be nice to use the Javadoc tool to create actual API documentation web pages for the project. (You can generate Javadoc documentation in Eclipse.)
If you do decide to work in C++ or C, we will have to discuss what would be the best structure for the code.
You will need to make many design decisions as you build your API. We will be discussing many of the issues in class as we work through Chapters 3 and 4. Here are some of the things that you should think about:
- Tree or Dag? A fundamental decision is whether your scene graph will have the structure of a tree. In a tree, a node can have only one parent; in a general dag, a node can have several parents. There are real advantages to using only trees—especially if you are going to allow cameras as nodes in the structure. However, if you do use trees, it's a good idea to have a "copy" method in your nodes that will recursively create a copy of the node and its children. A copy operation will allow you to easily add several copies of a compound object to the scene. Also, for a tree-structured scene graph, it is common to include a parent pointer in each node, which points to the parent of that node in the scene graph.
- Basic Objects. What basic objects will the API support and how? You will want to at least have things like cubes, spheres, and cylinders. (If you like, you can use my TexturedShapes class to actually draw the shapes; they are similar to GLUT shapes, except that, unlike GLUT shapes, they support texturing. You will be using them in a later lab in any case.) Will you have a different class for each type of basic object? Or maybe one BasicObject class, with an instance variable to say which particular basic object it represents? Will there be polyhedral objects? Objects made of lines or points instead of triangles? For objects like spheres and cylinders, will you will rely on transformations to set the size and shape, or you will provide constructors with parameters to set some properties of the objects.
- Other objects. How easy will it be for a programmer to construct other objects, if they want something that is not available as a basic shape? How about support for some kind of indexed face set?
- Representing Transforms. Will you use separate nodes to represent modeling transforms, as was done in my 2D API? Or will you allow every kind of node to have transform properties? (You could do that, for example, by putting the support for transforms in the abstract base class for all node types.) Will you have one or more classes to represent transforms, or will the data for transforms be stored as simple properties of scene graph nodes? Will you allow rotations about arbitrary axes, or just the x-, y-, and z-axes?
- Materials. How will material properties be represented? Will every object have material properties (as was done for color in my 2D API)? Will material properties be inherited by child nodes, or will they only apply to a single node? What are the default material properties?
- Textures. Will you support image textures? How will you get the images into your system?
- Lights as nodes. Will there be nodes to represent lights? As with cameras, that would allow a light to be placed in the scene and subject to transformations, even as part of a compound object. Note that this is not required, although it's a nice feature to have.
- Cameras. Will you have nodes to represent cameras? A camera object usualy represents a viewing transformation along with a projection. (A basic camera class for OpenGL is defined in Camera.java.) Putting a camera into the scene graph would allow it to be transformed like other objects, and even to be part of a compound object so that the point of view can move along with the object (like the viewpoint of the driver of a car). If you have cameras, you need a way to render the scene from the point of view of a given camera. Again, this is not required.
- Global properties. Some properties of the drawing won't be in the scene graph (unless maybe you make a special kind of root node to hold them, or maybe make them properties of a camera). This includes, for example, background color, ambient light, and lights that are independent of the view. Will you provide any support for these aspects of a scene, or will you just provide a scene graph and leave the rest up to the programmer?
Note that you should not try to do everything! You are not expected to include all possible features in your API. If your design is flexible, you should be able to start with a basic set of features and add more later, according to your available time and interest.