5
\$\begingroup\$

I'm making a first person shooter, and I've seen questions like this before, but the answer is either overly complicated or they're using SDL, GLFW, GLUT, or something else. I'm not using any of that. OpenGL, C++, and GLEW for me.

I am just a little confused on how to do a framerate counter, so if I could get pseudo-code or some code-snippets that would point me in the right direction, that would help.

\$\endgroup\$
3
  • \$\begingroup\$ frame rate is simply draws / time... so you could get an average "over time" frame rate by counting your total draw calls and dividing that by seconds elapsed... or doing this for FPS i think its fairly common to do that same process updating some text on screen once a second with the last seconds findings \$\endgroup\$
    – Joe
    Commented Sep 9, 2014 at 14:53
  • \$\begingroup\$ @Joe but how would I get my draw calls? Cuz draw calls divided by time sounds like a good method for me. \$\endgroup\$
    – ezio160324
    Commented Sep 9, 2014 at 14:56
  • 2
    \$\begingroup\$ if you aren't familiar with the traditional game loop id strongly recommend checking out this question gamedev.stackexchange.com/questions/8623/… \$\endgroup\$
    – Joe
    Commented Sep 9, 2014 at 14:58

2 Answers 2

7
\$\begingroup\$

To measure framerate you need two counts:

  • How many frames (not draw calls) have passed, and,
  • How much time has passed.

Your framerate is therefore calculated as:

frames / time

There are a few subtle complexities to this.

First thing is that you need a good, accurate, high resolution timer. You don't say what platform you're on so I'm not going to make any assumptions beyond:

  • You have such a timer available, and,
  • You're not using Sleep calls to control framerate (if you are, stop it now).

Let's say that you're storing the time in a variable called "timepassed". It's a double and it starts at 0 and counts the time (in seconds) since the game started. Our framerate counter begins like this:

static int frames = 0;
static double starttime = 0;
static bool first = TRUE;
static float fps = 0.0f;

The first thing we do is check if this is the first time we've passed through the counter and set some stuff up:

if (first)
{
    frames = 0;
    starttime = timepassed;
    first = FALSE;
    return;
}

Next we increment the number of frames that have passed; I'm assuming here that you're updating the framerate counter once per frame only:

frames++;

And here we evaluate the actual FPS number.

if (timepassed - starttime > 0.25 && frames > 10)
{
    fps = (double) frames / (timepassed - starttime);
    starttime = timepassed;
    frames = 0;
}

Here we update the FPS count every 0.25 seconds. This isn't strictly speaking necessary but otherwise if you have a variable framerate you're going to be getting numbers wildly flashing on your screen and you won't be able to read them too good. (It's also important that timepassed - starttime is greater than 0.) After calculating the FPS we then update our static variables for the next pass through.

This is prety much my standard FPS counter (it's C heritage shows in some of the code) and I've cross-checked it with the values provided by FRAPS and found it highly accurate.

\$\endgroup\$
6
  • \$\begingroup\$ The standard "don't measure FPS, measure milliseconds per frame" disclaimer applies here, but I should note that an FPS count is what players are used to seeing and provides a number that's meaningful to them, so despite the disclaimer I find that an FPS count still has value. \$\endgroup\$ Commented Sep 9, 2014 at 23:52
  • 2
    \$\begingroup\$ Your code is pretty good, but I would suggest replacing that Win32 BOOL by just bool/true|false. Any decent C compiler can run C99 these days, so I don't see a reason to still rely on the MS typedefs. \$\endgroup\$
    – glampert
    Commented Sep 10, 2014 at 2:14
  • 1
    \$\begingroup\$ You're not using Sleep calls to control framerate (if you are, stop it now). Whoa now, I wouldn't be so absolute. Sleep is unreliable and hence it's unwise to use it alone, but it's perfectly reasonable to use it if you can manage the unreliability by using it with a more precise method. Doing so makes sure you don't peg your CPU at 100%, which is important for anything that runs on batteries. \$\endgroup\$ Commented Sep 10, 2014 at 2:24
  • 1
    \$\begingroup\$ @congusbongus : i was heading to the comments to say exactly that. +1 Also as a supplentary comment for FPS counting, the regulated update (every 250ms) is good for stability, there is an even better method to my sense (the one unreal tournament uses), is a rolling average based on a fixed time frame, with varying sampling. Of course the OP here seems confused enough, so the answer is well suited. \$\endgroup\$
    – v.oddou
    Commented Sep 10, 2014 at 5:35
  • 1
    \$\begingroup\$ @congusbongus - I'm drawing a distintion between using Sleep to save power and using it to control framerate. The former is appropriate, the latter is not. Even if Sleep were reliable and even if it gave you sub-millisecond control, Sleep (1/60) wouldn't give you 60fps because it doesn't account for the time taken to actually run the frame. You still need a proper timer. \$\endgroup\$ Commented Sep 10, 2014 at 7:41
0
\$\begingroup\$

Since you are using SLD then the first thing to do is look up SDL_GetTicks();

Obviously it's very easy to figure out what to display on your counter from there but you need to actually display it, too.

Generally you want to use something like FreeType to allow you to load entire font sets. This gives you a great deal of information about each "glyph", which represents a single character; and additionally allowing you to create a texture or textures full of your glyphs.

http://www.learnopengl.com/#!In-Practice/Text-Rendering

This tutorial takes you through the basics.

\$\endgroup\$
1
  • \$\begingroup\$ He's not using SDL, he's using OpenGL and GLEW \$\endgroup\$
    – Viliami
    Commented Sep 26, 2016 at 3:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .