// Copyright (c) David Kabala // Fall 2009 #include #include #include #include class SceneManager { protected: unsigned int _Example; unsigned int _GeoType; GLfloat _Rotation[3]; int _MouseLastX, _MouseLastY; bool _LeftButtonDown; GLfloat _PointLightAngle; GLfloat _PointLightRadius; int _PlaneSegments; public: SceneManager(void) : _Example(1), _GeoType(1), _MouseLastX(-1), _MouseLastY(-1),_LeftButtonDown(false), _PointLightAngle(0.0f), _PointLightRadius(350.0f),_PlaneSegments(1) { } void init(void) { glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glShadeModel(GL_SMOOTH); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); } void reshape(int w, int h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); GLdouble Aspect = static_cast(w)/static_cast(h); gluPerspective(45.0, Aspect, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); glutPostRedisplay(); } void drawGeometry(void) const { switch(_GeoType) { case 4: drawPlane(190.0,190.0,_PlaneSegments,_PlaneSegments); break; case 3: glutSolidTorus(25.0, 50.0, 24, 24); break; case 2: glutSolidSphere(50.0, 24,24); break; default: case 1: drawBox(100.0,100.0,100.0); } } void drawPointLight(void) const { //Clear the Draw Buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(400.0,400.0,400.0, 0.0,0.0,0.0, 0.0,1.0,0.0); //Rotate the Scene glRotatef(_Rotation[0],1.0f,0.0f,0.0f); glRotatef(_Rotation[1],0.0f,1.0f,0.0f); glRotatef(_Rotation[2],0.0f,0.0f,1.0f); //Define the Light Properties GLfloat light_ambient[] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; //Make this a point light GLfloat light_position[] = { 0.0, 0.0, 0.0, 1.0 }; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position); //Make sure this is not a spotlight glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180.0); //Define the Material Properties GLfloat mat_ambient[] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_emmision[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_shininess[] = { 50.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emmision); //Boxes glPushMatrix(); glTranslatef(200.0,0.0,0.0); drawGeometry(); glPopMatrix(); glPushMatrix(); glTranslatef(-200.0,0.0,0.0); drawGeometry(); glPopMatrix(); glPushMatrix(); glTranslatef(0.0,200.0,0.0); drawGeometry(); glPopMatrix(); //Draw some geometry to represent the light drawLight(light_position,3.0); glutSwapBuffers(); } void drawMovingPointLight(void) const { //Clear the Draw Buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(400.0,400.0,400.0, 0.0,0.0,0.0, 0.0,1.0,0.0); //Rotate the Scene glRotatef(_Rotation[0],1.0f,0.0f,0.0f); glRotatef(_Rotation[1],0.0f,1.0f,0.0f); glRotatef(_Rotation[2],0.0f,0.0f,1.0f); //Define the Light Properties GLfloat light_ambient[] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; //Make this a point light GLfloat light_position[] = { _PointLightRadius*cos(_PointLightAngle), _PointLightRadius*sin(_PointLightAngle), 0.0, 1.0 }; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position); //Make sure this is not a spotlight glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180.0); //Define the Material Properties GLfloat mat_ambient[] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_emmision[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_shininess[] = { 50.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emmision); //Boxes glPushMatrix(); glTranslatef(200.0,0.0,0.0); drawGeometry(); glPopMatrix(); glPushMatrix(); glTranslatef(-200.0,0.0,0.0); drawGeometry(); glPopMatrix(); glPushMatrix(); glTranslatef(0.0,200.0,0.0); drawGeometry(); glPopMatrix(); //Draw some geometry to represent the light drawLight(light_position,3.0); glutSwapBuffers(); } void drawDirectionLight(void) const { //Clear the Draw Buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(400.0,400.0,400.0, 0.0,0.0,0.0, 0.0,1.0,0.0); //Rotate the Scene glRotatef(_Rotation[0],1.0f,0.0f,0.0f); glRotatef(_Rotation[1],0.0f,1.0f,0.0f); glRotatef(_Rotation[2],0.0f,0.0f,1.0f); //Define the Light Properties GLfloat light_ambient[] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; //Make this a directional light GLfloat light_position[] = { 0.0, 1.0, 0.0, 0.0 }; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position); //Make sure this is not a spotlight glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180.0); //Boxes //Define the Material Properties GLfloat mat_ambient_red[] = { 0.3, 0.0, 0.0, 1.0 }; GLfloat mat_diffuse_red[] = { 0.7, 0.0, 0.0, 1.0 }; GLfloat mat_specular_red[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_emmision[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_shininess_red[] = { 50.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_red); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse_red); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular_red); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess_red); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emmision); glPushMatrix(); glTranslatef(200.0,0.0,0.0); drawGeometry(); glPopMatrix(); //Define the Material Properties GLfloat mat_ambient_green[] = { 0.0, 0.3, 0.0, 1.0 }; GLfloat mat_diffuse_green[] = { 0.0, 0.7, 0.0, 1.0 }; GLfloat mat_specular_green[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess_green[] = { 50.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_green); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse_green); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular_green); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess_green); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emmision); glPushMatrix(); glTranslatef(-200.0,0.0,0.0); drawGeometry(); glPopMatrix(); //Define the Material Properties GLfloat mat_ambient_white[] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat mat_diffuse_white[] = { 0.7, 0.7, 0.7, 1.0 }; GLfloat mat_specular_white[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess_white[] = { 50.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_white); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse_white); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular_white); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess_white); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emmision); glPushMatrix(); glTranslatef(0.0,200.0,0.0); drawGeometry(); glPopMatrix(); glutSwapBuffers(); } void drawSpotlight(void) const { //Clear the Draw Buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(400.0,400.0,400.0, 0.0,0.0,0.0, 0.0,1.0,0.0); glRotatef(_Rotation[0],1.0f,0.0f,0.0f); glRotatef(_Rotation[1],0.0f,1.0f,0.0f); glRotatef(_Rotation[2],0.0f,0.0f,1.0f); //Define the Light Properties GLfloat light_ambient[] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; //Make this a spot light GLfloat light_position[] = { 0.0, 150.0, 300.0, 1.0 }; GLfloat light_direction[] = { 0.0, 0.0, -1.0, 0.0 }; GLfloat light_cutoff[] = { 45.0 }; GLfloat light_exp[] = { 10.0 }; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_direction); glLightfv(GL_LIGHT0, GL_SPOT_CUTOFF, light_cutoff); glLightfv(GL_LIGHT0, GL_SPOT_EXPONENT, light_exp); //Boxes //Define the Material Properties GLfloat mat_ambient_red[] = { 0.3, 0.0, 0.0, 1.0 }; GLfloat mat_diffuse_red[] = { 0.7, 0.0, 0.0, 1.0 }; GLfloat mat_specular_red[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_emmision[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_shininess_red[] = { 50.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_red); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse_red); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular_red); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess_red); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emmision); glPushMatrix(); glTranslatef(200.0,0.0,0.0); drawGeometry(); glPopMatrix(); //Define the Material Properties GLfloat mat_ambient_green[] = { 0.0, 0.3, 0.0, 1.0 }; GLfloat mat_diffuse_green[] = { 0.0, 0.7, 0.0, 1.0 }; GLfloat mat_specular_green[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess_green[] = { 50.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_green); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse_green); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular_green); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess_green); glPushMatrix(); glTranslatef(-200.0,0.0,0.0); drawGeometry(); glPopMatrix(); //Define the Material Properties GLfloat mat_ambient_white[] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat mat_diffuse_white[] = { 0.7, 0.7, 0.7, 1.0 }; GLfloat mat_specular_white[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess_white[] = { 50.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_white); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse_white); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular_white); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess_white); glPushMatrix(); glTranslatef(0.0,200.0,0.0); drawGeometry(); glPopMatrix(); //Draw some geometry to represent the light drawLight(light_position,3.0); glutSwapBuffers(); } void drawPlane(GLfloat width, GLfloat height, int X_Segments,int Y_Segments) const { glBegin(GL_QUADS); glNormal3f(0.0,0.0,1.0); for(unsigned int i(0) ; i(i)/X_Segments)*width-width*0.5,(static_cast(j)/Y_Segments)*height-height*0.5, -3.0f); glVertex3f(static_cast(i+1)/X_Segments*width-width*0.5,static_cast(j)/Y_Segments*height-height*0.5, -3.0f); glVertex3f(static_cast(i+1)/X_Segments*width-width*0.5,static_cast(j+1)/Y_Segments*height-height*0.5, -3.0f); glVertex3f(static_cast(i)/X_Segments*width-width*0.5,static_cast(j+1)/Y_Segments*height-height*0.5, -3.0f); } } glEnd(); } void drawBox(GLfloat width, GLfloat height, GLfloat depth) const { //Draw a single quad glBegin(GL_QUADS); //Front glNormal3f(0.0,0.0,1.0); glVertex3f(-width/2.0, -height/2.0, -depth/2.0); glVertex3f(-width/2.0, height/2.0, -depth/2.0); glVertex3f(width/2.0, height/2.0, -depth/2.0); glVertex3f(width/2.0, -height/2.0, -depth/2.0); //Back glNormal3f(0.0,0.0,-1.0); glVertex3f(-width/2.0, -height/2.0, depth/2.0); glVertex3f(width/2.0, -height/2.0, depth/2.0); glVertex3f(width/2.0, height/2.0, depth/2.0); glVertex3f(-width/2.0, height/2.0, depth/2.0); //Top glNormal3f(0.0,-1.0,0.0); glVertex3f(-width/2.0, -height/2.0, -depth/2.0); glVertex3f(width/2.0, -height/2.0, -depth/2.0); glVertex3f(width/2.0, -height/2.0, depth/2.0); glVertex3f(-width/2.0, -height/2.0, depth/2.0); //Bottom glNormal3f(0.0,1.0,0.0); glVertex3f(-width/2.0, height/2.0, -depth/2.0); glVertex3f(-width/2.0, height/2.0, depth/2.0); glVertex3f(width/2.0, height/2.0, depth/2.0); glVertex3f(width/2.0, height/2.0, -depth/2.0); //Right glNormal3f(1.0,0.0,0.0); glVertex3f(width/2.0, -height/2.0, -depth/2.0); glVertex3f(width/2.0, height/2.0, -depth/2.0); glVertex3f(width/2.0, height/2.0, depth/2.0); glVertex3f(width/2.0, -height/2.0, depth/2.0); //Left glNormal3f(-1.0,0.0,0.0); glVertex3f(-width/2.0, -height/2.0, -depth/2.0); glVertex3f(-width/2.0, -height/2.0, depth/2.0); glVertex3f(-width/2.0, height/2.0, depth/2.0); glVertex3f(-width/2.0, height/2.0, -depth/2.0); glEnd(); } void drawLight(const GLfloat* pos, GLfloat radius) const { //Define the Material Properties for the light Sphere GLfloat mat_black[] = { 0.0,0.0,0.0, 1.0 }; GLfloat mat_emissive_white[] = { 1.0, 1.0, 1.0, 1.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_black); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_black); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_black); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emissive_white); glPushMatrix(); glTranslatef(pos[0],pos[1],pos[2]); glutSolidSphere(radius,24,24); glPopMatrix(); } void display(void) const { switch(_Example) { case 4: drawMovingPointLight(); break; case 3: drawSpotlight(); break; case 2: drawDirectionLight(); break; case 1: default: drawPointLight(); break; } } void keyboard(unsigned char key, int x, int y) { switch(key) { case '1': _Example = 1; break; case '2': _Example = 2; break; case '3': _Example = 3; break; case '4': _Example = 4; break; case 'b': _GeoType = 1; break; case 's': _GeoType = 2; break; case 't': _GeoType = 3; break; case 'p': _GeoType = 4; break; case '+': _PlaneSegments += 1; break; case '-': _PlaneSegments -= 1; if(_PlaneSegments < 1) { _PlaneSegments = 1; } break; } glutPostRedisplay(); } void mouse(int button, int state, int x, int y) { if(button == GLUT_LEFT_BUTTON) { _LeftButtonDown = state == GLUT_DOWN; } _MouseLastX = x; _MouseLastY = y; } void mouseDrag(int x, int y) { float MouseDragRotationScale(0.5); if(_MouseLastX >= 0 && _MouseLastY >= 0 && _LeftButtonDown) { int XDiff(x - _MouseLastX), YDiff(y - _MouseLastY); _Rotation[1] += static_cast(XDiff) * MouseDragRotationScale; _Rotation[0] += static_cast(YDiff) * MouseDragRotationScale; glutPostRedisplay(); } _MouseLastX = x; _MouseLastY = y; } void idle(void) { float fTime, fSimTime; float static fLastIdleTime=0; fTime=glutGet(GLUT_ELAPSED_TIME); fSimTime=fTime-fLastIdleTime; GLfloat PointLightOrbitRate(0.001); _PointLightAngle += PointLightOrbitRate*fSimTime; fLastIdleTime=fTime; glutPostRedisplay(); } }; SceneManager mgr; void reshape(int w, int h) { mgr.reshape(w,h); } void display(void) { mgr.display(); } void keyboard(unsigned char key, int x, int y) { mgr.keyboard(key,x,y); } void mouse(int button, int state, int x, int y) { mgr.mouse(button, state,x,y); } void mouseDrag(int x, int y) { mgr.mouseDrag(x,y); } void idle(void) { mgr.idle(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow("Light Examples"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMotionFunc(mouseDrag); glutMouseFunc(mouse); glutReshapeWindow(800,640); glutPositionWindow(50,50); glutKeyboardFunc(keyboard); glutIdleFunc(idle); mgr.init(); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }