/* This OpenGL program shows a simple animation. A line rotates 180 degrees around its center. Then it grows into a red square. Then it shrinks back to a line. This repeats indefinitely. This demonstrates how to do animation in OpenGL, using GLUT for the GUI interface. It also shows one way of having a "segmented" animation, in which different types of action take place during different parts of the animation. */ #include #include #include /* In the folowing constant definitions, MAX_FRAME represents the number of frames in one loop of the animation. The frame number goes from 0 to MAX_FRAME-1, then back to 0. The OpenGL coordinates on the widow (which are used for OpenGL drawing operations) go from -COORD_LIMIT to COORD_LIMIT in both the horizontal and vertical directions. (Note that the y-coordinate in OpenGL increases UPWARD!) COORD_LIMIT is used in the main() routine at the end of this file, when the windows is opened and configured. */ #define MAX_FRAME 380 #define COORD_LIMIT 250 static int frameNumber; /* Current frame number. The value of ** this variable is updated by updateFrameData(), ** and it is used in drawFrame(). */ void init(void) { /* This function is called once, by the main() routine, before the animation starts. It is meant for initializing global variables and OpenGL states. */ glClearColor(1.0, 1.0, 1.0, 0.0); glShadeModel(GL_FLAT); } void updateFrameData(void) { /* This function is called by drawNextFrame() just before each frame in the animation is drawn. It is meant for updating the values of global variables. Here, only the frameNumber is updated. (All the other data needed to draw the frame is calculated in drawFrame(), based on the frameNumber; */ frameNumber++; if (frameNumber >= MAX_FRAME) frameNumber = 0; } void drawFrame(void) { /* This function is called by display() whenever a frame in the animation needs to be drawn. In this example, there are three cases, based on the value of framenumber. if 0 <= frameNumber <= 180, a black line is drawn, tilted at an angle of frameNumber degrees. As the frame number increases, the line rotates. If 180 < frameNumber <= 280, a rectangle is drawn with a height of (frameNumber - 180). This rectangle grows from size 2 when frameNumber == 1 to size 200 when frameNumber == 280. Also, the redness of the square increases from 0.0 to 1.0. In the third segment, when 280 < frameNumber < 380, the square decreases in size and redness. */ if (frameNumber <= 180) { float d = 3.141592654 / 180; float theta = 3.141592654 / 180.0 * frameNumber; glColor3f(0.0,0.0,0.0); glBegin(GL_LINES); glVertex2f(200*cos(theta), 200*sin(theta)); glVertex2f(-200*cos(theta), -200*sin(theta)); glEnd(); } else if (frameNumber <= 280) { glColor3f((frameNumber-180)/100.0, 0.0, 0.0); glRecti(-200,2*(frameNumber-180),200,-2*(frameNumber-180)); } else { glColor3f((380-frameNumber)/100.0, 0.0, 0.0); glRecti(-200,2*(380-frameNumber),200,-2*(380-frameNumber)); } } /**************************************************************************/ /* To write a new animation, do NOT change the following three routines */ /**************************************************************************/ void display(void) { /* This is the display function, which is called by glutMainLoop() whenever the picture in the window needs to be redrawn. The display fuction is set by glutDisplayFunc(), which is called in the main() routine. */ glClear (GL_COLOR_BUFFER_BIT); drawFrame(); glutSwapBuffers(); } void doNextFrame(void) { /* This is the "idle" function, which is called repeatedly by glutMainLoop(), whenever it has nothing else to do. The idle function is set by glutIdleFunc(), which is called in the main() routine. (The call to glutPostRedisplay() in this routine will force glutMainLoop() to redraw the picture in the window.) */ updateFrameData(); glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition(50,50); glutCreateWindow(argv[0]); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-COORD_LIMIT,COORD_LIMIT,-COORD_LIMIT,COORD_LIMIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity (); glutDisplayFunc(display); glutIdleFunc(doNextFrame); frameNumber = -1; init(); glutMainLoop(); return 0; }