/* File: step4.c Author: Katia Oleinik Here we clean up and optimize the code using GL_lists Assignment: 1. use glScale to scale down the ball. Try to place glScale command before glTranslate and then after. Compare the results. 2. Add to the keyPress callback routine: if user presses "<" and ">" (or left, right) buttons, the platform (box) moves to the left and to the right accordingly. Remember it should not go beyond the clipping planes, so x coordinate for the translation can not exceed plus/minus 4 */ #include #include #include GLuint ballList; // gl list to hold ball geometry GLuint boxList; // gl list to hold box geometry /* user defined functions declarations */ void boxDef( float length, float height, float width); void mydraw(void); void keypress( unsigned char key, int x, int y); void specialkeys(int key, int x, int y); void mousepress( int button, int state, int x, int y); void resize(int width, int height); void display(void); void init(void); /* drawing routine, called by display every animated frame */ void mydraw(void) { /* display ball */ glPushMatrix(); glTranslatef(0., 1., 0.); glColor3f( 1.0, 0.5, 0.0); // orange color glCallList(ballList); // draw ball glPopMatrix(); /* display box */ glPushMatrix(); glTranslatef(0., -.05, 0.); glColor3f( 0.0, 1.0, 0.0); // green color glCallList(boxList); // draw box glPopMatrix(); } /* keyboard callback routine */ void keypress( unsigned char key, int x, int y) { switch (key) { case 'q': case 'Q': exit(0); case 'w': case 'W': /* Set up a state */ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); printf("Set state to wireframe\n"); break; case 's': case 'S': /* Set up a state */ printf("Set state to solid\n"); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; case ',': case '<': // add your code here break; case '.': case '>': // add your code here break; } /* we would like to force openGL to redraw the scene */ glutPostRedisplay(); } /* handle special keys */ void specialkeys(int key, int x, int y) { switch (key) { case GLUT_KEY_LEFT: // add your code here break; case GLUT_KEY_RIGHT: // add your code here break; } /* force openGL to redraw the scene */ glutPostRedisplay(); } /* mouse click callback routine */ void mousepress( int button, int state, int x, int y) { if (state != GLUT_DOWN)return; switch (button) { case GLUT_LEFT_BUTTON: printf("Left mouse button pressed\n"); break; case GLUT_MIDDLE_BUTTON: printf("Middle mouse button pressed\n"); break; case GLUT_RIGHT_BUTTON: printf("Right mouse button pressed\n"); break; } printf( " Mouse coordinates: %d %d\n",x,y); } /* ball definition - define geometry only */ /* add geometry into a GL list */ void ballDef(void) { /* define a new list */ ballList = glGenLists(1); /* open a new list */ glNewList(ballList, GL_COMPILE); /* draw a sphere of radius 1 */ glutSolidSphere(1., 24, 24); /* close gl list */ glEndList(); } /* box definition */ /* here we define geometry only */ /* color definition could be used inside also if some vertices or sides are of different color */ /* Add geometry into GL list */ void boxDef( float length, float height, float width) { /* define a new list */ boxList = glGenLists(1); /* open a new list */ glNewList(boxList, GL_COMPILE); glBegin(GL_QUADS); /* upper side of the box */ glVertex3f(-length/2., height/2., width/2.); glVertex3f( length/2., height/2., width/2.); glVertex3f( length/2., height/2.,-width/2.); glVertex3f(-length/2., height/2.,-width/2.); /* bottom side of the box */ glVertex3f(-length/2.,-height/2., width/2.); glVertex3f(-length/2.,-height/2.,-width/2.); glVertex3f( length/2.,-height/2.,-width/2.); glVertex3f( length/2.,-height/2., width/2.); /* front side of the box */ glVertex3f(-length/2.,-height/2., width/2.); glVertex3f( length/2.,-height/2., width/2.); glVertex3f( length/2., height/2., width/2.); glVertex3f(-length/2., height/2., width/2.); /* back side of the box */ glVertex3f(-length/2., height/2.,-width/2.); glVertex3f(-length/2.,-height/2.,-width/2.); glVertex3f( length/2.,-height/2.,-width/2.); glVertex3f( length/2., height/2.,-width/2.); /* left side of the box */ glVertex3f(-length/2.,-height/2.,-width/2.); glVertex3f(-length/2.,-height/2., width/2.); glVertex3f(-length/2., height/2., width/2.); glVertex3f(-length/2., height/2.,-width/2.); /* right side of the box */ glVertex3f( length/2.,-height/2., width/2.); glVertex3f( length/2., height/2., width/2.); glVertex3f( length/2., height/2.,-width/2.); glVertex3f( length/2.,-height/2.,-width/2.); /* do not forget to END gl primitives ! */ glEnd(); /* close gl list */ glEndList(); } /* callback routine to respond on resize of the window */ void resize(int width, int height) { double aspect; /* Reset the viewport */ glViewport(0,0,width,height); /* compute aspect */ aspect = (double)width / (double)height; /* Set up the perspective matrix accordingly */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); //reset projection matrix /* make sure that the clipping planes are set to the original values in the smallest direction */ if (aspect < 1.0) glOrtho(-4., 4., -4./aspect, 4./aspect, 1., 10.); else glOrtho(-4.*aspect, 4.*aspect, -4., 4., 1., 10.); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* Set Camera Position */ gluLookAt(0., 0., 5., 0., 0., 0., 0., 1., 0.); } /* display is called by the glut main loop once for every animated frame */ void display(void) { /* initialize color and depth buffers */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* call the routine that actually draws what you want */ mydraw(); /* show the just-filled frame buffer */ glutSwapBuffers(); } /* called once to set up basic opengl state */ void init(void) { /* Use depth buffering for hidden surface elimination. */ glEnable(GL_DEPTH_TEST); /* Set up the perspective matrix */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* Define perspective matrix */ glOrtho(-4., 4., -4., 4., 1, 10.); /* Set up the model view matrix */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* Define Camera Position */ gluLookAt(0., 0., 5., 0., 0., 0., 0., 1., 0.); /* Define Geometry of ball and box */ boxDef(2., .1, .4); ballDef(); } int main(int argc, char **argv) { /* GLUT Configuration */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500,500); glutInitWindowPosition(100,100); glutCreateWindow("Orange Ball"); /* Set callbacks */ glutDisplayFunc(display); glutReshapeFunc(resize); glutKeyboardFunc (keypress); glutSpecialFunc(specialkeys); glutMouseFunc(mousepress); /* Set basic openGL states */ init(); /* Enter GLUT event processing loop */ glutMainLoop(); return 0; }