Lab (2) - Simple Animation Using 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+=.2, y+=.2 will march the square across the screen and gets out of the screen.

#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 */
        glPolygonMode(GL_FILL,GL_FRONT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(0.0, max, 0.0, max);
        glMatrixMode(GL_MODELVIEW);
}

void display( void )
{
        glClear(GL_COLOR_BUFFER_BIT);  /*clear the window */
        glBegin(GL_POLYGON);
                glVertex2f(x,y);
                glVertex2f(x+size,y);
                glVertex2f(x+size,y-size);
                glVertex2f(x,y-size);
        glEnd();
        glFlush(); /* clear buffers */
}

void idle()
{
        x+ = xinc;
        y+ = yinc;
        glutPostRedisplay();
}

void main(int argc, char** argv)
{
        /* Standard GLUT initialization */
        glutInit(&argc,argv);
        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 */
        glutIdleFunc(idle);

        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;
        glutPostRedisplay();
}

Keeping the Square in the Frame
Exercise (2)
Make changes in the program, basically add two if statements, 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 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

        glutSwapBuffers();
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:

glutMouseFunc(mouse_callback_func)

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.  Thus, if the square is moving from right to left, once you press the left button it turn around and moves left to right immediately.  Once you are done let me see you program to get the final grade for the lab.

If you didn't finish this in the lab, finish it and bring the hard copy to the next class.