Frame rate capping (aka predictable drawing time)

Hi all,

I knocked up a simple frame rate capping class this evening to make my life easier - I was fiddling with a few things, and my animations were running at different speeds depending on the amount of work done that frame. Lock the frame rate to 60 FPS and I can be sure that things will run at no more than that rate.

This is a very simple bit of code, and is a first cut. It works fine, but needs a few more features. Cas mentioned the process in his diary a while back, and I’ve just found need for it.

I’d be grateful if anyone interested in it give it a go and tell me if it works for you. Consider it BSD licenced! Here’s the new class:

import org.lwjgl.Sys ;

public class FrameRateCap
{
      private FrameRateCap() {}

      private static int frameRate = -1 ;
      private static long preferredFrameTicks ;
      private static long frames ;
      private static long startTick ;
      private static long endTick ;
      private static long frameStartTick ;

      public static void setFrameRate(int frameRate2)
      {
            assert (frameRate2 > 0) : frameRate2 ;
            assert (frameRate == -1) : "Already set" ;

            frameRate = frameRate2 ;
            preferredFrameTicks = Sys.getTimerResolution() / frameRate ;
      }

      public static void start()
      {
            startTick = Sys.getTime() ;
            frames = 0 ;
      }

      public static void startFrame()
      {
            frameStartTick = Sys.getTime() ;
      }

      public static void endFrame()
      {
            frames++ ;

            long frameDurationTicks = Sys.getTime() - frameStartTick ;

            while(frameDurationTicks < preferredFrameTicks)
            {
                  long sleepTime = ((preferredFrameTicks - frameDurationTicks) * 1000) / Sys.getTimerResolution() ;

                  try
                  {
                        Thread.sleep(sleepTime) ;
                  }
                  catch(InterruptedException e)
                  {
                  }

                  frameDurationTicks = Sys.getTime() - frameStartTick ;
            }
      }

      public static void end()
      {
            endTick = Sys.getTime() ;
      }

      public static long getFrames()
      {
            return frames ;
      }

      public static float getFramesPerSecond()
      {
            return frames / ((endTick - startTick) / (float)Sys.getTimerResolution()) ;
      }
}

And you use it like this:

FrameRateCap.setFrameRate(60) ;
FrameRateCap.start() ;

while(!finished)
{
      FrameRateCap.startFrame() ;

      // Drawing code here

      FrameRateCap.endFrame() ;
}

FrameRateCap.end() ;

System.out.println("Frames rendered: " + FrameRateCap.getFrames()) ;
System.out.println("FPS: " + FrameRateCap.getFramesPerSecond()) ;

You just tell it how many FPS you want, tell it when the drawing process starts and ends, and tell it about the start and end of each frame, and it’ll introduce a padding delay if the drawing completed early and track number of frames rendered and actual frames per second for you.

Any comments?

Nice, I’ll give it a go this weekend :slight_smile:

Is this really neccessary? using the Sys.getTime() I managed to get the time it takes to draw each frame and then update the current FPS depending on the time it took. Something like this:

temp = Sys.getTime();

rendering code…

FPS = 1((Sys.getTime() - temp)/Sys.getTimerResolution());

It’s not for throttling gameplay, but just to limit the fps. More than 60fps is just not necessary so when you limit to that speed, you will have time left for other things(like GC?).

[quote]More than 60fps is just not necessary
[/quote]
And 640 kb is enough? :stuck_out_tongue:

Seriously I can detect a difference in 60 fps vs. 100!
Monitor updates below 85Hz almost makes my eyes bleed.

You are confusing framerate with monitor update frequency. The latter will make your eyes bleed if set to low, the first will just look ugly.

A 60 fps framerate is way more than what is used in Hollywood movies (20-something i believe?), and way way more than what is used in e.g. anime movies (12fps I think).

So yes, 60fps is quite enough. And no, it is not comparable to BGs famous 640K statement :), as human eyes are not likely to evolve at the same rate that computer HW and SW has :stuck_out_tongue:

(Oh, and another thing: Monitor update frequency is not a generic problem, but related especially to CRT monitors because these screens loose their charge quickly, a TFT at 60Hz is rock solid)

