{{FULL_COURSE}} Homework 4 - Scene Graph


0 Goal

To familiarize yourself with OpenGL and extend your knowledge of object-oriented programming and memory management.

1 Supplied Code

We will provide you with a basic Qt GUI that consists of only a window with an OpenGL widget. The supplied code will also contain an example of techniques for drawing shapes with OpenGL using Vertex Buffer Objects. You can also create your own Qt project from scratch with an OpenGL widget and add the requisite files if you so choose. You are free to organize your code and classes however you like as long as they adhere to the requirements outlined below.

This homework is particularly notable because it is a standalone assignment; you will not need to incorporate any code from homeworks 1, 2, or 3 into this project. Instead of using the linear algebra libraries you wrote for the first homework assignment, we have provided you with a code library called GLM. Its functions and classes use the same terminology as the linear algebra libraries you wrote, such as vec4 and mat4, so it should be fairly easy to pick up.

When your project runs successfully, you should see the following scene (yes, that black area on top of the sphere is expected due to a missing triangle):

Click here to download the code.

2 Help Log (5 points)

Maintain a log of all help you receive and resources you use. Make sure the date and time, the names of everyone you work with or get help from, and every URL you use, except as noted in the collaboration policy. Also briefly log your question, bug or the topic you were looking up/discussing. Ideally, you should also the answer to your question or solution to your bug. This will help you learn and provide a useful reference for future assignments and exams.

3 Conceptual Questions (15 points)

Before you begin the programming portion of this homework assignment, read and answer the following conceptual questions. Your answers should be written in your readme.txt file along with your documentation of your project.

4 Code Requirements (80 points)

This homework has four main components: coding and building your scene graph, using OpenGL functions to pass geometry from your CPU to your GPU, writing GLSL shader code, and adding a simple Qt GUI element to display your nodes. They are all fairly independent of each other, so do not feel compelled to complete each section below in the order in which they are presented.

4.1 Scene Graph Classes (15 points)

A scene graph is a node-based tree data structure used to organize geometry in computer graphics. You will create a basic Node class which should support the following features:

When creating your basic node class, please make sure that you use pointers for your member variables. Stack-based nodes will cease to exist once your program execution leaves their scope. Note that some of the pointers listed above may be NULL. For example, a leaf node will have no children pointers. Any node may have geometry; that property is not restricted to leaf nodes.

You will also create three classes that inherit from your basic Node class: TranslateNode, RotateNode, and ScaleNode. Each subclass node should support the following feature:

Store the root node of your scene graph in MyGL.

4.2 Scene Graph Traversal (10 points)

Inside MyGL, write a recursive function that traverses your scene graph. This function should take in a node and a 4x4 matrix (in your initial call to this function, you should pass in your scene graph's root note and an identity matrix). Within the body of this function, you should call ShaderProgram::draw on a node's geometry if that geometry is non-null.

4.3 Polygon Primitives with Vertex Buffer Objects (20 points)

Your scene graph should be able to render transformed cubes, transformed cylinders, and transformed spheres using OpenGL's vertex buffer objects. We have provided the code to build and render cylinders and spheres, but it's up to you to implement cube building, uploading, and rendering. Refer to the Cylinder and Sphere classes for how you might choose to go about constructing your cube class.

4.4 Character (15 points)

Create and render a scene graph that uses primitives to form a creature. The code creating your creature should be easy to read and modify so we can easily adjust your graph's transformations when testing it. The creature has to have the following parts:

You should call your puppet construction function from MyGL::initializeGL. You should not construct your scene graph in MyGL::paintGL.

4.5 Fragment shader: Lambertian reflection (10 points)

Implement the Lambertian reflection model in your OpenGL viewer by adding code to the main functions of lambert.vert.glsl and lambert.frag.glsl. Among other data, you will have to pass surface normal data from your vertex shader to your fragment shader in order to accomplish this. Take note of the comments in the shader files if you feel stuck.

4.6 Qt GUI: QTreeWidget (5 points)

Add a QTreeWidget to your GUI in order to visualize the structure of your scene graph. We will post detailed instructions on how to complete this requirement after we discuss Qt GUIs in class. Here is a brief list if you want to get a head start:

5 Extra Credit (Maximum 30 points)

If you implement any extra credit features, please note them in your readme.txt file. If applicable, also explain how to activate or use your additional feature(s).

5.1 Additional polygon primitives (Variable points)

Create additional geometry classes that inherit from Drawable and add them to your puppet. The surface normals on these geometries should be blended where appropriate (e.g. on the "barrel" of a cylinder) and sharp where appropriate (e.g. between an endcap and barrel of a cylinder).

5.2 Texture mapping in OpenGL (30 points)

Associate a texture with each geometry primitive and draw that geometry using that texture rather than the color defined by a node. You will have to create a VBO for UVs in the Drawable class and handle its generation in the create() function of your geometries. Refer to the OpenGL documentation for information on OpenGL's sampler classes that are used in shader files. We also recommend OpenGLTutorial.org for help with more advanced OpenGL features like texture mapping.

5.3 Animation (10 - 20 points)

Use the QTimer created in GLWidget277 to drive an animation of your node attributes. To facilitate this, you might consider having each node store a set of floating point numbers to represent its transformation rather than a 4x4 matrix. For example, the TranslateNode would store three floats, one for each axis of translation. The function that returns a node's 4x4 matrix would instead compute a matrix on the fly based on these numbers.

Note that if you implement this functionality, you must not instantiate your scene graph more than once. You should modify your nodes' attributes every timer tick instead.

The more complex your animated scene, the more points you will be awarded.

6 Submission

Make sure your homework compiles in the Moore labs. We will deduct points from any homework that does not compile, and possibly give a 0 grade if the compile errors are numerous. After you have tested your program, zip the topmost folder of your project and submit the zip to the class web site. Remember to submit your help log and your readme. Additionally, make sure to remove any .git folders as well as any folders created when Qt Creator compiles your program (e.g. folders with a name like "build-460-Desktop-Debug").