animation speeding up out of control

hi, im having a bit of trouble keeping this rotating torus at a constant speed, i’ve reduced the increment of it rotation to a really small number. it starts off fine but then speeds up, is this something to do with buffers? i apologise for my ignorance i’m a newbie.

Here’s the code:
#include <gl\glut.h>

float angle=0.0;

void init(void)
{
GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};
GLfloat mat_shininess[] = {50.0};
GLfloat light_position[] = {1.0,1.0,1.0,0.0};
GLfloat white_light[] = {1.0,0.0,0.0,1.0};
GLfloat lmodel_ambient[] = {0.4,0.1,0.1,1.0};
glClearColor(0.0,0.0,0.0,0.0);
glShadeModel(GL_SMOOTH);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);

}

void display (void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glRotatef(angle,0.0,1.0,0.0);
glutSolidTorus(0.25,0.5,4,100);
angle=angle+0.001;
glutSwapBuffers();
glFlush();
}

int main (int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500,500);
glutInitWindowPosition(100,100);
glutCreateWindow(“Rotating Torus”);
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutMainLoop();
return 0;
}

Thanks for your help.

glRotate multiplies the current modelview matrix with a rotation matrix that represents your rotation around the Y-axis.
Every time you call display (), the current modelview matrix is multiplied, including your previous rotations, so they are being summed. After a while your rotation will indeed become huge. You can fix this two ways:

  • call glRotatef(angle,0.0,1.0,0.0); in display() without increasing the angle (so leave out angle=angle+0.001;). This way your rotation will be summed with the previous rotation each time (the effect you want to achieve with angle+= 0.001). the next way works better though:

  • call glLoadIdentity () right after glClear(GL_COLOR_BUFFER_BIT | L_DEPTH_BUFFER_BIT); this will reset the modelview matrix. You can now rotate the torus each time, without having the effect of the previous rotations (you have to keep angle += 0.001). Usually it’s a good idea to start your display function with a call to glLoadIdentity (), so your current drawing won’t be affected by previous rotations, translations or scalings.

greetz

Don’t use:

angle=angle+0.001;

But:

angle+= angular_speed * dt;

with angular_speed is the speed (number of turns per second) and dt is the elapsed time in seconds since the last draw.

Thanks, i’ve got it working! Superb.