How do you make sure the speed of OpenGL animation is consistent on different machines?

animation, opengl

Solution

This is the poor man's solution:

FPS = 60.0;
while (game_loop) {
    int t = getticks();
    if ((t - t_prev) > 1000/FPS)
        process_animation_tick();
    t_prev = t;
}

this is the better solution:

GAME_SPEED = ...
while (game_loop) {
    int t = getticks();
    process_animation((t - t_prev)*GAME_SPEED/1000.0);
    t_prev = t;
}

In the first one, getframe moves your object by a fixed amount, but that is prone to errors if framerate drops.

In the latter, you move the objects based on the time passed. E.g. if 20ms pass, you rotate an object 12 degrees, and if 10ms pass, you rotate it 6 degrees. In general, the animation if a function of time passed.

Implementation of `getticks()` is up to you. For a start you could use `glutGet(GLUT_ELAPSED_TIME)`.

In your case it would look something like:

int old_t;

void idle(void) {
  int t = glutGet(GLUT_ELAPSED_TIME);
  int passed = t - old_t;
  old_t = t;
  animate( passed );
  glutPostRedisplay();
}

void animate( int ms )
{  
  if (!wantPause){    
    circleSpin = circleSpin + ms*0.01;      //spin circles
    if(circleSpin > 360.0)
    {
      circleSpin = circleSpin - 360.0;
    }
    diamondSpin = diamondSpin - ms*0.02;    //spin diamonds
    if(diamondSpin > 360.0)
    {
        diamondSpin = diamondSpin - 360.0;
    }
    ellipseScale = ellipseScale + ms*0.001;  //scale ellipse
    if(ellipseScale > 30)
    {
        ellipseScale = 15;
    }
  }
}

Problem

How do you control the speed of an animation? My objects animate faster on another's machine. ``` void idle(void){ if (!wantPause){ circleSpin = circleSpin + 2.0; //spin circles if(circleSpin > 360.0) { circleSpin = circleSpin - 360.0; } diamondSpin = diamondSpin - 4.0; //spin diamonds if(diamondSpin > 360.0) { diamondSpin = diamondSpin + 360.0; } ellipseScale = ellipseScale + 0.1; //scale ellipse if(ellipseScale > 30) { ellipseScale = 15; } glutPostRedisplay(); } } void drawScene() { ... glColor3f(1,0,0); glPushMatrix(); glRotatef(circleSpin,0,0,1); drawOuterCircles(); glPopMatrix(); } int main (int argc, char** argv) { glutInit(&argc, argv); glutInitWindowSize(400,400); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Lesson 6"); init(); glutDisplayFunc(drawScene); glutKeyboardFunc(keyboard); glutReshapeFunc(handleResize); glutIdleFunc(idle); glutMainLoop(); return 0; } ```

Original source