Reputation: 2046
Right now I have two timers. One for physics and one for display.
The display timer is attached to the main window. It is about once every 5 ms and posts the message WM_PAINT, and the WM_PAINT message handler says to run the opengl display code, then do SwapBuffers().
The physics timer is attached to the secondary window (for no reason other than that the only way I know how to implement a windows timer is to attach it to a window). The handler makes it update my physics code.
However, I noticed that sometimes the display is "spazzy". It is barely noticeable, perhaps one tiny spaz per second, but I suspect there is something going on that makes the physics move slower or faster for a short burst of time.
Upvotes: 3
Views: 913
Reputation: 162164
The correct method for interactive simulations (like your's) is to call the drawing function as the idle action:
... idle_action(...)
{
redraw();
}
... event_loop(...)
{
while(!quit) {
event e = PeekEvent();
if( e != NO_EVENT ) {
process_event();
} else {
idle_action();
}
}
}
Instead of using timers you should measure the time it takes to draw a frame.
Also for the sake of precision of the physics simulation you should not use a timer for that either. Instead you should advance it in smaller timesteps of constant length, so that there multiple timesteps to a single rendered frame. So for example for a 60Hz refresh rate you have a frame interval of ~16ms. If you perform your physics simulation in steps of 1ms you'd calculate 16 steps inbetween. *Note that most, if not all physics simulation packages do this internally. I.e. you're setting the step interval and then only call the physics simulation with the desired time you's like it to progress.
In practice that means, that you'll advance your physics simulation by the time you measured the frame drawing to take.
Upvotes: 3