Cool, trying on your PC is a good idea. I wrote a quick program and saw 407171 FPS with my NVIDIA 9600 GT – note that nothing is actually drawn faster than the refresh rate of the monitor but openGL skips the in between frame to give such a high FPS.
Note the use of a timer like ctime with 1ms precision may lead to misleading results for instance a difference of 1ms could lead to a FPS difference of 500FPS!
1ms/frame = 1/1e-3=1000FPS
2ms/frame = 1/2e-3=500FPS
3ms/frame = 1/3e-3=333FPS
...
so at very high frame rates your FPS values could be completely off. So to deal with an imprecise clock it is best to measure the number of frames that are drawn in say 1 second – that takes the precision of the timer out of the issue.
For what its worth here is a glut based code used to time your example on my Linux box – will run on windows too but you would have to setup your compiler with glut accordingly. Note when you run this for the first second it is calibrating itself to the frame rate – but after that it knows the frame rate so scales the rate of rotation to be 8 rotations per second – still running a full FPS possible.
//this shows a way to get FPS using an imprecise clock glutTimerFunc
//on linux: g++ glut_fps_demo.cpp -lGL -lglut
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <iostream>
//linux openGL headers
#include <GL/gl.h>
#include <GL/glut.h>
GLint gFramesPerSecond = 0;
GLfloat gAngle = 0.0;
void FPS(void) {
static GLint Frames = 0; // frames averaged over 1000mS
static GLuint Clock; // [milliSeconds]
static GLuint NextClock = 0; // [milliSeconds]
++Frames;
Clock = glutGet(GLUT_ELAPSED_TIME); //has limited resolution, so average over 1000mS
if ( Clock < NextClock ) return;
gFramesPerSecond = Frames/1; // store the averaged number of frames per second
NextClock = Clock+1000; // 1000mS=1S in the future
Frames=0;
}
void timer(int value)
{
const int desiredFPS=1000000; //make infinity to go as fast as possible
glutTimerFunc(1000/desiredFPS, timer, ++value);
GLfloat dt = (gFramesPerSecond>0 ? 1.0/gFramesPerSecond : 1.0);
//put your specific idle code here
//... this code will run at desiredFPS
gAngle += dt*360./8.; //rotate 360 degrees every 8 seconds
gAngle = fmodf(gAngle,360.); // keep between 0 and 360 degrees
//end your specific idle code here
FPS(); //only call once per frame loop to measure FPS
glutPostRedisplay(); // initiate display() call at desiredFPS rate
}
void display() {
// Will be called at FPS rate, ok to use global values now to rener scene
glClear(GL_COLOR_BUFFER_BIT);
//quick and dirty way to display FPS value
printf("FPS %d Angle %g\r",gFramesPerSecond,gAngle); fflush(stdout);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef( 35/2, 35/2,0);
glRotatef(gAngle,0,0,1);
glTranslatef(-35/2,-35/2,0);
static GLuint list=0;
if (list==0) {
list=glGenLists(1);
glNewList(list,GL_COMPILE);
glColor3f(0.5,0.5,0);
glBegin(GL_QUADS);
for (int i = 0; i < 35; i++)
{
for (int j =0; j < 35; j++)
{
glVertex3f(i,j,0);
glVertex3f(i+1,j,0);
glVertex3f(i+1,j+1,0);
glVertex3f(i,j+1,0);
}
}
glEnd();
glEndList();
}
glCallList(list);
glutSwapBuffers();
}
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-10.0,46.0,-10.0,46.0,-1.0,1.0);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27: // escape key
exit(0);
break;
default:
break;
}
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutCreateWindow("FPS test /w glutTimerFunc");
glutTimerFunc(0,timer,0);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
init();
glutMainLoop();
return 0;
}