/* File: step6.c Author: Katia Oleinik In this tutorial we disable rotations and enable moving the ball along the screen We should treat the boundaries of the screen as walls and enable the ball to bounce from the walls, the ceiling and the platform. If the ball falls bellow the platform in falls down and then a ball of a new color appears from the top Assignment: 1. move the platform down the screen, so it would move along the y=-4 level */ #include #include #include /* user defined functions declarations */ void animate (void); void lightSetUp(); 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); GLuint ballList; // gl list to hold ball geometry GLuint boxList; // gl list to hold box geometry static float xPos; // position of the platform on the screen static float step=.1; // step to move the platform static float bxStep; // step in x direction static float byStep; // step in y direction static float bxPos, byPos; // ball position on XY plane static GLint before; void animate (void) { GLint now; now = glutGet( GLUT_ELAPSED_TIME ); if (abs(now-before) >=40){ //check intersection with the platform if (byStep < 0. && bxPos <=xPos+1.25 && bxPos >=xPos-1.25 && byPos <= -3.45 && byPos >-3.5) { byStep=-byStep; byPos+=byStep; } else { bxPos+=bxStep; byPos+=byStep; if (bxPos<=-3.5)bxStep=-bxStep; if (bxPos>= 3.5)bxStep=-bxStep; if (byPos>= 3.5)byStep=-byStep; if (byPos<=-4.5)byPos=3.4; } before = now; glutPostRedisplay(); } } /* drawing routine, called by display every animated frame */ void mydraw(void) { /* display ball */ glPushMatrix(); glTranslatef(bxPos, byPos, 0.); glScalef(.5, .5, .5); // scale down the ball glColor3f(1.0, 0.5, 0.0); glCallList(ballList); // draw ball glPopMatrix(); /* display platform */ glPushMatrix(); glTranslatef(xPos, -3.95, 0.); glColor3f(0.0, 1.0, 0.0); 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 '<': if (xPos<=-3.)return; xPos-=step; break; case '.': case '>': if (xPos>= 3.)return; xPos+=step; 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: if (xPos<=-4.)return; xPos-=step; break; case GLUT_KEY_RIGHT: if (xPos>=4.)return; xPos+=step; break; } /* we would like to 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); } /* 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(); } /* 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(); bxPos = 0.; byPos = 3.4; bxStep = -0.1; byStep = -0.1; } /* 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) { // Initialize box position on x axis xPos=0; /* define a new list */ boxList = glGenLists(1); /* open a new list */ glNewList(boxList, GL_COMPILE); glBegin(GL_QUADS); /* upper side of the box */ glNormal3f( 0., 1., 0.); 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 */ glNormal3f( 0.,-1., 0.); 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 */ glNormal3f( 0., 0., 1.); 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 */ glNormal3f( 0., 0.,-1.); 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 */ glNormal3f( -1., 0., 0.); 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 */ glNormal3f( 1., 0., 0.); 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(); } void lightSetUp() { GLfloat global_ambient[] = { 0.2, 0.2, 0.2, 1.0}; // Global ambient light model GLfloat diffuseLight[] = { 0.75, 0.75, 0.75, 1.0 };// RGBA, vary the 3 first param. to change the light color and intensity. GLfloat ambientLight[] = { 0.01, 0.01, 0.01, 1.0 };// Define color and intensity GLfloat specularLight[] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat lightPos[] = { 150, 250, 50, 0.0 }; GLfloat mat_spec[] = {.5, .5, .5, 1.0}; GLfloat mat_shine = 50.; // background color glClearColor(0.1,0.5,0.75,0.); // Setup light source //glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient); glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseLight ); // diffuse component of light0 glLightfv( GL_LIGHT0, GL_AMBIENT, ambientLight ); // ambient component glLightfv( GL_LIGHT0, GL_SPECULAR, specularLight ); // specular component glLightfv( GL_LIGHT0, GL_POSITION, lightPos ); // position in space glEnable(GL_LIGHTING); glEnable( GL_LIGHT0 ); // Light it! // explore how wach type of shade-model effect the scene //glShadeModel(GL_FLAT); // Enables Flat Color Shading glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading (default) // Set up material properties glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); // glMaterialfv( GL_FRONT, GL_SPECULAR, mat_spec ); glMaterialf( GL_FRONT, GL_SHININESS, mat_shine ); glEnable(GL_COLOR_MATERIAL); } /* called once to set up basic opengl state */ void init(void) { /* Use depth buffering for hidden surface elimination. */ glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); /* 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.); /* Initialize lighting */ lightSetUp(); /* Define Geometry of ball and box */ boxDef(2., .1, .4); ballDef(); /* Initialize the timer */ before = glutGet(GLUT_ELAPSED_TIME); } int main(int argc, char **argv) { /* GLUT Configuration */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); /* These 2 setup calls are optional - set size and position of the window */ glutInitWindowSize(500,500); glutInitWindowPosition(100,100); /* Create Window */ glutCreateWindow("Orange Ball"); /* Set display as a callback for the current window */ glutDisplayFunc(display); /* Set callback function that respond to resizing the window */ glutReshapeFunc(resize); /* Set callback function that responds on keyboard pressing */ glutKeyboardFunc (keypress); glutSpecialFunc(specialkeys); /* Set callback function that responds on the mouse click */ glutMouseFunc(mousepress); /* Set a call back routine for animation */ glutIdleFunc( animate); /* Set basic openGL states */ init(); /* Enter GLUT event processing loop, which interprets events and calls respective callback routines */ glutMainLoop(); /* Exit the program */ return 0; }