# GLUT idle func

This topic is 3764 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi Guys, I want my ball to move around in the window and I am using the idle function for this. The problem is, is once I run the app the ball is no where to be seen. See code: #define angle 45.0 #define M_PI 3.14 void idlefunc(void) { glClear (GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 0.0); glPointSize (4); glBegin (GL_POINTS); glVertex2f (- LENGTH * sin( angle * M_PI / 180.0 ), LENGTH * cos( angle * M_PI / 180.0 )); glEnd (); glutSwapBuffers(); glFlush(); glutPostRedisplay(); }

##### Share on other sites
1. Don't call GL functions from your idle func. Instead call glutPostRedisplay to instruct GLUT to call your display function, and do the drawing there.

##### Share on other sites
Thanks. I've moved the code back into the display function.

Now does anyone know why my dot disappears when I load the app ?

##### Share on other sites
Ok, so I've managed to get it to work. But I have a new problem, the ball doesn't want to move unless I move the mouse on the windows bar (the blue bar on XP). Does anyone know the reason behind this ?

##### Share on other sites
1. You don't have to call glFlush if you call glutSwapBuffers.
2. I have a sneaking suspicion that you but glutPostRedisplay in your render function. If that's not it, then show your new code.

##### Share on other sites
Lol, you are right. I am using glutPostRedisplay in idle to render my functions. What would be a better method ?

##### Share on other sites
No, it's OK to put glutPostRedisplay in your idle function. I was trying to find out if you had perhaps put in in your render function. glutPostRedisplay is great to put at the end of your other glut functions. I typically call render directly from idle, but that's probably bad practice.

So, let's see your new idle and render functions.

##### Share on other sites
Ok. Here is my latest code and findings:

GLfloat getInitialAngle(void)
{
time_t calendarTime = time(NULL);
srand(localtime( &calendarTime)->tm_sec );
return ( (float) rand() / (float) RAND_MAX ) * 90.0 - 45.0;
}

void display(void)
{
float angle = getInitialAngle();
glClear (GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 0.0);

glBegin(GL_LINE_LOOP);
glVertex2f( X_CENT - LINE_LENGTH / 2, Y_CENT - LINE_LENGTH / 2);
glVertex2f( X_CENT + LINE_LENGTH / 2, Y_CENT - LINE_LENGTH / 2);
glEnd();

glPointSize (4);
glBegin (GL_POINTS);
glVertex2f (-LINE_LENGTH * sin( angle * M_PI / 180.0 ), LINE_LENGTH * cos( angle * M_PI / 180.0 ));
glEnd ();

glutSwapBuffers();
}

void idle(void)
{
glutPostRedisplay();
}

What I've noticed is when I put the GLfloat getInitialAngle(void) function underneath the display(); function then I have to constantly move my mouse on the window bar (xp blue bar) in order for the ball to move. But if I put GLfloat getInitialAngle(void) above the display function then the ball doesn't move. Although when I run the program initially it makes 1 move after the app has been running for afew seconds but thats it.

##### Share on other sites
You should only use srand once, somewhere in your initialization. "Random" numbers come in a predictable sequence, based on whatever number you end up sseding with. As it is, you're only using 60 possible values (0..60).

Picture this: a random number sequence with only ten available numbers: 0, 4, 3, 8, 1, 9, 2, 5, 7, 6

If you say srand(3) then the next number will be 8. If you call rand again without seeding, the next number will be 1, and after that 9.

If you say srand(1) then rand returns 9, and after that 2, and then 5.

But what you're doing it essentially this:

the loop {  what time is it? 17:42:00.000  seed with the seconds (0)  get a random number   (4)  do stuff with 4  what time is it? 17:42:00.001  seed with the seconds (0)  get a random number   (4)  do stuff with 4  what time is it? 17:42:00.002  seed with the seconds (0)  get a random number   (4)  do stuff with 4  ...later...  what time is it? 17:42:00.999  seed with the seconds (0)  get a random number   (4)  do stuff with 4  what time is it? 17:42:01.000  seed with the seconds (1)  get a random number   (9)  do stuff with 9  what time is it? 17:42:01.001  seed with the seconds (1)  get a random number   (9)  do stuff with 9  ...and so on...}

So, it's going to change at best every second anyways. Besides that, many rand() functions return the same value for seeds of 0 and 1, so that first jump is a two second wait. On top of that, there's no guarantee that a seed of 2 is going to return a number that's noticeably different from what you had after you change it into an angle, and then run it through trig functions.

So the lesson is: Call srand() just once. For the children.

##### Share on other sites
Thank you for your excellent explanation. So if I want to initialise the srand only once, how would I do that ?

I'm guessing I would need to move float angle = getInitialAngle(); from the display(); to the top ? I have tried that, but I don't know how to declare it. Should it be a GLfloat, an int, or float etc ?

##### Share on other sites
Just put srand() somewhere in main(), before you initialize gl/glut.

GLfloat getInitialAngle(void) {  return ( (float) rand() / (float) RAND_MAX ) * 90.0 - 45.0;}int main() {  srand( time(NULL) );  ...  // everything you already had goes here  ...  return 0;}