/* kronos3.c * CS425, * * This program demonstrates the use of a hierarchical model. * * Kronos, the alien machine from the golden age of Sci-Fi is drawn. * Then a bunch of clones are drawn to demonstrate multiple calls to the * object hierarchy. */ #include #include #include /* uncomment to change styles #define MY_STYLE GL_LINE_LOOP */ #define MY_STYLE GL_POLYGON /* DELTA_RAD is the increment for rotation, useful for * different speed computers. Set lower to slow down rotation. */ #define DELTA_RAD 0.01 #define TWO_PI 2*M_PI #define RAD_TO_DEGREES 57.2958 #define FLASH_DELTA 0.04 #define FLASH_PT_1 TWO_PI/4.0 #define FLASH_PT_2 TWO_PI/3.0 #define FLASH_PT_3 TWO_PI/2.0 #define FLASH_PT_4 TWO_PI/1.3 static double rad=0.0, x=0.0, z=0.0; GLuint theCube; GLuint thePyramid; GLuint theTransformedPyramid; GLuint theWhitePyramid; void draw_kronos_upper(); void draw_kronos(); void draw_scene(); void display(void); void fly_around(void); void draw_kronos_torso(); void draw_kronos_body(); void draw_kronos_leg(); void draw_kronos_sphererod(); void draw_kronos_cuberod(); void myCube(void) { /* Define vertices for the cube */ GLfloat cube_vertices[][3] = { /* 0 */ { -1.0, -1.0, -1.0}, /* 1 */ { 1.0, -1.0, -1.0}, /* 2 */ { 1.0, -1.0, 1.0}, /* 3 */ { -1.0, -1.0, 1.0}, /* 4 */ { -1.0, 1.0, 1.0}, /* 5 */ { 1.0, 1.0, 1.0}, /* 6 */ { 1.0, 1.0, -1.0}, /* 7 */ { -1.0, 1.0, -1.0}, }; /* Define faces of the cube using indices */ GLubyte cube_bottom[] = {0, 1, 2, 3}; GLubyte cube_front[] = {3, 2, 5, 4}; GLubyte cube_left[] = {0, 3, 4, 7}; GLubyte cube_right[] = {1, 2, 5, 6}; GLubyte cube_back[] = {0, 1, 6, 7}; GLubyte cube_top[] = {4, 5, 6, 7}; glEnableClientState(GL_VERTEX_ARRAY); /* initialize pointer to vertex array */ glVertexPointer(3, GL_FLOAT, 0, cube_vertices); /* draw bottom */ glColor3f(1.0, 0.0, 0.0); glDrawElements(MY_STYLE, 4, GL_UNSIGNED_BYTE, cube_bottom); /* draw front */ glColor3f(0.0, 1.0, 0.0); glDrawElements(MY_STYLE, 4, GL_UNSIGNED_BYTE, cube_front); /* draw left */ glColor3f(0.0, 0.0, 1.0); glDrawElements(MY_STYLE, 4, GL_UNSIGNED_BYTE, cube_left); /* draw right */ glColor3f(1.0, 1.0, 0.0); glDrawElements(MY_STYLE, 4, GL_UNSIGNED_BYTE, cube_right); /* draw back */ glColor3f(0.0, 1.0, 1.0); glDrawElements(MY_STYLE, 4, GL_UNSIGNED_BYTE, cube_back); /* draw top */ glColor3f(1.0, 0.0, 1.0); glDrawElements(MY_STYLE, 4, GL_UNSIGNED_BYTE, cube_top); } void mypyramid(void) { /* Define vertices for the cube */ GLfloat pyramid_vertices[][3] = { /* 0 */ {-1.0, -1.0, -1.0}, /* 1 */ { 1.0, -1.0, -1.0}, /* 2 */ { 1.0, -1.0, 1.0}, /* 3 */ {-1.0, -1.0, 1.0}, /* 4 */ { 0.0, 1.0, 0.0}, }; GLubyte pyramid_front[] = { 3, 2, 4 }; GLubyte pyramid_right[] = { 2, 1, 4 }; GLubyte pyramid_bottom[] = { 0, 1, 2, 3 }; GLubyte pyramid_back[] = { 0, 4, 1 }; GLubyte pyramid_left[] = { 0, 3, 4 }; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, pyramid_vertices); /* front face */ glColor3f(1.0,0.0,0.0); glDrawElements(MY_STYLE, 3, GL_UNSIGNED_BYTE, pyramid_front); /* right face */ glColor3f(0.0,1.0,0.0); glDrawElements(MY_STYLE, 3, GL_UNSIGNED_BYTE, pyramid_right); /* bottom face */ glColor3f(0.0,0.0,1.0); glDrawElements(MY_STYLE, 4, GL_UNSIGNED_BYTE, pyramid_bottom); /* back face */ glColor3f(1.0,1.0,0.0); glDrawElements(MY_STYLE, 3, GL_UNSIGNED_BYTE, pyramid_back); /* left face */ glColor3f(0.0,1.0,1.0); glDrawElements(MY_STYLE, 3, GL_UNSIGNED_BYTE, pyramid_left); } void fly_around() { rad += DELTA_RAD; if(rad >= TWO_PI) rad=0.0; z = cos(rad); x = sin(rad); glutPostRedisplay(); } void myinit (void) { /* theCube = glGenLists(1); glNewList(theCube, GL_COMPILE); myCube(); glEndList(); /* thePyramid = glGenLists(1); glNewList(thePyramid, GL_COMPILE); mypyramid(); glEndList(); theCube = thePyramid; glShadeModel (GL_FLAT); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(60.0, 1.0, 1.0, 200.0); glMatrixMode (GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 20.0, 50.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glPushMatrix(); glEnable(GL_DEPTH_TEST); } void draw_kronos_torso() { glPushMatrix(); glRotatef(45.0, 0.0, 1.0, 0.0); glScalef(3.0, 2.0, 3.0); glCallList(theCube); glPopMatrix(); } void draw_kronos_body() { glPushMatrix(); glScalef(8.0, 4.0, 8.0); glCallList(theCube); glPopMatrix(); } void draw_kronos_leg() { glPushMatrix(); glScalef(1.0, 4.0, 1.0); glCallList(theCube); glPopMatrix(); } void draw_kronos_legs() { glPushMatrix(); glTranslatef(-6.0, 0.0, -6.0); draw_kronos_leg(); glPopMatrix(); glPushMatrix(); glTranslatef(6.0, 0.0, -6.0); draw_kronos_leg(); glPopMatrix(); glPushMatrix(); glTranslatef(6.0, 0.0, 6.0); draw_kronos_leg(); glPopMatrix(); glPushMatrix(); glTranslatef(-6.0, 0.0, 6.0); draw_kronos_leg(); glPopMatrix(); } void flash_kronos_sphere() { if(rad >= (FLASH_PT_1-FLASH_DELTA) && rad <= (FLASH_PT_1+FLASH_DELTA)) glColor3f(1.0, 0.0, 0.0); else if((rad >= FLASH_PT_2-FLASH_DELTA) && (rad <= FLASH_PT_2+FLASH_DELTA)) glColor3f(1.0, 1.0, 0.0); else if((rad >= FLASH_PT_3-FLASH_DELTA) && (rad <= FLASH_PT_3+FLASH_DELTA)) glColor3f(0.0, 1.0, 1.0); else if((rad >= FLASH_PT_4-FLASH_DELTA) && (rad <= FLASH_PT_4+FLASH_DELTA)) glColor3f(0.0, 1.0, 0.0); else glColor3f(0.8, 0.8, 0.8); } void draw_kronos_sphererod() { glPushMatrix(); /* save before we do this function */ /* draw shaft */ glRotatef(20.0, 1.0, 0.0, 0.0); glTranslatef(0.0, 4.0, 0.0); glPushMatrix(); /* save angle of rotation */ glScalef(0.2, 5.0, 0.2); glCallList(theCube); /* draw sphere */ glPopMatrix(); /* so we don't get scaled sphere */ glTranslatef(0.0, 5.0, 0.0); glColor3f(0.4, 0.8, 0.9); glutSolidSphere(0.8, 10, 10); glPopMatrix(); /* leave the way we found it */ } void draw_kronos_cuberod() { glPushMatrix(); /* save before we do this function */ /* draw shaft */ glRotatef(20.0, 0.0, 0.0, 1.0); glTranslatef(0.0, 4.0, 0.0); glPushMatrix(); /* save angle of rotation */ glScalef(0.2, 5.0, 0.2); glCallList(theCube); /* draw cube */ glPopMatrix(); /* so we don't get scaled cube */ glTranslatef(0.0, 5.0, 0.0); glColor3f(0.9, 0.8, 0.4); glScalef(0.5, 0.5, 0.5); glCallList(theCube); glPopMatrix(); /* leave the way we found it */ } void draw_kronos_upper() { glPushMatrix(); draw_kronos_body(); glTranslatef(0.0, 3.0, 0.0); flash_kronos_sphere(); glutSolidSphere(4.0, 20, 20); glPopMatrix(); glPushMatrix(); glTranslatef(-6.0, 0.0, 0.0); glRotatef(3.0*rad*RAD_TO_DEGREES, 0.0, 1.0, 0.0); draw_kronos_cuberod(); glPopMatrix(); glPushMatrix(); glTranslatef( 6.0, 0.0, -1.0); glRotatef(5.0*rad*RAD_TO_DEGREES, 0.0, 1.0, 0.0); draw_kronos_sphererod(); glPopMatrix(); } void draw_kronos() { /* assume you are positioned at the ground * level in the center of the lower body */ /* draw lower body */ glPushMatrix(); glTranslatef(0.0, -6.0, 0.0); draw_kronos_body(); /* draw legs */ glTranslatef(0.0, -8.0, 0.0); draw_kronos_legs(); /* draw torso */ glPopMatrix(); glPushMatrix(); draw_kronos_torso(); /* draw upperbody */ glPopMatrix(); glPushMatrix(); glTranslatef(0.0, 6.0, 0.0); draw_kronos_upper(); glPopMatrix(); /* go back to where you were */ } void draw_scene() { int i,j; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt (x*100.0, 20.0, z*100.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); draw_kronos(); glTranslatef(0.0, -20.0, 0.0); glPushMatrix(); for(i=1; i<10; i++) for(j=1;j<10;j++) { glPopMatrix(); glPushMatrix(); glTranslatef((float)i*10.0-50.0, 0.0, j*10.0-50.0); glScalef(0.2, 0.2, 0.2); draw_kronos(); } glPopMatrix(); } void display (void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); draw_scene(); glFlush(); glutSwapBuffers(); } void myReshape(int w, int h) { glViewport (0, 0, w, h); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: /* escape key */ exit(0); break; } } /* Main Loop * Open window with initial window size, title bar, * RGB display mode, and handle input events. */ int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (500, 500); glutCreateWindow (argv[0]); myinit (); glutIdleFunc(fly_around); glutReshapeFunc (myReshape); glutDisplayFunc(display); glutKeyboardFunc (keyboard); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }