Lab (3) - Simple Animation Using MOUSE and idle()

Lab Goals We can use the idle callback to implement animation. The following program registers idle() as the function to be called whenever there is free cpu time. This function changes the coordinates of a point at which display() will draw a square, then forces display() to be called by executing glutPostRedisplay(). If we call the coordinates x and y, then e.g. x += 0.2,  y += 0.2 will march the square across the screen and gets out of the screen.  Here is the program that draws a square on different locations of the display by continuously changing the coordinates. 

#include <GL/glut.h>

GLfloat x=10,y=20;
GLfloat xinc=.2,yinc=.2;
const GLfloat size=5;
const GLfloat max=50;
void myinit(void)
        /* attributes */
        glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */
        glColor3f(1.0, 0.0, 0.0); /* draw in red */
        /* set up viewing */
        /* 50 x 50 window with origin lower left */
        gluOrtho2D(0.0, max, 0.0, max);

void display( void )
        glClear(GL_COLOR_BUFFER_BIT);  /*clear the window */
        glFlush(); /* clear buffers */

void idle()
        x += xinc;
        y += yinc;

void main(int argc, char** argv)
        /* Standard GLUT initialization */
        glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */
        glutInitWindowSize(500,500); /* 500 x 500 pixel window */
        glutInitWindowPosition(0,0); /* place window top left on display */
        glutCreateWindow("Test"); /* window title */
        glutDisplayFunc(display); /* display callback invoked when window opened */


        myinit(); /* set attributes */
        glutMainLoop(); /* enter event loop */

Exercise (1)
What does each line in the following code segment do?
void idle()
        x  + = xinc;
        y  += yinc;

Keeping the Square in the Frame
Exercise (2)
Make changes in the program to prevent the square from going out of the screen and instead bounces back when reaches one of the boundaries.  In order to do this, you need to track the square and once reached the boundary reverse the increment process to decrement.  Once you made the change, compile and run the program.  Show me the result during the lab before moving to the next step.

Flicker Free Display using Double Buffer
As you have noticed the above program gives lots of flicker. The screen repeatedly gets refreshed while the square is only partially drawn. The solution is to use double buffering. We draw to an offscreen buffer, then switch buffers all at once. This requires changing only two lines of code. We add

to our display function (after the glFlush call, which flushes output to the buffer). We also change a flag in our call to glutInitDisplayMode:
        glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
Exercise (3)
Make the required changes in your program so that it is flicker free.  Once you are done, run the program and let me see the result.

Adding the Mouse Function
One last thing to do in this lab.  In class, we talked about the interaction of mouse with your graphics program.  We used the mouse callback for this purpose. The mouse callback function looks like this:


void mouse_callback_func(int button, int state, int x, int y)

Here is an example for a mouse function:

void mouse_callback_function(int button, int state, int x, int y)
     if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
          exit( 1);

Exercise (4)
Now, add to your program the mouse function such that by pressing the RIGHT button the program terminates and by pressing the LEFT button the square reverses its move, and by pressing the MIDDLE button the box stops at its present location.  Once you are done let me see your program to get the final grade for the lab.

An example output screen:

If you didn't finish this in the lab, finish it by next Wednesday and e-mail your final program to me as an attachment (have your name on the file).

A Good program for you to look at The Rotating Square