/* * Student Name: Stellios Keskinidis * Student Number: 02412012 * * 3D Rotating Lighthouse beam animation with reflecting * light off several objects and immersed in water */ /* glut library, includes all of gl */ #include /* require trigonometric functions */ #include /* require NULL */ #include /* bitmap font for writing text */ #define FONT GLUT_BITMAP_HELVETICA_18 /* light source distance from 0,0 on Z axis, radius */ #define lightRadian 1.0 /* increase rotation of light source angle */ #define lightIncrement 1.0 /* text logo to draw on the screen */ char *logo="02412012 - Lightbeam Animations."; /* moving object angles */ GLfloat rotateLight=0, /* light source angle */ rotateCelestial1=120, /* celestial body 1 angle */ rotateCelestial2=230, /* celestial body 2 angle */ rotateCelestial3=30, /* celestial body 2 angle */ lightx=0, /* x position of light source */ lightz=0, /* z position of light source */ maxLightx=lightRadian, /* max x position of light source */ minLightx=-lightRadian, /* max x position of light source */ maxLightz=lightRadian, /* max z position of light source */ minLightz=-lightRadian; /* max z position of light source */ /* window size coordinates */ int windowHeight=640,windowWidth=640; /* determine which light source coordinate value to * increment or decrement, this is used to rotate * light source in eliptical (circular) orbit around * the lighthouse roof in sync with the 'light beam' (cone) */ GLboolean incrementLightz=1,incrementLightx=1; /* quadratic for drawing 3D shapes */ GLUquadricObj *quad; /* lighting properties */ GLfloat specularLight[]={0.4f,0.4f,0.4f,0.4f},/* specular lighting */ diffuseLight[]={0.1f,0.1f,0.1f,0.1f}, /* diffuse lighting */ ambientLight[]={0.1f,0.1f,0.1f,0.1f}, /* ambient lighting */ lightPosition[]={0.0f,0.0f,0.0f,1.0f},/* light position, 1.0 indicates position */ lightEmission[]={0.2f,0.2f,0.2f,0.2f},/* light emmision */ shine[]={65.0f}; /* 'shininess' of object surfaces */ /* display list variables */ GLuint lhRoofList, /* roof object */ lhUpperList, /* upper part of ligthouse */ lhLowerList, /* lower part of ligthouse */ lhLightBeamList, /* light beam */ lhBgCelestial1, /* celestial body in background */ lhBgCelestial2, /* celestial body in background */ lhBgIceberg, /* iceberg on the side of the lighthouse */ lhOcean; /* ocean water */ /* initialisation method, what we only have to do once * and before anything else here */ void init(void) { /* setup lighting, animation and default background color properties */ glClearColor(0.1,0.1,0.1,0.1); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_COLOR_MATERIAL); /* set lighting properties, use GL_FRONT as there are no reflections for GL_BACK*/ glMaterialfv(GL_FRONT,GL_SPECULAR,specularLight); glMaterialfv(GL_FRONT,GL_AMBIENT,ambientLight); glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuseLight); glMaterialfv(GL_FRONT,GL_SHININESS,shine); /* initialise quadratic for drawing 3D objects */ quad = gluNewQuadric(); /* lighthouse roof */ lhRoofList = glGenLists(1); glNewList(lhRoofList,GL_COMPILE); glShadeModel(GL_SMOOTH); glColor3f(0.5f,0.1f,0.0f); gluSphere(quad,0.5,20,20); glEndList(); /* top part of lighthouse under roof */ lhUpperList = glGenLists(2); glNewList(lhUpperList,GL_COMPILE); glShadeModel(GL_FLAT); glColor3f(0.5f,0.5f,0.6f); gluQuadricDrawStyle(quad,GLU_FILL); gluQuadricNormals(quad,GLU_SMOOTH); gluCylinder(quad,0.5,0.5,1.5,50,20); glEndList(); /* bottom part of lighthouse */ lhLowerList = glGenLists(3); glNewList(lhLowerList,GL_COMPILE); glShadeModel(GL_FLAT); glColor3f(0.2f,0.2f,0.2f); gluQuadricDrawStyle(quad,GLU_FILL); gluQuadricNormals(quad,GLU_SMOOTH); gluCylinder(quad,0.6,0.5,1.0,50,20); glEndList(); /* create visual light beam, cone and cylinder */ lhLightBeamList = glGenLists(4); glNewList(lhLightBeamList,GL_COMPILE); glShadeModel(GL_FLAT); glEnable(GL_BLEND); /* translucent light beam */ glColor4f(1.0f,1.0f,0.0f,0.5f); /* yellow */ glBlendFunc(GL_SRC_ALPHA,GL_ONE); gluQuadricDrawStyle(quad,GLU_FILL); gluQuadricNormals(quad,GLU_SMOOTH); glutSolidCone(0.2,1.0,10,100); /* draw both light beams */ glColor4f(1.0f,0.8f,0.0f,0.5f); /* yellow */ gluCylinder(quad,0.1,0.5,0.8,30,10); glDisable(GL_BLEND); glEndList(); /* background object, sphere like celestial body */ lhBgCelestial1 = glGenLists(5); glNewList(lhBgCelestial1,GL_COMPILE); gluSphere(quad,0.5,10,20); glEndList(); /* background object, sphere like celestial body */ lhBgCelestial2 = glGenLists(6); glNewList(lhBgCelestial2,GL_COMPILE); glColor3f(0.6f,0.2f,0.4f); gluSphere(quad,0.2,20,25); glEndList(); /* draw iceberg, actually under the lighthouse * using vector list this time to demonstrate * ability to draw objects not just with quadratic */ lhBgIceberg = glGenLists(7); glNewList(lhBgIceberg,GL_COMPILE); glLoadIdentity(); glTranslatef(0.9f,-0.5f,0.2f); glRotatef(30.0f,0.4f,0.4f,0.3f); glBegin(GL_QUADS); glShadeModel(GL_SMOOTH); /* draw pyramid using vertices, 3 vertices 4 faces */ glColor3f(0.1f,0.1f,0.4f); glVertex3f(0.0f,0.3f,0.0f); /* top side */ glVertex3f(-0.3f,-0.3f, 0.3f); /* left side */ glVertex3f( 0.3f,-0.3f, 0.3f); /* right side */ glColor3f(0.1f,0.7f,0.1f); glVertex3f( 0.0f, 0.3f, 0.0f); glVertex3f( 0.3f,-0.3f, 0.3f); glVertex3f( 0.3f,-0.3f, -0.3f); glColor3f(0.3f,0.3f,0.7f); glVertex3f( 0.0f, 0.3f, 0.0f); glVertex3f( 0.3f,-0.3f, -0.3f); glVertex3f(-0.3f,-0.3f, -0.3f); glColor3f(0.2f,0.3f,0.1f); glVertex3f( 0.0f, 0.3f, 0.0f); glVertex3f(-0.3f,-0.3f,-0.3f); glVertex3f(-0.3f,-0.3f, 0.3f); glEnd(); glEndList(); } void display(void) { /* clear buffers for color writing and depth */ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); /* draw roof of the light house */ glPushMatrix(); glTranslatef(0.0f,1.45f,0.0f); glCallList(lhRoofList); glPopMatrix(); /* draw upper part of light house */ glPushMatrix(); glTranslatef(0.0f,-0.15f,0.0f); glRotatef(280.0f,0.2f,0.0f,0.0f); glCallList(lhUpperList); glPopMatrix(); /* draw lower part of light house */ glPushMatrix(); glTranslatef(0.0f,-1.0f,0.0f); glRotatef(280.0f,0.2f,0.0f,0.0f); glCallList(lhLowerList); glPopMatrix(); /* draw light beam */ glPushMatrix(); glTranslatef(0.0f,1.5f,0.0f); glRotatef(rotateLight,0.0f,1.0f,0.0f); glCallList(lhLightBeamList); glPopMatrix(); glPushMatrix(); glTranslatef(lightPosition[0],lightPosition[1],lightPosition[2]); glLightfv(GL_LIGHT0,GL_POSITION,lightPosition); glMaterialfv(GL_LIGHT0, GL_EMISSION,lightEmission); glutWireCube(0.1); glPopMatrix(); /* draw celestial body */ glPushMatrix(); glTranslatef(2.0f,1.2f,-14.0f); glRotatef(rotateCelestial1,1.2f,1.5f,8.2f); glColor3f(0.1f,0.1f,0.2f); glCallList(lhBgCelestial1); glPopMatrix(); /* draw celestial body */ glPushMatrix(); glTranslatef(-1.0f,2.2f,1.0f); glRotatef(rotateCelestial1,3.2f,0.5f,3.2f); glColor3f(0.2f,0.3f,0.6f); glCallList(lhBgCelestial1); glPopMatrix(); /* draw second celestial body */ glPushMatrix(); glTranslatef(-1.2f,1.2f,-10.0f); glRotatef(rotateCelestial2,0.2f,1.0f,0.0f); glCallList(lhBgCelestial2); glPopMatrix(); glPushMatrix(); glTranslatef(-2.2f,2.0,3.0f); glRotatef(rotateCelestial2,0.2f,1.0f,0.0f); glCallList(lhBgCelestial2); glPopMatrix(); /* draw quadric objects (rocks) underneath lighthouse */ glPushMatrix(); /* draw cube under lighthouse */ glColor3f(0.3f,0.2f,0.8f); glTranslatef(-0.2f,-1.3f,0.5f); glRotatef(115.0f,0.3f,0.2f,0.4f); glutSolidCube(0.5); /* draw another cube under lighthouse */ glColor3f(0.3f,0.2f,0.4f); glTranslatef(-0.2f,-0.5f,0.5f); glRotatef(155.0f,0.3f,0.2f,0.4f); glutSolidCube(0.6); /* draw another cube under lighthouse */ glColor3f(0.4f,0.1f,0.2f); glTranslatef(-0.5f,0.3f,0.2f); glRotatef(55.0f,0.3f,0.2f,0.4f); glutSolidCube(0.3); /* draw another cube under lighthouse */ glColor3f(0.4f,0.2f,0.1f); glTranslatef(-1.0f,-1.0f,0.7f); glRotatef(65.0f,0.5f,0.4f,0.1f); glutSolidCube(0.8); /* draw sphere under lighthouse */ glColor3f(0.6f,0.3f,0.1f); glTranslatef(1.5f,0.2f,0.0f); glRotatef(65.0f,0.5f,0.4f,0.0f); glutSolidSphere(0.5,20,20); glPopMatrix(); /* draw icerberg, actually just a rock on the side of lighthouse */ glPushMatrix(); glCallList(lhBgIceberg); glPopMatrix(); /* draw ocean water as a translucent blue smooth shaded square */ glPushMatrix(); glLoadIdentity(); glShadeModel(GL_SMOOTH); /* enable blend for translucent ocean */ glEnable(GL_BLEND); glColor4f(1.0f,1.0f,0.0f,0.5f); /* yellow */ /* translucent ocean */ glBlendFunc(GL_SRC_ALPHA,GL_ONE); /* draw ocean using 4 vertices */ glBegin(GL_QUADS); /* blend ocean color, dark to lighter blue */ glColor3f(0.0f,0.0f,1.0f); glVertex3f(-4.5f, -0.1f, -20.0f); /* top left */ glColor3f(0.2f,0.2f,0.9f); glVertex3f(4.5f, -0.1f, -20.0f); /* top right */ glColor3f(0.2f,0.3f,0.8f); glVertex3f(4.5f,-3.0f, 25.0f); /* bottom right */ glColor3f(0.3f,0.3f,0.7f); glVertex3f(-4.5f,-3.0f, 25.0f); /* bottom left */ glEnd(); glDisable(GL_BLEND); /* turn off translucency */ glPopMatrix(); /* draw text at top of screen */ /* color of text */ glColor3f(1.0f,0.9f,0.1f); /* position of text */ glRasterPos3f(0.0f,3.0f,-0.5f); { /* write text character by character */ int i; for(i=0;i=360) rotateCelestial1=0; else rotateCelestial1+=2; /* rotate the second celestial body */ if(rotateCelestial2>=360) rotateCelestial2=0; else rotateCelestial2+=5; /* rotate the third (dodacehedron) celestial body */ if(rotateCelestial3>=360) rotateCelestial3=0; else rotateCelestial3+=0.5; lightPosition[0]=rotateLight; /* update position of light source * light source follows a circular motion */ /* should we increment or decrement the X axis? */ if(lightx>=maxLightx) { incrementLightx=0; } else if(lightx<=minLightx) { incrementLightx=1; } /* should we increment or decrement the Z axis? */ if(lightz>=maxLightz) { incrementLightz=0; } else if(lightz<=minLightz) { incrementLightz=1; } /* perform increment/decrement of X and Z axis of light source */ if(incrementLightx==1) lightx+=lightIncrement; else lightx-=lightIncrement; if(incrementLightz==1) lightz+=lightIncrement; else lightz-=lightIncrement; /* rotate light beam angle */ /* performed full rotation, reset to 0 */ if(rotateLight>=360) rotateLight=0; rotateLight+=lightRadian; /* calculate position of light source based on the angle * of the rotation of the cylinder and cone lights */ /* calculate z axis */ lightz=lightRadian*(cos(rotateLight/57.5)); /* calculate x axis */ lightx=lightRadian*(sin(rotateLight/57.5)); /* update light source position with new x and z axis */ lightPosition[0]=lightx; lightPosition[1]=1.5; lightPosition[2]=lightz; /* call timer for 100 milliseconds to reduce cpu overload */ glutTimerFunc(100,NULL,1); /* update display 'show' animation */ glutPostRedisplay(); } int main(int argc, char *argv[]) { /* initialise glut library */ glutInit(&argc, argv); /* set the initial display mode */ glutInitDisplayMode (GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); /* initial window size */ glutInitWindowSize(windowHeight,windowWidth); /* create window with logo on title bar */ glutCreateWindow(logo); /* other initialisation that needs to be done */ init(); /* set the resize window function */ glutReshapeFunc(resize); /* drawing and display function */ glutDisplayFunc(display); /* idle function, rotations and angle calculations */ glutIdleFunc(animate); /* enter event processing loop */ glutMainLoop(); return 0; } /* a2_lh.c */