glutPostRedisplay not working inside a loop - opengl

I am trying to make a man jump on the y axis, so I use a loop of 2 seconds, the first second it should move down and bend its knees, and the second second it should move up and then finish in the starting position. Right now am just starting to make the man go down and bend it's knees in the first second, I haven't programmed the rest of the animation. The problem is that glutPostRedisplay is not refreshing the screen inside the loop as needed so it looks like an animation, it just re displays the screen after the loop has completed. How do I get glutPostRedisplay to refresh the screen inside my loop so it looks like an animation?
case ' ':
miliseconds = 0;
MoveManY = 0;
start = clock();
i=0;
while (miliseconds<2000)
{
finish = clock();
miliseconds = (finish - start);
Sleep(1);
if (miliseconds<1000)
{
MoveManY=MoveManY-0.02;
}
glutPostRedisplay();
}
break;

glutPostRedisplay does not directly trigger redrawing the screen. It only indicates to the system that the screen needs redrawing as soon as possible. Calling it multiple times in a loop, like you do, actually has the same effect as calling it once. See here for more details.
I cannot tell where the code you posted is called from. However, what you want to do is use glutIdleFunc to designate a method to be called when there's nothing else to do and, in it, do what you need for a single frame of your animation and call glutPostRedisplay once. This will require to move your timer somewhere else.
I found this tutorial to be really helpful with GLUT animations.

Related

What does glutTimerFunc() actually do?

If I run the following loop as part of my OpenGL program:
void Loop(int state)
{
glutPostRedisplay();
glutTimerFunc(1, Loop, 0);
}
Then, my program runs fine, and I am able to move the camera around the scene by dragging my mouse.
However, if I use this loop:
void Loop(int state)
{
glutPostRedisplay();
Loop();
}
I am not able to move around the scene with my mouse. The loop is being called, but it is just not processing any mouse or keyboard inputs.
I don't understand why this is. The only difference is that in the first example, a timer function is used to call Loop(), whereas in the second example, Loop() is called explicitly, without any delay.
So what is it that glutTimerFunc() is actually doing, besides calling Loop()?
In the first example, glutTimerFunc ensures Loop is called after 1 millisecond, however it returns and does not wait, meaning Loop in this case returns almost immediately.
In the second example, Loop is calling itself which results in infinite recursion and locks up your program's main thread, which would explain why nothing works in that case. Loop, then, never returns. If you left your program running long enough, your system would run out of memory due to the infinite recursion.

How to refresh window inside the idle function in GLUT

Im using GLUT and i need to refresh a draw inside the idle function, my code is something like that:
void idle(){
for(int i ;i<cant;i++){
/* do some stuff*/
glutPostRedisplay();
}
}
inside the idle function proccess de data what i want to redraw in every itaration.
Someone can help me?
Do one (or few) things in idle, then postRedisplay.
Let the timer (calling idle) do the loop !
you should ensure than the computation load of idle + redisplay is largely less than the timer rate you required (or the FPS you expect).

SDL_PollEvent indepth

Here is a part of SDL2 code
SDL main function
int main(int argc,char *argv[])
{
...
...
bool quit=false;
SDL_Event e;
while(!quit) ///First while (say)
{
while(SDL_PollEvent(&e)) ///Second while (say)
{
if(e.type==SDL_QUIT)
{
quit=true;
}
handleEvent(e) ;///Function for executing certain event
}
...
SDL_RenderPresent((SDL_Renderer)renderer);
}
}
My question is,what does this SDL_PollEvent() actually do ,and suppose an event occur does the execution goes out of the second while() and call the SDL_RenderPresent() or it waits for all the events to take poll and then SDL_RenderPresent() is called , i am totally confused ?
The above is a very common single thread event loop:
Basically the application is constantly inside the outer while loop. To get the smoothest user experience we try to keep this loop under 17ms (for a 60 frames a sec rate)
Every 'frame' starts by responding to all the events that are waiting in the queue (the inner while):
while(SDL_PollEvent(&e)) ///Second while (say)
{
if(e.type==SDL_QUIT)
{
quit=true;
}
handleEvent(e) ;///Function for executing certain event
}
Events are notifications from the operating system that something happened. It might be that the window is closing SDL_QUIT or that the mouse was moved.
You must respond to these events for the application to be responsive. Usually the response is to change the state of the application.
For example we might see a left-mouse is down event we might find what is "under" the mouse button and indicate that it is now selected. This is normally just finding the object and calling a function that will change its state. All that changes is the boolean value that indicates the object is now selected.
Maybe moving the mouse needs to change the point of view of the next frame so we will update the vector that stores the direction we are looking at. So we update the vector in memory.
You may have long stretches where the event queue is empty and the application does not have any events to handle. And there might be flurries of activity (for instance the user moving the mouse) where you will get lots of events to respond to.
SDL_PollEvent will not "wait" for events. If there is an event in the queue you will get the information. If there is no event it will return false.
Handling events should be done quickly (remember we have to be finished in 17ms) don't worry it is quite a lot of time on a PC.
Once you are done with all the events and out of the inner loop you are ready to move on to updating the world and rendering.
At this point you will normally do stuff like AI. Calling physics engine. For instance you might iterate over the objects and change their position based on their velocity.
The next step is to actually do the drawing.
SDL_RenderClear(renderer);
...
SDL_RenderPresent((SDL_Renderer)renderer);
The first call will clear the screen. You then go and based on the state of different objects do the rendering. For instance maybe because we changed the object state to selected we will now draw a glowing border around it.
Your final call is for SDL_RenderPresent(renderer) to present the new screen to the user
If you are using Vsync (quite common) then this final call will hide a small wait time to synch the screen update with the graphics card capabilities. This will produce a smoother graphics. Assuming a 60Hz refresh rate (60 frames per second) and assuming you are running under 16.6 ms in your frame rendering logic the app will wait the remaining time.
Now the application is ready to go back to the start of the loop and check if there are any events in SDL_PollEvent. Since the entire loop typically only takes a few milliseconds the application will always feel responsive.

glutWarpPointer makes multiple calls to the glutPassiveMotionFunc call back

I'm implementing a FPS style mouse look to "fly" around my scene.
I've got the right camera rotation and everything, my only problem is that when I try to warp the mouse to the middle of the screen, it performs multiple calls to the glutPassiveMotionFunc call back. So instead of teleporting the mouse, its moving it there over a few movements. These movements get processed and move the camera back to the original position.
How do I check that the mouse was actually moved and it was not triggered by the glutWarpPointer function.
I've tried to not process a movements if the pointer is in the middle of the screen but this doesn't help.
I want my program to run on Linux and Windows so I cannot use OS specific functions.
I wouldn't call this a great solution, but it should work:
bool isWarpingPointer = false;
void MyPassiveMovementCallback()
{
if (isWarpingPointer)
{
return;
}
//proceed normally
}
//elsewhere
isWarpingPointer = true;
glutWarpPointer();
isWarpingPointer = false;

Is there a way to check the glut key buffer?

EDITED WITH SOLUTION
So I am making a particle system in opengl. I am working in Linux. I want to make it more interactive, so, for example, when the user presses the spacebar, a new firework shoots out.
I am using GLUT to capture keyboard input, and when the user hits the spacebar, it shoots a firework out, then goes in a loop that loops for a while, and if I press spacebar again, it has to wait til that loop (mentioned above) is done executing before it registers the keypress.
So my question is this:
Is there a way for me to, at the start of the loop, to check the buffer that glut stores the keypress in? I feel like there has to be some sort of a buffer that it stores keypresses in, because yeah, once that loop above is finished executing, it registers the keypress.
SOLUTION:
I do not actually do any loops now anywhere (except to loop through arrays to update locations of my fireworks, etc), I do something like
in main, add this:
int main(int argc, char** argv){
//Usual glut initializations
glutTimerFunc(30, update, -1);//says in 30miliseconds call update
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Then in your update function (in the parameters for glutTimerFunc, so something like this:
void update(int k){
//UPDATE POSITION OF FIREWORKS
glutTimerFunc(30, update, -1);//it is important to add this
glutPostRedisplay();//calls display() on the next iteration of glut's main loop
}
Then finally in your display function, do what ever you need to do to draw one frame (in my case, loop through each firework and draw it!)
Hope this helps :)
You're going about this the wrong way.
Your keypress handler should not be looping over anything. Your keypress handler should simply set some variable and return.
Your main display function (which should be driven by a timer function that calls glutPostRedisplay) should check this variable. If it is set, then it should be firing your firework and looping for some duration.
During that time, your keypress handler should simply ignore any further pressing of the spacebar. Once the display function finishes with the firework, then it can respond to further key presses.