Project4F15

From Immersive Visualization Lab Wiki
Jump to: navigation, search

Contents

Project 4: Light and Shade

This project is on OpenGL lighting and shading, and adds support for the mouse.

The project is due on Friday, Oct 30th, 2015 at 2pm. You need to present your results in the CSE basement labs as usual, grading starts at 2:00pm.

The discussion for this project will be on Monday, Oct 26th at 3pm.

From this project on, we will no longer use the software rasterizer, so you don't have to keep the code for it around.

In this project we will only use the bunny, dragon and bear data sets from the last two projects. And we will add a sphere. Your application should switch between the four models with the function keys. Please change the mapping to 'F1' through 'F4'. Nothing should auto-spin like the cube did in assignment 1.

1. Object Centering (20 Points)

First add a sphere to your collection of 3D models. You can render it with glutSolidSphere(). Make it accessible with the 'F1' key.

For the mouse controls we're about to implement to work well, we're going to need to center our 3D models on the screen and normalize their sizes. Write function calls to do both of these things whenever a new model is selected with the function keys. All models should get scaled to the same size, and should fully occupy the OpenGL window, without exceeding it.

Grading

  • -10 if object is not centered
  • -10 if object is not scaled to window size

2. Mouse Control (30 Points)

It is time to support the mouse to control your 3D models. We will no longer use keyboard support to manipulate the models. Add functionality to allow the following operations on your 3D models:

  • While the left mouse button is pressed and the mouse is moved, rotate the model about the center of your graphics window. This is similar to the earlier orbit function, but it should allow rotations in all directions. We will refer to this function as "trackball rotation". This video shows how this should work.
  • When the right mouse button is pressed and the mouse is moved, move the model along the x and y axes of your window. If you don't have a right mouse button, use your mouse button along with a function key.
  • Use the mouse wheel to scale the model about its object space origin. Mouse wheel down should make it smaller, up should make it bigger. You can access the mouse wheel with the callback function glutMouseWheelFunc. This function is not available in the basic version of GLUT. If you don't have it please install FreeGLUT. If you don't have a mouse wheel, simulate it with the mouse cursor up/down keys. To keep the normals of your 3D models pointing in the right directions, put the following OpenGL command in the initialization part of your code: glEnable(GL_NORMALIZE).

Notes on Mouse Support in GLUT

To access the mouse x and y coordinates, you should use GLUT's callback function glutMouseFunc(), which gets called when you press a mouse button, and glutMotionFunc(), which gets called repeatedly while you hold the button down and move the mouse. Note that successive trackball rotations must build on previous ones; at no point should the model snap back to a previous or default position.

Notes on the Trackball Rotation

The figure below illustrates how to translate mouse movement into a rotation axis and angle. m0 and m1 are consecutive 2D mouse positions. These positions define two locations v and w on an invisible 3D sphere that fills the rendering window. Use their cross product as the rotation axis a = v x w, and the angle between v and w as the rotation angle.

Trackball.jpg

Horizontal mouse movement exactly in the middle of the window should result in a rotation just around the y-axis. Vertical mouse movement exactly in the middle of the window should result in a rotation just around the x-axis. Mouse movements in other areas and directions should result in rotations about an axis a which is not parallel to any single coordinate axis, and is determined by the direction the mouse is moved in.

Once you have calculated the trackball rotation matrix for a mouse drag, you will need to multiply it with the object-to-world transformation matrix of the object you are rotating.

For step by step instructions, take a look at this tutorial. Note that the tutorial was written for Windows messages, instead of GLUT mouse functions. This means that you'll need to replace the "CSierpinskiSolidsView::OnLButtonDown" function with "glutMouseFunc", "CSierpinskiSolidsView::OnMouseMove" with "glutMotionFunc", etc. To help you understand the code here is a line-by-line commented version of the trackBallMapping function:

Vec3f CSierpinskiSolidsView::trackBallMapping(CPoint point)    // The CPoint class is a specific Windows class. Either use separate x and y values for the mouse location, or use a Vector3 in which you ignore the z coordinate.
{
    Vec3f v;    // Vector v is the synthesized 3D position of the mouse location on the trackball
    float d;     // this is the depth of the mouse location: the delta between the plane through the center of the trackball and the z position of the mouse
    v.x = (2.0*point.x - windowSize.x) / windowSize.x;   // this calculates the mouse X position in trackball coordinates, which range from -1 to +1
    v.y = (windowSize.y - 2.0*point.y) / windowSize.y;   // this does the equivalent to the above for the mouse Y position
    v.z = 0.0;   // initially the mouse z position is set to zero, but this will change below
    d = v.Length();    // this is the distance from the trackball's origin to the mouse location, without considering depth (=in the plane of the trackball's origin)
    d = (d<1.0) ? d : 1.0;   // this limits d to values of 1.0 or less to avoid square roots of negative values in the following line
    v.z = sqrtf(1.001 - d*d);  // this calculates the Z coordinate of the mouse position on the trackball, based on Pythagoras: v.z*v.z + d*d = 1*1
    v.Normalize(); // Still need to normalize, since we only capped d, not v.
    return v;  // return the mouse location on the surface of the trackball
}

Grading:

  • -5 if rotation is not in world coordinates
  • -5 if object's size changes when rotating
  • -5 if rotation is in opposite direction
  • -10 if rotation is not cumulative
  • -10 if there is no zoom

3. Materials (20 Points)

Select different material properties for each of the 3D model files: make some more shiny, others more diffuse. Use colors other than white. The differences in shininess must be obvious - use extreme settings if you need to.

Grading:

  • -10 if it is hard to tell whether an object is shinier or more diffuse than another.
  • -10 if it is hard to tell the colors of your objects apart.

4. Light Sources (30 Points)

In this part we add more light sources and control them with the mouse.

Write classes to manage lights and their properties (Light). Instead of the default light source from the previous assignments, create three separate light sources: a directional light, a point light and a spot light. Give all of them a bright white color. Choose useful values for the other parameters, so that your models are being nicely illuminated. The spot light should always point to the origin of the world coordinate system.

To visually indicate where the light sources are, draw a glutSolidSphere in the location of point light and spot light.

Give the user control of the lights: make them selectable with the number keys '1', '2', and '3' (for the directional, point and spot lights, respectively). Use the '0' key to de-select and return to controlling the 3D model.

When a light source is selected, your mouse controls should only affect this particular light source. You need to support the following functions, depending on the type of light source:

  • Directional light: rotations change the direction of the light
  • Point light: rotations rotate the light around the origin of the world coordinate system (=center of window). Scaling with the mouse wheel changes the distance of the light from the origin of the world coordinate system.
  • Spot light: should do everything the point light does, plus: when the right mouse button is held down, mouse up/down should make the spot wider/narrower, left/right should make the spot edge sharper/blurrier. Make sure the spot keeps pointing at the center of your window coordinate system even when its position is changed.

Notes:

  • For detailed information and sample code, see Chapter 5 of the OpenGL Programming Guide, as well as the OpenGL Lighting FAQ.
  • By default, OpenGL uses a simplified model for the calculation of the highlights. For a more realistic model add this command to your main() function: glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE).
  • The model color should be white, but this does not mean that the models should show up in bright white - the color should be affected by the light sources instead.

Grading:

  • -10 if the spot light is indistinguishable from a point light (spot too wide)
  • -5 if point or spot light have no visual representations as described (-10 if neither is correctly displayed)
  • -5 for each light if light source representation and source of light don't match

5. Extra Credit: Parameter Editor (10 Points)

Create a visual editor to allow the custom modification of the colors and shading parameters of your light sources and materials. Use the 'e' key to display the color editor (its close button closes it). The editor needs to be exclusively mouse controlled. You can either write your own OpenGL code to generate GUI widgets such as buttons or sliders, or you can use an existing open source library for it, such as GLUI.

For a full score you need to allow the modification of (at least) the following parameters:

  • The current object's shininess parameter.
  • The current object's color.
  • The current light's color.
  • For the spot light: cone angle, edge falloff.
  • For point and spot lights: attenuation mode (constant, linear, quadratic).
  • The current object's material properties for ambient, diffuse and specular reflectivity.