GLUT idle func

Started by
9 comments, last by erissian 16 years, 5 months ago
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(); }
Advertisement
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.
Thanks. I've moved the code back into the display function.

Now does anyone know why my dot disappears when I load the app ?
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 ?
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.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Lol, you are right. I am using glutPostRedisplay in idle to render my functions. What would be a better method ?
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.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
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.
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.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
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 ?

This topic is closed to new replies.

Advertisement