CS155 Computer Graphics

Cheesy Shadow Labs

Today you'll build a little scene with simple shadows.

  1. Create a new visual studio project with the following code: shadow.cpp. Compile the program and run it. You'll see a red floor, a blue cube, and a white background.


  2. The next step is to draw a basic shadow. To do so you need to Compile and run the code. Problem? Currently the shadow occupies the same place as the floor so you may not see it. To check that it is there, comment out the floor-drawing code, re-compile and run the program. You should see now be able to see the shadow.


  3. Of course we want to have a floor. The problem of drawing two things in the same place is not uncommon and OpenGL provides a solution, called polygon offset. You need to use the command glPolygonOffset(f,u), which can be done in the init routine. (Check out the documentation to help figure out good values for f and u.) You also need to enable polygon offset, glEnable(GL_POLYGON_OFFSET_FILL), before drawing the shadow an disable it after, glDisable(GL_POLYGON_OFFSET_FILL).


  4. Rather than drawing a black shadow, we'd like to blend it with the floor. To do this you need to define a blending function, glBlendFunc(sFactor,dFactor), set the alpha channel of the shadow color, and enable blending, glEnable(GL_BLEND) . Be sure to disable alpha blending when you are done with the shadow.


  5. The shadow will not look right because each polygon of the cube is producing its own shadow. The final shadow is darker in regions where several polygon shadows are drawn. To avoid this you need to use the stencil buffer. Enable the stencil buffer before the floor is originally drawn. Whenever a pixel is drawn to the frame buffer, you should write a "3" to the stencil buffer. When drawing the shadow, compare the stencil buffer to 2. If the stencil value is greater than 2 then draw the shadow pixel and replace the stencil value by 2. A shadow will never be drawn more than once for any pixel and only on pixels where the floor has been drawn. That is it!