How to do a XNA fps counter

Frame rate or FPS, how it is most commonly known is a way for you to know how many images per second is you game drawing. The more the better. Less then 30 and you start to see hiccups.

So how can you measure your frame rate in XNA?

Inside your game1 class declare these vars:

SpriteFont  _spr_font;
int _total_frames = 0;
float _elapsed_time = 0.0f;
int _fps = 0;

On function LoadContent() do

// Put the name of the font
_spr_font = Content.Load("kootenay"); you have on your project

On the update pump do:

 protected override void Update(GameTime gameTime)
        {
            // Update
            _elapsed_time += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
 
            // 1 Second has passed
            if (_elapsed_time >= 1000.0f)
            {
                _fps = _total_frames;
                _total_frames = 0;
                _elapsed_time = 0;
            }
 
            // Allows the game to exit
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                this.Exit();
 
            base.Update(gameTime);
        }

Finally on Draw function do:

protected override void Draw(GameTime gameTime)
        {
            // Only update total frames when drawing
            _total_frames++;
            GraphicsDevice.Clear(Color.CornflowerBlue);
 
            spriteBatch.Begin();
            spriteBatch.DrawString(_spr_font, string.Format("FPS={0}", _fps),
                new Vector2(10.0f, 20.0f), Color.White);
            spriteBatch.End();
 
            base.Draw(gameTime);
        }

If everything went alright you should have a white counter on the upper left screen. You probably want to turn this into a drawable component or adjusting it to be an independent component on your engine.

xna_fps_counter

Here’s the project for VC# Express : download

note: For those who have asked me why do I use a prefix _ on some variables. I use this to help me know which vars are members of the class and which aren’t. I don’t like using mPosition, instead I use _Position.

7 Comments

  1. Thorsten

    if (_elapsed_time >= 1000.0f)

    Does not works wiht C# XNA 4.0 – what means &gt ? Even when i remove this &gt i get compiler error, cant convert typ float into bool. Any idea? thx

  2. Chris

    Thorsten, the > thing is a HTML code – and it got there simply because you copied and pasted from this website. Just replace it with a > symbol.

  3. Carson

    Or you could be a real G and just write:
    spriteBatch.DrawString(font, “FPS: ” + (1000 / gameTime.ElapsedGameTime.Milliseconds), position, Color.White);

  4. Thanks for sharing.

  5. string.Format(“FPS={0}”, _fps) will create garbage.

    Better to update a StringBuilder perhaps. A tiny point, but relevant knowledge for a tut.

    Thanks for the tuts. good reads.

  6. public struct stringbuilderHolder
    {
    public StringBuilder sb;// = new StringBuilder();
    private string __holder_string_so_not_touch;

    public stringbuilderHolder(int stringBuilderImmutableSize)
    {
    // 32 , 32 was the default.
    sb = new StringBuilder(stringBuilderImmutableSize, stringBuilderImmutableSize);
    __holder_string_so_not_touch = (string)sb.GetType().GetField(
    “m_StringValue”, BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(sb);
    }

    public void empty()
    {
    if (sb.Length > 1)
    {
    sb.Remove(0, sb.Length);
    }
    }
    }

    then in your class

    #if DEBUG

    public static stringbuilderHolder screenOutputStringbuilder;

    #endif

    then in Update()

    #if DEBUG

    // Update
    DebugParams._elapsed_time += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

    // 1 Second has passed
    if (DebugParams._elapsed_time >= 1000.0f)
    {
    DebugParams._fps = DebugParams._total_frames;
    DebugParams._total_frames = 0;
    DebugParams._elapsed_time = 0;
    }

    // clean out the stringbuilder; regardless of how full it is we always just “remove” on it.
    // NOTICE WE CALL IT ON THE STRUCT NOT THE STRINGBUILDER

    screenDebugOutputStringbuilder.empty();

    // use the Screen Output Stringbuilder for something
    screenDebugOutputStringbuilder.sb.ConcatFormat(“FPS={0}”, DebugParams._fps);

    #endif

    And finally in Draw()

    #if DEBUG
    DebugParams._total_frames++;
    spriteBatch.DrawString(font, screenDebugOutputStringbuilder.sb, DebugParams.DebugTextLocation , Color.White);
    // Only update total frames when drawing

    #endif

    props to http://www.gavpugh.com/xnac-articles/

    Zero Garbage. Hope it helps someone else.

  7. public struct DebugParams
    {
    public static Vector2 DebugTextLocation;

    public static void InitializeTitleSafeArea(GraphicsDevice GraphicsDevice)
    {
    DebugTextLocation = new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, GraphicsDevice.Viewport.TitleSafeArea.Y);
    }

    public static int _total_frames = 0;
    public static float _elapsed_time = 0.0f;
    public static int _fps = 0;

    }

    Just to keep my life simple.

Leave a Reply