/* cs4451_a2.c */ /* PLEASE PUT YOUR NAME HERE */ #include #include #include #include #include #include #define VPD_MIN 200 #define VPD_DEFAULT 800 #define VPD_MAX 1024 #define MENU_SLOWER 1 #define MENU_FASTER 2 #define MENU_STOP_RUN 3 #define TWOPI (2.0 * M_PI) /* --------------------------------------------- */ GLint wid, /* GLUT window id */ vpd = VPD_DEFAULT; /* (square) viewport dimensions */ /* --------------------------------------------- */ GLuint sceneID; /* display list ID */ /* --------------------------------------------- */ GLfloat angle1 = 0; /* angles used in animation */ GLfloat angle2 = 0; GLfloat dangle1 = 0.57; GLfloat dangle2 = 0.71; GLint animate = 1; /* animate or not? */ /* --------------------------------------------- */ GLvoid init_lightsource ( GLvoid ) { GLfloat light_ambient[] = { .1, .1, .1, 1.0 }; GLfloat light_diffuse[] = { .9, .9, .9, 1.0 }; GLfloat light_specular[] = { 0, 0, 0, 1.0 }; GLfloat light_position[] = { 2.0, 2.0, 2.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); glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,1.0); glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0); glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.0); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } GLvoid set_material_properties ( GLfloat r, GLfloat g, GLfloat b ) { GLfloat mat_specular[4] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_ambient_and_diffuse[4] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat mat_shininess[1] = { 0.0 }; mat_specular[0] = mat_ambient_and_diffuse[0] = r; mat_specular[1] = mat_ambient_and_diffuse[1] = g; mat_specular[2] = mat_ambient_and_diffuse[2] = b; glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_ambient_and_diffuse); } /* --------------------------------------------- */ /* create display list: axis-oriented cube centered at the origin, with edge length = 2 */ GLuint create_unit_cube ( ) { GLuint sceneList = glGenLists(1); glNewList(sceneList,GL_COMPILE); glBegin(GL_QUADS); glNormal3f(0.0,0.0,-1.0); glVertex3f(1.0,1.0,-1.0); glVertex3f(1.0,-1.0,-1.0); glVertex3f(-1.0,-1.0,-1.0); glVertex3f(-1.0,1.0,-1.0); glNormal3f(0.0,0.0,1.0); glVertex3f(1.0,1.0,1.0); glVertex3f(-1.0,1.0,1.0); glVertex3f(-1.0,-1.0,1.0); glVertex3f(1.0,-1.0,1.0); glNormal3f(1.0,0.0,0.0); glVertex3f(1.0,-1.0,1.0); glVertex3f(1.0,-1.0,-1.0); glVertex3f(1.0,1.0,-1.0); glVertex3f(1.0,1.0,1.0); glNormal3f(-1.0,0.0,0.0); glVertex3f(-1.0,-1.0,1.0); glVertex3f(-1.0,1.0,1.0); glVertex3f(-1.0,1.0,-1.0); glVertex3f(-1.0,-1.0,-1.0); glNormal3f(0.0,1.0,0.0); glVertex3f(-1.0,1.0,1.0); glVertex3f(1.0,1.0,1.0); glVertex3f(1.0,1.0,-1.0); glVertex3f(-1.0,1.0,-1.0); glNormal3f(0.0,-1.0,0.0); glVertex3f(-1.0,-1.0,-1.0); glVertex3f(1.0,-1.0,-1.0); glVertex3f(1.0,-1.0,1.0); glVertex3f(-1.0,-1.0,1.0); glEnd(); glEndList(); return sceneList; } GLuint create_scene ( ) { GLuint cubeList = create_unit_cube(); GLuint sceneList = glGenLists(1); glNewList(sceneList,GL_COMPILE); set_material_properties(1.0,1.0,1.0); glCallList(cubeList); set_material_properties(1.0,0.0,0.0); glPushMatrix(); glTranslatef(-1.0,-1.0,-1.0); glScalef(.4,.4,.4); glCallList(cubeList); glPopMatrix(); set_material_properties(0.0,1.0,0.0); glPushMatrix(); glTranslatef(-1.0,-1.0,1.0); glScalef(.4,.4,.4); glCallList(cubeList); glPopMatrix(); set_material_properties(0.0,0.0,1.0); glPushMatrix(); glTranslatef(-1.0,1.0,-1.0); glScalef(.4,.4,.4); glCallList(cubeList); glPopMatrix(); set_material_properties(0.5,0.0,0.5); glPushMatrix(); glTranslatef(1.0,-1.0,-1.0); glScalef(.4,.4,.4); glCallList(cubeList); glPopMatrix(); glEndList(); return sceneList; } /* --------------------------------------------- */ /* redraw the scene */ GLvoid draw(GLvoid) { /* set the projection matrix */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(8.0,1.0,15.0,25.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* initialize light */ init_lightsource(); if (animate) { angle1 += dangle1; angle2 += dangle2; } glTranslatef(0,0,-20); glRotatef(angle1,1,2,3); glRotatef(angle2,-2,-1,0); /* ensure we're drawing to the correct GLUT window */ glutSetWindow(wid); /* clear the color buffers */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* DRAW WHAT IS IN THE DISPLAY LIST */ glCallList(sceneID); /* flush the pipeline */ glFlush(); /* look at our handiwork */ glutSwapBuffers(); if (animate) glutPostRedisplay(); } /* --------------------------------------------- */ /* handle mouse events */ GLvoid mouse_button(GLint btn, GLint state, GLint mx, GLint my) { switch( btn ) { case GLUT_LEFT_BUTTON: printf("Left Button"); // remove this line from your final submission switch( state ) { case GLUT_DOWN: printf(" down\n"); // remove this line from your final submission break; case GLUT_UP: printf(" up\n"); // remove this line from your final submission break; } break; case GLUT_MIDDLE_BUTTON: printf("Middle Button"); // remove this line from your final submission switch( state ) { case GLUT_DOWN: printf(" down\n"); // remove this line from your final submission break; case GLUT_UP: printf(" up\n"); // remove this line from your final submission break; } break; case GLUT_RIGHT_BUTTON: printf("Right Button"); // remove this line from your final submission switch( state ) { case GLUT_DOWN: printf(" down\n"); // remove this line from your final submission break; case GLUT_UP: printf(" up\n"); // remove this line from your final submission break; } break; } } GLvoid button_motion(GLint mx, GLint my) { printf("Motion with button down: %d %d\n",mx,my); // remove this line from your final submission return; } GLvoid passive_motion(GLint mx, GLint my) { printf("Passive Motion: %d %d\n",mx,my); // remove this line from your final submission return; } /* --------------------------------------------- */ /* handle keyboard events; here, just exit if ESC is hit */ GLvoid keyboard(GLubyte key, GLint x, GLint y) { switch(key) { case 27: /* ESC */ exit(0); default: break; } } /* --------------------------------------------- */ GLvoid menu ( int value ) { switch(value) { case MENU_SLOWER: dangle1 *= .5; dangle2 *= .5; break; case MENU_FASTER: dangle1 *= 1.5; dangle2 *= 1.5; break; case MENU_STOP_RUN: animate = !animate; break; } } /* --------------------------------------------- */ /* handle resizing the glut window */ GLvoid reshape(GLint vpw, GLint vph) { glutSetWindow(wid); /* maintain a square viewport, not too small, not too big */ if( vpw < vph ) vpd = vph; else vpd = vpw; if( vpd < VPD_MIN ) vpd = VPD_MIN; if( vpd > VPD_MAX ) vpd = VPD_MAX; glViewport(0, 0, vpd, vpd); glutReshapeWindow(vpd, vpd); glutPostRedisplay(); } /* --------------------------------------------- */ GLint init_glut(GLint *argc, char **argv) { GLint id; glutInit(argc,argv); /* size and placement hints to the window system */ glutInitWindowSize(vpd, vpd); glutInitWindowPosition(10,10); /* double buffered, RGB color mode */ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); /* create a GLUT window (not drawn until glutMainLoop() is entered) */ id = glutCreateWindow("cs4451 assignment 2"); /* register callbacks */ /* window size changes */ glutReshapeFunc(reshape); /* keypress handling when the current window has input focus */ glutKeyboardFunc(keyboard); /* mouse event handling */ glutMouseFunc(mouse_button); /* button press/release */ glutMotionFunc(button_motion); /* mouse motion w/ button down */ glutPassiveMotionFunc(passive_motion); /* mouse motion with button up */ /* window obscured/revealed event handler */ glutVisibilityFunc(NULL); /* handling of keyboard SHIFT, ALT, CTRL keys */ glutSpecialFunc(NULL); /* what to do when mouse cursor enters/exits the current window */ glutEntryFunc(NULL); /* what to do on each display loop iteration */ glutDisplayFunc(draw); /* create menu */ GLint menuID = glutCreateMenu(menu); glutAddMenuEntry("slower",MENU_SLOWER); glutAddMenuEntry("faster",MENU_FASTER); glutAddMenuEntry("stop/run",MENU_STOP_RUN); glutSetMenu(menuID); glutAttachMenu(GLUT_RIGHT_BUTTON); return id; } /* --------------------------------------------- */ GLvoid init_opengl(GLvoid) { /* back-face culling on */ glEnable(GL_CULL_FACE); glCullFace(GL_BACK); /* automatically scale normals to unit length after transformation */ glEnable(GL_NORMALIZE); /* clear to BLACK */ glClearColor(0.0, 0.0, 0.0, 1.0); /* Enable depth test */ glEnable(GL_DEPTH_TEST); } /* --------------------------------------------- */ GLint main(GLint argc, char **argv) { /* initialize light */ init_lightsource(); /* initialize GLUT: register callbacks, etc */ wid = init_glut(&argc, argv); /* any OpenGL state initialization we need to do */ init_opengl(); /* CREATE THE DISPLAY LIST FOR THE SCENE */ sceneID = create_scene(); glutMainLoop(); return 0; }