This page was last updated: September 13, 2022
The goal of this project is to create a 3D animated scene that demonstrates dynamic OpenGL lighting.
|Category||Minimum number||Minimum number|
|Light motion||2 stationary||1 moving|
|Light types||1 point||1 spotlight|
|Light colors||1 white||1 colored|
|Object material||1 shiny||1 dull|
|Object glShadeModel||1 GL_FLAT||1 GL_SMOOTH|
|Object motion||1 stationary||1 moving|
|Object texture||1 lighted and textured||1 lighted, not textured|
|'0'||Toggle light #0 off/on|
|'1'||Toggle light #1 off/on|
|'2'||Toggle light #2 off/on|
|'f'||Freeze/un-freeze the animation|
The 'f' key is implemented by turning the Idle Function on and off, like in Project #3:
bool Frozen; // declare this as a global Frozen = false; // set this in Reset( ) // in Keyboard( ): case 'f': case 'F': Frozen = ! Frozen; if( Frozen ) glutIdleFunc( NULL ); else glutIdleFunc( Animate ); break;
The number keys are implemented something like this:
bool Light0On, Light1On, Light2On; // declare these as globals Light0On = Light1On = Light2On = false; // set these in Reset( ) // in Keyboard( ): case '0': Light0On = ! Light0On; break; case '1': Light1On = ! Light1On; break; case '2': Light2On = ! Light2On; break; // in Display( ): if( Light0On ) glEnable( GL_LIGHT0 ); else glDisable( GL_LIGHT0 ); if( Light1On ) glEnable( GL_LIGHT1 ); else glDisable( GL_LIGHT1 ); if( Light2On ) glEnable( GL_LIGHT2 ); else glDisable( GL_LIGHT2 );
Deliberately time the animation like we've seen before. Here is a good way to do that. Set a constant called something like MS_PER_CYCLE that specifies the number of milliseconds per animation cycle. Then, in your Idle Function, query the number of milliseconds since your program started and turn that into a floating point number between 0. and 1. that indicates how far through the animation cycle you are. So, in Animate, you might say:
int ms = glutGet( GLUT_ELAPSED_TIME ); ms %= MS_PER_CYCLE; Time = (float)ms / (float)MS_PER_CYCLE; // [0.,1.)and then in Display, you might use that 0.-1. number something like this:
glRotatef( 360.*Time, 0., 1., 0. );
If you want to load a .obj file as part of one of your projects,
incorporate the file loadobjfile.cpp
into your own code.
Use this by placing the .obj object into a display list:
int DinoDL; // declare as a global
// in InitLists( ):
DinoDL = glGenLists( 1 );
glNewList( DinoDL, GL_COMPILE );
LoadObjFile( "dino.obj" );
// in Display( ):
glCallList( DinoDL );
Warning! Not all obj files have normals and textures.
Take a look at the lines in the obj file (it is ascii-editable).
If you see lines of text beginning with vn, it has normals.
If you see lines of text beginning with vt, it has texture coordinates.
One of the things that you are supposed to learn from this project is that lighting is difficult, especially good lighting. (Unfortunately, even bad lighting is hard...) Next time you see a CG-animated movie, look to see how many people in the credits have the word "Lighting" somewhere in their title. There's a reason the list is so long. Look to see how the lighting is used, how it becomes part of telling a story. Some CG movies can end up being lit with hundreds or thousands of light sources (e.g., Coco).
Use the Teach system to turn in your:
Don't spin a smooth-shaded lighted sphere about an axis through its center! You can't tell that it is spinning. Same goes for any other 360-degree smooth objects like torii and cones.
Note: you don't get credit for these things by just having done them. You get credit by convincing us that your program's lighting behavior is correct. That is, code that looks correct will only get credit if you have made a scene that demonstrates the correct visual lighting behavior.
|Lights: 2 stationary, 1 moving||15|
|Lights: 1 point, 1 spotlight||15|
|Lights: 1 white, 1 colored||15|
|Objects: 1 stationary, 1 moving||15|
|Objects: 1 shiny, 1 dull||15|
|Objects: 1 GL_FLAT, 1 GL_SMOOTH||10|
|Objects: 1 textured+lighted||10|
|Small unlit spheres to show the where the light sources are||5|