1

I am using this code structure below from here http://www.koonsolo.com/news/dewitters-gameloop/ to set a game loop that processes based on a set fps but renders/draws at the most possible. How would one implement a cap on the drawing fps so as not to use up all the processing power /battery life. or to limit it for v-syncing.

const int TICKS_PER_SECOND = 60;
const int SKIP_TICKS = 1000000000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 5;

DWORD next_game_tick = GetTickCount();
int loops;
float interpolation;

bool game_is_running = true;
while( game_is_running ) {

    loops = 0;
    while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
        update_game();

        next_game_tick += SKIP_TICKS;
        loops++;
    }

    interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
                    / float( SKIP_TICKS );
    display_game( interpolation );
}
RustyH
  • 473
  • 7
  • 22
  • I would assume your int TICKS_PER_SECOND is the set frame rate. Why don't you try lowering that number? – Tristan Hull Oct 11 '12 at 02:30
  • that is for the logic loop it sets it to 60 but the "display_game" function is called as often as possible often drawing over 1000 fps if not much is going on so as to always max out the processor (constant 98-99% on task manager) – RustyH Oct 11 '12 at 02:34

2 Answers2

2

I assume that you are actually doing proper motion interpolation? Otherwise it doesn't make sense to render faster than your game update: you'll just be rendering all the objects again in exactly the same position.

I'd suggest the following:

  • Put a Thread.sleep(millis) call in to stop the busy-looping. Probably a Thread.sleep(5) is fine, since you are just going to do a quick check for whether you are ready for the next update.
  • Put a conditional test on the display_game call to see if at least a certain number of millisconds has elapsed since the last display_game. For example, if you make this 10ms then your frame rate will be limited to 100 FPs.

There are also a couple of other things that are a bit unclear in your code:

  • What is DWORD? Is this really Java? Looks like some funny C/C++ conversion? The normal way to get the current time in Java would be long time=System.nanoTime() or similar.....
  • What graphics framework are you using? If it is Swing, then you need to be careful about what thread you are running on, as you don't want to be blocking the GUI thread....

Finally, you should also consider whether you want to decouple your update loop from the rendering code and have them running on different threads. This is trickier to get right since you may need to lock or take snapshots of certain objects to ensure they don't change while you are rendering them, but it will help your performance and scalability on multi-core machines (which is most of them nowadays!)

mikera
  • 105,238
  • 25
  • 256
  • 415
  • sorry that code was taken from the link above(its really just pseudocode) dword is just double, and they would not draw in the same place because of the interpolation and i am using libgdx framework which is using opengl Edit: the small sleep does work i just thought that might be sloppy but it seems to work just fine. – RustyH Oct 11 '12 at 03:03
  • the sleep works ok but now i have a sleep that could hurt the logic loop's cycles in the long run. the conditional seems more logical just like the logic loop but for some reason it causes very odd rubber-banding and jerking. im toying with it but it does not seem to be working very well – RustyH Oct 11 '12 at 03:33
  • Have you made sure that you still interpolate using the ticks derived from the update loop? If you switch to using the display loop ticks to calculate the interpolation then you will definitely get strange behaviour..... – mikera Oct 11 '12 at 03:39
  • yeah tried with and without i ended up using a combination i checked for how long it had been then if it had not been long enough i waited the difference so ill give it to ya since it lead me to it. – RustyH Oct 11 '12 at 03:54
0

I think you can update your display_game to compare the FPS being painted against the desired limit. If it has reach that limit, you can add a wait time for wait time as:

   Thread.sleep(500); //wait for 500 milliseconds
Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
  • while the sleep works the comparing it to the fps hurt the flow of the game drastically. – RustyH Oct 11 '12 at 03:09
  • I meant compare the fps against a constant limit (int). Are you saying one addition compare statement of int is adding so much overhead? – Yogendra Singh Oct 11 '12 at 03:20