/********************************************************************* * File: MorphingWithIdleFunc.cpp * Author: Dr. Dalton R. Hunkins * Date: September 2008 * * * Purpose of Exmaple * This example illustrates using an Idle * function in creating an animation. The reason * we use an glut idle function versus counted * iteration is the iteration will run to completion * before any user events can be handled. On the * other hand, an idle runs while the event queue * is empty and is interrupted wheneven an event * must be handled. * * * User Interaction particular to this example: * Menu: * Right Mouse Button tiggered providing choices * to pause and resume animation * to display full screen or window * to set speed of the animation (amount of change per frame) **********************************************************************/ #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #include <cmath> #define MENU_ITEM_PAUSE 902 #define MENU_ITEM_RESUME 903 #define MENU_ITEM_FULL 904 #define MENU_ITEM_WINDOW 905 #define MENU_ITEM_SLOWER 906 #define MENU_ITEM_SLOW 907 #define MENU_ITEM_NORMAL 908 #define MENU_ITEM_FAST 909 #define MENU_ITEM_FASTER 910 int count = 0; int numberOfPartitions = 1000; int millisecondDelay = 50; int countDirection = 1; void star() { glClear(GL_COLOR_BUFFER_BIT); double PI = 3.14159; double radius1 = -0.75 * (count/ (double) numberOfPartitions) + 1.0; double radius2 = 0.75 * (count/ (double) numberOfPartitions) + 0.25; float colorValue1 = -1.0*(count/ (float) numberOfPartitions) + 1.0; float colorValue2 = 1.0*(count/ (float) numberOfPartitions); glBegin(GL_TRIANGLE_FAN); glColor3f(0.7, 0.7, 0.7); glVertex3d(0.0, 0.0, 0.0); glColor3f(colorValue1, colorValue2, colorValue2); glVertex3d(radius1 * cos(0.0 * PI / 180.0), radius1 * sin(0.0 * PI / 180.0), 0.0); glColor3f(colorValue1, colorValue1, colorValue2); glVertex3d(radius2 * cos(30.0 * PI / 180.0), radius2 * sin(30.0 * PI / 180.0), 0.0); glColor3f(colorValue2, colorValue1, colorValue2); glVertex3d(radius1 * cos(60.0 * PI / 180.0), radius1 * sin(60.0 * PI / 180.0), 0.0); glColor3f(colorValue2, colorValue1, colorValue1); glVertex3d(radius2 * cos(90.0 * PI / 180.0), radius2 * sin(90.0 * PI / 180.0), 0.0); glColor3f(colorValue2, colorValue2, colorValue1); glVertex3d(radius1 * cos(120.0 * PI / 180.0), radius1 * sin(120.0 * PI / 180.0), 0.0); glColor3f(colorValue1, colorValue2, colorValue1); glVertex3d(radius2 * cos(150.0 * PI / 180.0), radius2 * sin(150.0 * PI / 180.0), 0.0); glColor3f(colorValue1, colorValue2, colorValue2); glVertex3d(radius1 * cos(180.0 * PI / 180.0), radius1 * sin(180.0 * PI / 180.0), 0.0); glColor3f(colorValue1, colorValue1, colorValue2); glVertex3d(radius2 * cos(210.0 * PI / 180.0), radius2 * sin(210.0 * PI / 180.0), 0.0); glColor3f(colorValue2, colorValue1, colorValue2); glVertex3d(radius1 * cos(240.0 * PI / 180.0), radius1 * sin(240.0 * PI / 180.0), 0.0); glColor3f(colorValue2, colorValue1, colorValue1); glVertex3d(radius2 * cos(270.0 * PI / 180.0), radius2 * sin(270.0 * PI / 180.0), 0.0); glColor3f(colorValue2, colorValue2, colorValue1); glVertex3d(radius1 * cos(300.0 * PI / 180.0), radius1 * sin(300.0 * PI / 180.0), 0.0); glColor3f(colorValue1, colorValue2, colorValue1); glVertex3d(radius2 * cos(330.0 * PI / 180.0), radius2 * sin(330.0 * PI / 180.0), 0.0); glColor3f(colorValue1, colorValue2, colorValue2); glVertex3d(radius1 * cos(360.0 * PI / 180.0), radius1 * sin(360.0 * PI / 180.0), 0.0); glEnd(); glutSwapBuffers(); } void init() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-1.0, 1.0, -1.0, 1.0); glClearColor(0.0, 0.0, 0.0, 1.0); } void animation() { glutPostRedisplay(); count += countDirection; if (count > numberOfPartitions) { count = numberOfPartitions; countDirection *= -1; } else if (count < 0) { count = 0; countDirection *= -1; } } void menuHandler(int selection) { switch (selection) { // Pausing and Resuming Animation case MENU_ITEM_PAUSE : glutIdleFunc(NULL); break; case MENU_ITEM_RESUME : glutIdleFunc(animation); break; // Changing the Display Area case MENU_ITEM_FULL : glutFullScreen(); break; case MENU_ITEM_WINDOW : glutPositionWindow(50, 50); glutReshapeWindow(500, 500); break; // Setting the Animation Speed case MENU_ITEM_SLOWER : numberOfPartitions = 1800; count = 0; glutPostRedisplay(); break; case MENU_ITEM_SLOW : numberOfPartitions = 1400; count = 0; glutPostRedisplay(); break; case MENU_ITEM_NORMAL : numberOfPartitions = 1000; count = 0; glutPostRedisplay(); break; case MENU_ITEM_FAST : numberOfPartitions = 600; count = 0; glutPostRedisplay(); break; case MENU_ITEM_FASTER : numberOfPartitions = 200; count = 0; glutPostRedisplay(); break; } } void createMenu() { glutCreateMenu(menuHandler); glutAddMenuEntry("Pause Animation", MENU_ITEM_PAUSE); glutAddMenuEntry("Resume Animation", MENU_ITEM_RESUME); glutAddMenuEntry("Full Screen", MENU_ITEM_FULL); glutAddMenuEntry("Window", MENU_ITEM_WINDOW); glutAddMenuEntry("Slower Speed", MENU_ITEM_SLOWER); glutAddMenuEntry("Slow Speed", MENU_ITEM_SLOW); glutAddMenuEntry("Normal Speed", MENU_ITEM_NORMAL); glutAddMenuEntry("Fast Speed", MENU_ITEM_FAST); glutAddMenuEntry("Faster Speed", MENU_ITEM_FASTER); glutAttachMenu(GLUT_RIGHT_BUTTON); } int main (int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowPosition(10, 10); glutInitWindowSize(500, 500); glutCreateWindow("Morphing"); createMenu(); init(); glutDisplayFunc(star); glutIdleFunc(animation); glutMainLoop(); return 0; }