/* cs4451_a2.c */ /* PLEASE PUT YOUR NAME HERE */ #include #include #include #include #include #include #define VPD_MIN 200 #define VPD_DEFAULT 256 #define VPD_MAX 66666600 #define TWOPI (2.0 * M_PI) GLvoid parse_args(GLint argc, char **argv); GLvoid usage(char *argv0); GLint init_glut(GLint *argc, char **argv); GLvoid init_opengl(GLvoid); GLvoid init_lightsource(GLvoid); GLvoid idle(GLvoid); GLvoid reshape(GLint vpw, GLint vph); GLvoid keyboard(GLubyte key, GLint x, GLint y); GLvoid mouse_button(GLint btn, GLint state, GLint mx, GLint my); GLvoid button_motion(GLint mx, GLint my); GLvoid passive_motion(GLint mx, GLint my); GLvoid set_material_color( GLfloat r, GLfloat g, GLfloat b ); GLuint create_unit_cube(GLvoid); GLuint create_scene(GLvoid); GLvoid draw(GLvoid); GLvoid shade_pixel(GLfloat *r, GLfloat *g, GLfloat *b, GLint x, GLint y); GLint wid, /* GLUT window id */ vpd; /* (square) viewport dimensions */ /* --------------------------------------------- */ GLuint sceneID; /* --------------------------------------------- */ GLint main(GLint argc, char **argv) { /* read and process command line arguments */ parse_args(argc, argv); /* initialize GLUT: register callbacks, etc */ wid = init_glut(&argc, argv); /* any OpenGL state initialization we need to do */ init_opengl(); init_lightsource(); /* CREATE THE DISPLAY LIST FOR THE SCENE */ sceneID = create_scene(); glutMainLoop(); return 0; } GLvoid draw(GLvoid) { static GLint which_time = 0; const GLfloat angle1 = 1.5; const GLfloat angle2 = 2.2; /* back-face culling on */ glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(8.0,1.0,15.0,25.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0,0,-20); glRotatef(angle1*which_time,1,2,3); glRotatef(angle2*which_time,-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); /* save the current (MODELVIEW) matrix stack value */ glPushMatrix(); /* DRAW WHAT IS IN THE DISPLAY LIST */ glCallList(sceneID); /* restore the saved matrix value */ glPopMatrix(); glFinish(); /* look at our handiwork */ glutSwapBuffers(); glutPostRedisplay(); which_time++; } GLvoid init_lightsource ( GLvoid ) { GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.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); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } GLvoid parse_args(GLint argc, char **argv) { extern char *optarg; int optchar; if( argc == 1 ) { usage(argv[0]); exit(1); } /* flags with a : will require an argument on the command line */ while( (optchar = getopt(argc, argv, "d:D:hH")) != -1) { switch(optchar) { case 'd': case 'D': vpd = atoi(optarg); if( vpd < VPD_MIN || vpd > VPD_MAX ) { fprintf(stderr,"Bad window size (using %d x %d).\n", VPD_DEFAULT, VPD_DEFAULT); vpd = VPD_DEFAULT; } break; case 'h': case 'H': usage(argv[0]); exit(0); } } } GLvoid usage(char *argv0) { printf("\n"); printf("Usage: %s [-d dim] -h\n", argv0); printf("\n"); printf("where dim = square window size (dim x dim)\n"); printf(" %d < dim < %d\n", VPD_MIN, VPD_MAX); printf("\n"); printf(" -h = display this usage message\n"); printf("\n"); } 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 */ /* what to do when GLUT events are not being recd */ glutIdleFunc(idle); /* 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); return id; } GLvoid init_opengl(GLvoid) { /* clear to BLACK */ glClearColor(0.0, 0.0, 0.0, 1.0); /* this is the default (Gouraud shading) */ glShadeModel(GL_SMOOTH); /* ENABLE DEPTH TEST */ glEnable(GL_DEPTH_TEST); } GLvoid idle(GLvoid) { if(wid) { glutSetWindow(wid); glutPostRedisplay(); } } 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(); } GLvoid keyboard(GLubyte key, GLint x, GLint y) { switch(key) { case 27: /* ESC */ exit(0); default: break; } } GLvoid mouse_button(GLint btn, GLint state, GLint mx, GLint my) { switch( btn ) { case GLUT_LEFT_BUTTON: switch( state ) { case GLUT_DOWN: break; case GLUT_UP: break; } break; case GLUT_MIDDLE_BUTTON: switch( state ) { case GLUT_DOWN: break; case GLUT_UP: break; } break; case GLUT_RIGHT_BUTTON: switch( state ) { case GLUT_DOWN: break; case GLUT_UP: break; } break; } } GLvoid button_motion(GLint mx, GLint my) { return; } GLvoid passive_motion(GLint mx, GLint my) { return; } GLvoid set_material_color ( GLfloat r, GLfloat g, GLfloat b ) { GLfloat mat_specular[4] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_ambient_and_diffuse[4] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess[1] = { 50.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); } /* ----------------------------------------- */ /* ---- THE DISPLAY LISTS ARE CREATED ---- */ /* ----------------------------------------- */ GLuint create_unit_cube ( ) { GLuint ListID = glGenLists(1); glNewList(ListID,GL_COMPILE); glBegin(GL_QUADS); glNormal3f(0.0,0.0,-1.0); glVertex3f(1.0,1.0,0.0); glVertex3f(1.0,0.0,0.0); glVertex3f(0.0,0.0,0.0); glVertex3f(0.0,1.0,0.0); glNormal3f(0.0,0.0,1.0); glVertex3f(1.0,1.0,1.0); glVertex3f(0.0,1.0,1.0); glVertex3f(0.0,0.0,1.0); glVertex3f(1.0,0.0,1.0); glNormal3f(1.0,0.0,0.0); glVertex3f(1.0,0.0,1.0); glVertex3f(1.0,0.0,0.0); glVertex3f(1.0,1.0,0.0); glVertex3f(1.0,1.0,1.0); glNormal3f(-1.0,0.0,0.0); glVertex3f(0.0,0.0,1.0); glVertex3f(0.0,1.0,1.0); glVertex3f(0.0,1.0,0.0); glVertex3f(0.0,0.0,0.0); glNormal3f(0.0,1.0,0.0); glVertex3f(0.0,1.0,1.0); glVertex3f(1.0,1.0,1.0); glVertex3f(1.0,1.0,0.0); glVertex3f(0.0,1.0,0.0); glNormal3f(0.0,-1.0,0.0); glVertex3f(0.0,0.0,0.0); glVertex3f(1.0,0.0,0.0); glVertex3f(1.0,0.0,1.0); glVertex3f(0.0,0.0,1.0); glEnd(); glEndList(); return ListID; } GLuint create_scene ( ) { GLuint cubeList = create_unit_cube(); GLuint sceneList = glGenLists(1); glNewList(sceneList,GL_COMPILE); set_material_color(1.0,1.0,1.0); glPushMatrix(); glTranslatef(.2,.2,.2); glScalef(.8,.8,.8); glCallList(cubeList); glPopMatrix(); set_material_color(1.0,0.0,0.0); glPushMatrix(); glTranslatef(-1.0,-1.0,-1.0); glScalef(.8,.8,.8); glCallList(cubeList); glPopMatrix(); set_material_color(0.0,1.0,0.0); glPushMatrix(); glTranslatef(-1.0,0.2,-1.0); glScalef(.8,.8,.8); glCallList(cubeList); glPopMatrix(); set_material_color(0.0,0.0,1.0); glPushMatrix(); glTranslatef(-1.0,0.2,0.2); glScalef(.8,.8,.8); glCallList(cubeList); glPopMatrix(); set_material_color(0.5,0.0,0.5); glPushMatrix(); glTranslatef(-.75,-.75,-.75); glScalef(1.5,1.5,1.5); glCallList(cubeList); glPopMatrix(); glEndList(); return sceneList; }