#include <stdio.h>
class FramePerSecond
{
public:
FramePerSecond();
~FramePerSecond();
void calculateFPS();
char* getFPS();
private:
int m_iFps;
char m_cFpsStr[55];
float m_fTime;
float m_fLastTime;
};
FramePerSecond::FramePerSecond()
{
m_iFps = 0;
m_cFpsStr[55] = 0;
m_fTime = 0.0f;
m_fLastTime = 0.0f;
}
FramePerSecond::~FramePerSecond()
{
}
void FramePerSecond::calculateFPS()
{
m_fTime = GetTickCount() * 0.001f;
if(m_fTime - m_fLastTime > 1.0f)
{
m_fLastTime = m_fTime;
sprintf_s(m_cFpsStr, "FPS: %d", m_iFps);
m_iFps = 0;
}
else
m_iFps++;
}
char* FramePerSecond::getFPS()
{
return m_cFpsStr;
}
How accurate is my FPS class?
I just put together this class that calculates the fps and I was wondering how accurate is it exactly if you can tell by this code. Any suggestions would be appreciated.
Well, the accuracy is going to be determined by your clock source, so in this case GetTickCount. You can learn about its resolution by checking MSDN.
You're using it to determine when a full second is elapsed, so its resolution is sufficient. If you wanted more, there is QueryPerformanceCounter, along with its wonderful caveats.
There are also other methods apart from counting frames over a one second period if you wanted to explore them. You can maintain a sliding window of frame times and average them over a range of seconds.
General implementation things:
Why are you converting the count returned by GetTickCount from ms to s? If you use ms directly, there's no need for floating-point values.
If a full second has elapsed, calculateFPS doesn't increment the frame counter before formatting the frame count to the FPS text and resetting it - you're missing a frame here. You should just always increment the frame count when entered calculateFPS regardless of how much time has elapsed.
Why are you storing m_fTime as a member variable?
General C++ things:
Bigger picture:
Consider using a different performance metric than FPS altogether. Using frame times directly provides a better metric when comparing how performance has changed due to code changes, etc. See here. Also see this post by frob for how minimum and maximum values for frame times can help provide a clearer picture into what's going on.
You're using it to determine when a full second is elapsed, so its resolution is sufficient. If you wanted more, there is QueryPerformanceCounter, along with its wonderful caveats.
There are also other methods apart from counting frames over a one second period if you wanted to explore them. You can maintain a sliding window of frame times and average them over a range of seconds.
General implementation things:
Why are you converting the count returned by GetTickCount from ms to s? If you use ms directly, there's no need for floating-point values.
If a full second has elapsed, calculateFPS doesn't increment the frame counter before formatting the frame count to the FPS text and resetting it - you're missing a frame here. You should just always increment the frame count when entered calculateFPS regardless of how much time has elapsed.
Why are you storing m_fTime as a member variable?
General C++ things:
- No need to define or implement a deconstructor, the compiler's version will be fine.
- Use initialization lists in your constructor.
- You are going out of bounds when you do m_cFpsStr[55] = 0 in your constructor. You should be using 54, or even better, 0, or even betterer, std::strings, see below.
- Don't use C-style strings. Use std::string and std::ostringstream.
- Better yet, don't mix the string formatting in with the FPS counter. They are seperate tasks. If you need to convert the FPS to a string for rendering, that is something else's problem, not the FPS counter object's. Instead, return the FPS as an integer directly.
- GetTickCount returns a DWORD, so use that for your tick count variables.
class FramesPerSecond{public: FramesPerSecond(); void frameDone(); int getFPS() { return m_fps; }private: int m_fps, m_frameCount; DWORD m_lastTime;};FramePerSecond::FramePerSecond(): m_fps(0), m_frameCount(0), m_lastTime(0){}void FramePerSecond::frameDone(){ ++m_frameCount; DWORD now = GetTickCount(); if(now - m_lastTime >= 1000) { m_lastTime = now; m_fps = m_frameCount; m_frameCount = 0; }}
Bigger picture:
Consider using a different performance metric than FPS altogether. Using frame times directly provides a better metric when comparing how performance has changed due to code changes, etc. See here. Also see this post by frob for how minimum and maximum values for frame times can help provide a clearer picture into what's going on.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement