rakkarage's picture

fps

GameWindow.RenderFrequency can be used as or to calculate the fps somehow? thanks


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

RenderFrequency itself gives you the projected fps count. It is updated every time a RenderFrame event occurs.

There are other ways to calculate fps if you need a more stable counter:

  • Calculate the number of frames that occur over the course of a second
  • Calculate the mean RenderFrequency over the course of a second

The "over the course of a second" part can be implemented through a System.Threading.Timer or even simple polling in the RenderFrame event, using e.Time.

Arguably, the RenderPeriod provides a more useful metric, as it increases in a linear fashion with CPU/GPU load. For example, add a new graphics effect that takes 2ms and your RenderPeriod will increase by exactly 2ms, be it from e.g. 2ms->4ms or 10ms->12ms. However, in the first case the fps will fall in half (500fps->250fps), while in the second it will fall from 100fps->83fps - note that the new effect took just 2ms in both cases!

rakkarage's picture
public static class Fps
{
	static double _time = 0.0, _frames = 0.0;
	static int _fps = 0;
 
	public static int GetFps(double time) {
		_time += time;
		if (_time < 1.0) {
			_frames++;
			return _fps;
		}
		else {
			_fps = (int)_frames;
			_time = 0.0;
			_frames = 0.0;
			return _fps;
		}
	}
}

this seems to work ok... i call it from UpdateFrame and pass in e.Time

Title = String.Format("{0} - {1}", Resources.Name, Fps.GetFps(time));

rakkarage's picture

someone else posted a better one here that uses a timer and (1.0 / e.Time) but i cant find it now... "TKTests"

the Fiddler's picture

What you could do is create a timer that executes every 1 second: the timer would execute the 'else' part of your code above, while the 'if' part (_frames++) would be executed unconditionally inside every RenderFrame event.

However, there's nothing inherently better to using a timer compared to your solution above.

krisnye's picture

You could use RenderFrequency and interpolate it with the last X frames or so to get a more stable FPS.

something like this would work:

float fps = 60; // starting value, instance field.
void UpdateEveryFrame()
{
fps = fps * 0.99f + RenderFrequency * 0.01; // linear interpolate retained fps with this frames fps with a strong weighting to former.
}

gwicksted's picture

This is just as succinct as @krisnye 's example but obtains an accurate FPS more rapidly. I have included a more complete code sample because a lot of brand new devs may be interested in this early on.

    // NOTE: for new developers: this example will work with the Game.cs that you copied and pasted into Program.cs during the first Tutorial.
    class Game : GameWindow
    {
        // Set this to the same value used when initializing the game: game.Run(_fps);
        private float _fps = 30;
 
        // ...
 
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);
 
            // ... GL.Clear, GL.Begin, GL.End, SwapBuffers, etc.
 
            // Compute the fps by averaging the time between this frame and last frame (1 / e.Time) with the previous fps
            _fps = ((float)(1 / e.Time) + _fps) / 2;
 
            // Optionally add this to write the frames per second out to the console window
            // NOTE: writing to the console can be quite slow but this shouldn't dramatically affect fps
            Console.WriteLine(_fps);
        }
 
        // ...
    }
gwicksted's picture

After writing this I found you can simply do the following:

Console.WriteLine(RenderFrequency);