Difference between revisions of "Project5SP15"

From Immersive Visualization Lab Wiki
Jump to: navigation, search
(1. Texturing)
(Project 5: Textures and Scene Graphs)
Line 5: Line 5:
 
=Project 5: Textures and Scene Graphs=
 
=Project 5: Textures and Scene Graphs=
  
In this project you will need to texture your 3D models, and then create a scene graph data structure to render an army of robots.  
+
In this project you will need to put textures on geometry, and create a scene graph data structure to render an army of androids.  
  
You can start out with your code from project 3. But don't worry if your lights don't work perfectly. Perfect lighting won't be necessary in this project, but would be nice to have.
+
You can start out with your code from project 3. Don't worry if your lights don't work perfectly, it will have no impact on this homework project.
 
   
 
   
 
The project is due on <b>Friday, May 8th, 2015 at 1:00pm</b>. You need to present your results in the CSE basement labs as usual, grading starts at 12:15pm.  
 
The project is due on <b>Friday, May 8th, 2015 at 1:00pm</b>. You need to present your results in the CSE basement labs as usual, grading starts at 12:15pm.  

Revision as of 07:27, 2 May 2015

DO NOT START YET - UNDER CONSTRUCTION

Contents

==========================

Project 5: Textures and Scene Graphs

In this project you will need to put textures on geometry, and create a scene graph data structure to render an army of androids.

You can start out with your code from project 3. Don't worry if your lights don't work perfectly, it will have no impact on this homework project.

The project is due on Friday, May 8th, 2015 at 1:00pm. You need to present your results in the CSE basement labs as usual, grading starts at 12:15pm.

The homework discussion for this project will be on Monday, May 4th.

1. Sky Box

Embed your 3D models in a sky box. A sky box is a large box which is drawn around your entire scene and which your scene is inside of. The walls of the box have pictures of a sky and perhaps imagery at the horizon. Sky boxes are typically cubic, which means that they consist of six square textures for the six sides of a cube. Here is is a nice collection of textures for sky boxes.

Draw a cubic sky box around your patch by generating five sides of a cube (all but the bottom - the bottom side will be replaced by your patch) out of large textured GL_QUADS. Position and scale the box so that the patch is at its base, and it snugly hugs the patch.

Make sure single-sided rendering (triangle culling) is enabled with these lines somewhere in your code to ensure the box never occludes your patch:

glEnable(GL_CULL_FACE); 
glCullFace(GL_BACK); 

Use the following settings for your texture after your first glBindTexture for correct lighting and filtering settings:

  // Make sure no bytes are padded:
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

  // Select GL_MODULATE to mix texture with polygon color for shading:
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  // Use bilinear interpolation:
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

To familiarize yourself with texture mapping in OpenGL, we provide a sample program, which loads a PPM file and uses it as a texture for a quad. If you decide to use one of the above referenced sky box images, you will have to convert them from JPEG to PPM format. The free image processing tool IrfanView for Windows will do this for you.

Alternatively, you can use a third party library such as SOIL to natively load JPEG images.

2. Scene Graph Engine

Implement scene graph classes with the following hierarchy:

Project4F14-scenegraph-half.jpg

The classes should have at least the following functionality (5 points for each class):

  • Class Node should be abstract and serve as the common base class. It should implement an abstract draw method: virtual void draw(Matrix4 C) = 0, and also an abstract virtual void update() = 0 method to separate bounding sphere updates from rendering.
  • Group should store a list of pointers to child nodes (std::list<Node*>) and provide functionality to add and remove child nodes (addChild(), removeChild()). Its draw method needs to traverse the list of children and call each child node's draw function.
  • Geode should be an abstract class. It should set OpenGL's ModelView matrix to the current C matrix, and have an abstract render function to render its geometry.
  • MatrixTransform should store a 4x4 transformation matrix M which is multiplied with matrix C, which is passed to the draw method.
  • Sphere should have a draw function which draws a sphere. You can use glutSolidSphere for that.
  • Cube should have a draw function which draws a cube. You can use glutSolidCube for that.

3. Walking Robot

Demonstrate your scene graph functionality by constructing a walking robot.

First get your rendering engine ready to recursively traverse the scene graph for rendering by creating a root node of type Group and calling its draw() function with the identity matrix as its parameter.

The robot should have a torso, head, arms and legs. This means that the robot has to consist of at least 6 instances of Geode-derivatives. You can use the sphere and cube classes for the body parts, and add more shapes as you like (e.g., using any of GLUT's pre-defined shapes). Each Geode-derivative should have a MatrixTransform before it to position the body part(s) below it in the scene graph. You might want some of your basic shapes, such as spheres and cubes, elongated, rotated, or otherwise deformed, which you should do with separate MatrixTransform nodes for (non-uniform) scales, and/or rotations. Note that it is very common to concatenate multiple MatrixTransform nodes in a scene graph, each of which doing a separate affine transformation (e.g., one for position, one for scale, one to rotate). (20 points)

Animate the robot to make it look like it is walking: move arms and legs back and forth by rotating around hip and shoulder joints. You can do this by re-calculating rotation matrices every frame by increasing or decreasing the respective angle by a small amount, up to a limit point at which you reverse the direction. (10 points)

4. Robot Army

Test your implementation by constructing a scene which consists of a sufficiently large amount of your robots to speed up rendering when object culling is used.

  • Distribute the robots on a 2D grid (i.e., place them on a plane with uniform spacing). (5 points)
  • Choose the camera parameters so that many of the robots are located outside of the view frustum (off-screen), so that object-level culling matters. (5 points)
  • Use your rotation and scale routines to allow the user to rotate the grid of 3D objects and zoom in or out. (5 points)
  • Compare the frame rates with and without object-level culling by supporting the keyboard key 'c' to toggle culling on and off, and displaying the rendering rate (frames per second) in the console window for every frame (frames_per_second = 1/rendering_time). Tweak the number of robots, their spatial density, and your camera parameters until your frame rate is noticeably higher with culling enabled. (5 points)

Notes:

  • All your robots need to be walking like in part 2. This means that you need to re-calculate the bounding spheres each frame.
  • For the calculation of the view frustum bounding planes you may want to take a look at the Lighthouse3D web site.

This image illustrates the grid layout of the robots:

Robots.png

5. Extra Credit: Optimization by Culling

Add a bounding sphere (Vector3 for its center point, and a radius) to your Node class, and implement code to update the bounding box parameters in all other classes of your scene graph. You also need to add code to your Node class to display each node's bounding sphere as a wireframe sphere with glutWireSphere. Support the 'b' key to toggle these bounding spheres on and off.

Note: You do not need to find the smallest possible bounding sphere, but can use an approach similar to the one in homework assignment 2:

  • Find minimum and maximum extents of your geometry in x,y and z (bounding box).
  • The center of the bounding sphere is the center of the bounding box.
  • The radius of the bounding sphere is equal to half the diameter of the bounding box.

Extend the Node class to perform view frustum culling using the bounding spheres of the objects. If the bounding sphere of an object is completely outside of the view frustum, the object should be culled (not rendered). Your culling algorithm should make use of a utility function to test whether a bounding sphere intersects with a given plane, or whether the sphere is entirely on one side of the plane.