Hello,
I’ve got an other problem I have an 2d quad wich I move in my glut idle function with glTranslate. Now there is everything fine but when i run it and the object moves it moves first fast then slow and then fast again. Where does this come from I’ve no idea! Thx for answers!
Greedings cookiesoft
This is because you are in a multitasking OS and that somes others process can sometimes “temporally freeze” your OpenGL task
For a linear translation on the x axis don’t use a basic “x += dx” but something like “x += dx * elapsedtime” where elapsedtime is the difference time between the last frame and the instant where you begin to draw the current frame, and where elapsedtime is updated at the beginning of each new frame
=> if a frame begin a “long” time after another, the elapsedtime value is then bigger so the translation is bigger too
(this work too on another side, if a frame begin “quickly” after another, the elapsedtime value is small, so the translation is small too)
You can for example regularly update the elapsedtime value using “elapsedtime = ElapsedTime()” at the beginning of each frame :
struct timeval last;
int inited = 0;
double ElapsedTime()
{
struct timeval current;
double last_ms , current_ms , diff;
if( inited == 0)
{
gettimeofday(&last , NULL);
inited = 1;
return 0;
}
else
{
gettimeofday(¤t , NULL);
last_ms = (double)last.tv_sec*1000000 + (double)last.tv_usec;
current_ms = (double)current.tv_sec*1000000 + (double)current.tv_usec;
diff = (double)current_ms - (double)last_ms;
last = current;
return diff / 1000000;
}
(this give a timediff in seconds)
Here is an functional example with a constant time rotations of a cube and a triangle :
/*
* from OGL01Shape3D.cpp: 3D Shapes (http://www.ntu.edu.sg/home/ehchua/programming/opengl/CG_Examples.html)
*/
#include <GL/glut.h> // GLUT, include glu.h and gl.h
/* Global variables */
char title[] = "3D Shapes";
/* YLP 25 april 2013 : add a "constant time" rotation */
#include <sys/time.h>
#include <stdlib.h>
struct timeval last;
int inited = 0;
double ElapsedTime()
{
struct timeval current;
double last_ms , current_ms , diff;
if( inited == 0)
{
gettimeofday(&last , NULL);
inited = 1;
return 0;
}
else
{
gettimeofday(¤t , NULL);
last_ms = (double)last.tv_sec*1000000 + (double)last.tv_usec;
current_ms = (double)current.tv_sec*1000000 + (double)current.tv_usec;
}
diff = (double)current_ms - (double)last_ms;
last = current;
return diff / 1000000;
}
float cubeRotate = 0.0f;
float triRotate = 0.0f;
float cubeInc = 1;
float triInc = 1;
float elapsed = 0.0f;
void idleFunc()
{
elapsed = ElapsedTime() * 100;
cubeRotate += cubeInc * elapsed;
triRotate += triInc * elapsed;
glutPostRedisplay();
}
/* Initialize OpenGL Graphics */
void initGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClearDepth(1.0f); // Set background depth to farthest
glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
glDepthFunc(GL_LEQUAL); // Set the type of depth-test
glShadeModel(GL_SMOOTH); // Enable smooth shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
}
/* Handler for window-repaint event. Called back when the window first appears and
whenever the window needs to be re-painted. */
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix
// Render a color-cube consisting of 6 quads with different colors
glLoadIdentity(); // Reset the model-view matrix
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
glRotatef(cubeRotate, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd(); // End of drawing color-cube
// Render a pyramid consists of 4 triangles
glLoadIdentity(); // Reset the model-view matrix
glTranslatef(-1.5f, 0.0f, -6.0f); // Move left and into the screen
glRotatef(triRotate, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES); // Begin drawing the pyramid with 4 triangles
// Front
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f);
// Right
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f);
// Back
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f(1.0f, -1.0f, -1.0f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, -1.0f, -1.0f);
// Left
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f,-1.0f);
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f);
glEnd(); // Done drawing the pyramid
glutSwapBuffers(); // Swap the front and back frame buffers (double buffering)
}
/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
void reshape(GLsizei width, GLsizei height) { // GLsizei for non-negative integer
// Compute aspect ratio of the new window
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;
// Set the viewport to cover the new window
glViewport(0, 0, width, height);
// Set the aspect ratio of the clipping volume to match the viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity(); // Reset
// Enable perspective projection with fovy, aspect, zNear and zFar
gluPerspective(45.0f, aspect, 0.1f, 100.0f);
glutPostRedisplay();
}
/* Main function: GLUT runs as a console application starting at main() */
int main(int argc, char** argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(640, 480); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow(title); // Create window with the given title
glutDisplayFunc(display); // Register callback handler for window re-paint event
glutReshapeFunc(reshape); // Register callback handler for window re-size event
glutIdleFunc(idleFunc);
initGL(); // Our own OpenGL initialization
glutMainLoop(); // Enter the infinite event-processing loop
return 0;
}
I use this for to compile it on my linux box :
gcc const_rot.c -lGL -lglut -lGLU -o const_rot
ok thx i’ll try it…
On another side, are yours update and/or display fonctions using a constant time to execute ?
And/or consume a lot of CPU time ?
hmh i dont now what you mean with “constant time” but my idle function looks sth like that:
void loop(){
render stuff...
glutSwapBuffers();
}
But i don’t use the display function.