/* timer.c */ /* Program to demonstrate the use of the glutTimerFunc callback. * This program uses the glutTimerFunc to update a variable at * regular intervals. Note that the callback must be re-set after the * timer function has been called if you want it to call again. * * Note also the resize behaviour of this program. Can you modify the * program so the text always begins at the top left of the screen, * regardless of window size? * * As another exercise, modify the program so that the 's' key starts * and stops the timer (press 's' to start, 's' again to stop) and displays * a "timer paused" message when stopped. Use the 'r' key to reset the * counter to 0. * */ /* Copyright Jon McCormack, March 2004 */ /* Updated 29 March 2004: Removed platform dependencies */ #include #include #ifdef __APPLE__ #include #else #include #endif #define MAX_TEXT_SIZE 255 /* maximum text string length */ #define GAP 1000 /* ms gap between updates */ /* * static shared variables */ static int g_counter = 0; /* * drawText * * Draws the specified message in both * raster and stroke text * */ void drawText(const char * message, GLfloat x, GLfloat y) { /* raster pos sets the current raster position * mapped via the modelview and projection matrices */ glRasterPos2f(x, y); /* * write using bitmap and stroke chars */ while (*message) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *message++); } } /* * display * * This function is called by the GLUT to display the graphics * In this case it clears the screen then calls the function "drawText" * which will draw some text using GLUT * */ void display(void) { char text[MAX_TEXT_SIZE]; sprintf(text,"%d seconds have elapsed.", g_counter); glClear( GL_COLOR_BUFFER_BIT ); drawText(text, -2.0, 1); drawText("Press q to quit", -2.0, 0); glFlush(); /* force OpenGL output */ } /* * myReshape * * This function is called whenever the user (or OS) reshapes the * OpenGL window. The GLUT sends the new window dimensions (x,y) * */ void myReshape(int w, int h) { /* set viewport to new width and height */ /* note that this command does not change the CTM */ glViewport(0, 0, w, h); /* * set viewing window in world coordinates */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* init projection matrix */ if (w <= h) glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w, -1.0, 1.0); else glOrtho(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -1.0, 1.0); /* set matrix mode to modelview */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /* * myTimer * * Called by the glutTimerFunc callback. This function increments the * supplied parameter value, storing it in g_counter. We then call * glutPostRedisplay() to force the glut to re-display the screen (which will * update the time displayed. The timer callback only calls the supplied * function once, so if we want repeated calls we must set the callback * again after each call. */ void myTimer(int value) { g_counter = value + 1; glutPostRedisplay(); glutTimerFunc(GAP, myTimer, g_counter); } /* * myKey * * responds to key presses from the user */ void myKey(unsigned char k, int x, int y) { switch (k) { case 'q': case 'Q': exit(0); break; default: printf("Unknown keyboard command \'%c\'.\n", k); break; } } /* * main * * Initialization and sets graphics callbacks * */ int main(int argc, char **argv) { /* glutInit MUST be called before any other GLUT/OpenGL calls */ glutInit(&argc, argv); /* need both double buffering and z buffer */ glutInitDisplayMode(GLUT_RGB); glutInitWindowSize(400, 100); glutCreateWindow("The Timer"); /* set callback functions */ glutReshapeFunc(myReshape); glutDisplayFunc(display); glutKeyboardFunc(myKey); glutTimerFunc(GAP, myTimer, 0); /* set clear colour */ glClearColor(1.0, 1.0, 1.0, 1.0); /* set current colour to black */ glColor3f(0.0, 0.0, 0.0); glutMainLoop(); return 0; }