[quote]You are confusing framerate with monitor update frequency.
[/quote]
no no no :slight_smile:
That was why I talked fps vs monitor updates (refresh rate)

[quote] A 60 fps framerate is way more than what is used in Hollywood movies (20-something i believe?), and way way more than what is used in e.g. anime movies (12fps I think).
[/quote]
Yes, TV’s are 24 fps - however unlike Cameras, computers cannot (or rather do not) use motion blur, which is what makes 24 fps acceptable.

[quote] So yes, 60fps is quite enough.
[/quote]
As you also know, any game doing 24 fps will look awfully jerky - and many will also say that they can feel a difference between 60 and 100 fps - I for one can.
But this is mostly related to FPS games. Many games can get off with much lower framerates - puzzle/rpg/rts games often do much lower framerates - some even 30 fps.

No problem, cap the frame rate to 100 instead! ;D

This little class is just designed to waste a bit of time at the end of each frame, making sure the frame rate never goes above a certain limit. Naturally, if your drawing takes longer than the set limit allows it’ll never sleep and your frame rate will drop.

The primary purpose of this is not to calculate your FPS, but to slow down the game logic so animations can be written to change every six frames or whatever - avoiding the need to calculate actual frame rendering time and adjust animations, object movements etc accordingly.

It’s a time saving hack really, but I’ve found it pretty darn useful. Naturally, depending on how you’ve written your render/update logic, this solution may be totally inappropiate for you. YMMV and all that.

[quote]Yes, TV’s are 24 fps
[/quote]
Not that it’s really important, but TV’s are 25 fps in Europe and 30 fps in the US, 50 resp. 60 fps interlaced.
Cinema is 24fps.

Actually North American television is approximately 29.97 frames per second, it was only 30 fps in the days of black and white. :-)

The only reason I bring it up, is that it sometimes matters if you are doing video work and you want your audio and video to stay in sync.

Yeah, I always loved that 24/25 incompatibility between cinema and TV. They generally don’t bother rescaling the original accordingly.

This does mean that films on TV are just that little bit shorter than in the cinema, and the voices are a bit faster and higher in pitch. Not something that many people would notice, but bloody funny when you think about it.

Well perhaps it is less disturbing than the 3:2 pull down that is used to show movies in NTSC…
I often wonder why they don’t just make the PAL TVs so they can sync to 24fps and come up with a signal variation with slightly different timing… I know that we did just that at the last company I worked at to make a true ‘film mode’ video preview.

[quote]Yeah, I always loved that 24/25 incompatibility between cinema and TV. They generally don’t bother rescaling the original accordingly.

This does mean that films on TV are just that little bit shorter than in the cinema, and the voices are a bit faster and higher in pitch. Not something that many people would notice, but bloody funny when you think about it.
[/quote]
it’s a part of the evil plan of the industry :>

think about it… that allows more commercials :o

back to the fps discussion… i play q3 with 85 fps and i know that 85fps can be smooft or jerky.

there are some things wich are neccessary to get it smooft:
[]vsync. it’s essential - no tearing and it ensures, that the time between each frame stays the same (if the comp is fast enough)
[
]the movement has to be steady. if something moves with 4 units per frame, it should always move this 4 units (340ups) - not 3 in one and 5 in another.
[*]a matching mouse polling interval is nice or twice as high and interpolation or just higher (than the hz of the display)

first one is nice and more ergonomic. 2nd has a huge impact - it feels like havin at least 30% fps more. 3rd is just an accuracy thingy but it’s nice this way :slight_smile:

hm… all we need is a hi-res timer. vote for it :slight_smile:

well timing is much easier for console devers. 25, 30, 50 or 60 fps… timing is frame/game tick based and u have to ensure that u get that framerate always otherways u get slowdowns (half fps=half ticks=half speed).

One comment Onyx. Sometimes games can be smoother if the characters move a different number of pixels per frame. A walking animation for example, should cause the character to move more pixels during the longer part of the stride, and fewer during the shorter part. This looks natural and more realistic. Other than that, you’re dead on. :slight_smile: