I''ve seen so many people''s demos with a FPS counter. Any idea on how I can implement one in my program?
--------------------Help Needed!Turn-based 20th century strategy wargameTitle still to be determined
// very simple really!
// ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
// FUNCTION NAME: ShowFrameRate ()
// FUNCTION DESCRIPTION: Shows frame rate
VOID ShowFrameRate ( int x, int y, COLORREF color)
{
static float fFPS = 0.0f;
static float fLastTime = 0.0f;
static DWORD dwFrames = 0L;
// Keep track of the time lapse and frame count
FLOAT fTime = timeGetTime() * 0.001f;
++dwFrames;
// Update the frame rate once per second
if( fTime - fLastTime > 1.0f )
{
fFPS = dwFrames / (fTime - fLastTime);
fLastTime = fTime;
dwFrames = 0L;
}
// Setup the text buffer to write out dimensions
TCHAR buffer[80];
sprintf( buffer, "Frames per second %7.02f fps ", fFPS );
DDTextOut ( m_pDDBackBuffer, buffer, x,y, color);
} //-------------------------------------------------------------
VOID DDTextOut ( LPDIRECTDRAWSURFACE7 lpdds, char* text, int x,
int y,
COLORREF textcolor )
{
HDC hdc;
HRESULT hRet;
char buffer[256];
hRet = lpdds->GetDC ( &hdc );
sprintf ( buffer, text );
SetBkMode ( hdc, TRANSPARENT );
SetTextColor ( hdc, textcolor );
TextOut ( hdc, x, y, buffer, strlen ( buffer ));
hRet = lpdds->ReleaseDC ( hdc );
}
if ( there''''s a will )
return ( there''''s a way );
Search this forum for FPS, I posted a digitally filtered framerate algo a month or so ago.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
I spent some time recently looking at the best timing method to use for calculating FPS and making my animation/sprite updates last-frame-time-dependent (sorry - I'm sure there's a proper phrase for this, but I don't know what it is!)
I searched Gamedev for 'FPS' and there is a lot of information out there. Unfortunately a lot of it is confusing or contradictory. After reading through it all and consulting MSDN I've got my timing routines working nicely. I'll attempt to explain the different methods used and what I see as the strengths and weaknesses of each, along with my code. I must point out that i'm very new to c++/DirectX/game programming, so if anyone spots a glaring error/bad code please point it out to me. I won't be offended.
The three methods I commonly see used to measure frame rate:
1. GetTickCount()
2. Multimedia Timer ( timeGetTime() )
3. High-Resolution Timer ( QueryPerformanceFrequency()/QueryPerformanceCounter() )
1. GetTickCount() - This function returns a DWORD containg the number of milliseconds since the system was started. It's ok for calculating FPS, but is crap for doing any kind of frame-by-frame timing because it has a very low resolution.
2. Multimedia Timer - I've seen a lot of people using timeGetTime() in place of GetTickCount(). It also returns a DWORD containing the number of milliseconds since the system was started. However, I found that the resolution is just as bad as GetTickCount() unless you change the frequency of the timer, which is something I've never seen mentioned elsewhere. To change the resolution you use:
MMRESULT timeBeginPeriod(UINT uPeriod);
before you start using the timer and then, when you're finished you use:
MMRESULT timeEndPeriod(UINT uPeriod);
I tried timeBeginPeriod(1) to set the resolution of the timer to 1 millisecond and it seemed to work ok. The resolution definitely improved. However, I think it's bad practice to just pass a constant like that. I think you are supposed to check the machine's device caps first (See MSDN for more info) I'm also guessing that the multimedia timers use the High Res timer mentioned next, but I could be wrong about that.
3. High-Resolution Timer - This is the method that I've chosen to use. It requires that the hardware supports a high-resolution performance counter, but it works fine on an old P166 so I don't think you'll have any compatibility problems. The other problem is that you need to use 64-bit integers, but MSVC has built-in support for them and they're easy enough to understand (again, check MSDN for details)
The High-Res timer requires the use of the following two functions:
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
QueryPerformanceFrequency returns the number of counts per second for the system. Get the current count using QueryPerformanceCounter and then divide this result by the Frequency to get the result in seconds.
_______________________________________________________________
I now use the high-res performance counter and everything works very well. Below is my timer class (don't worry if you don't use classes, you can easily adapt the code), along with the code I use to calculate the FPS. This code is actually part of my DirectDraw class. I call it whenever I Flip(), so it's called once per frame. Again, you could easily adapt the code for your own needs:
Phew, this has been one hell of a post. I hope this helps fellow newbies. If anyone out there sees something wrong with my code/approach please let me know.
EDIT: Oops, forgot to mention that if you want to use timeGetTime and the other multimedia timer functions then you'll have to #include <mmsystem.h>. You can just #include <windows.h> if you like, but make sure that you don't have WIN32_LEAN_AND_MEAN defined because otherwise the compiler will skip the mulitmedia stuff when it compiles the windows header.
Moot
Edited by - Moot on December 22, 2000 8:35:20 AM
I searched Gamedev for 'FPS' and there is a lot of information out there. Unfortunately a lot of it is confusing or contradictory. After reading through it all and consulting MSDN I've got my timing routines working nicely. I'll attempt to explain the different methods used and what I see as the strengths and weaknesses of each, along with my code. I must point out that i'm very new to c++/DirectX/game programming, so if anyone spots a glaring error/bad code please point it out to me. I won't be offended.
The three methods I commonly see used to measure frame rate:
1. GetTickCount()
2. Multimedia Timer ( timeGetTime() )
3. High-Resolution Timer ( QueryPerformanceFrequency()/QueryPerformanceCounter() )
1. GetTickCount() - This function returns a DWORD containg the number of milliseconds since the system was started. It's ok for calculating FPS, but is crap for doing any kind of frame-by-frame timing because it has a very low resolution.
2. Multimedia Timer - I've seen a lot of people using timeGetTime() in place of GetTickCount(). It also returns a DWORD containing the number of milliseconds since the system was started. However, I found that the resolution is just as bad as GetTickCount() unless you change the frequency of the timer, which is something I've never seen mentioned elsewhere. To change the resolution you use:
MMRESULT timeBeginPeriod(UINT uPeriod);
before you start using the timer and then, when you're finished you use:
MMRESULT timeEndPeriod(UINT uPeriod);
I tried timeBeginPeriod(1) to set the resolution of the timer to 1 millisecond and it seemed to work ok. The resolution definitely improved. However, I think it's bad practice to just pass a constant like that. I think you are supposed to check the machine's device caps first (See MSDN for more info) I'm also guessing that the multimedia timers use the High Res timer mentioned next, but I could be wrong about that.
3. High-Resolution Timer - This is the method that I've chosen to use. It requires that the hardware supports a high-resolution performance counter, but it works fine on an old P166 so I don't think you'll have any compatibility problems. The other problem is that you need to use 64-bit integers, but MSVC has built-in support for them and they're easy enough to understand (again, check MSDN for details)
The High-Res timer requires the use of the following two functions:
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
QueryPerformanceFrequency returns the number of counts per second for the system. Get the current count using QueryPerformanceCounter and then divide this result by the Frequency to get the result in seconds.
_______________________________________________________________
I now use the high-res performance counter and everything works very well. Below is my timer class (don't worry if you don't use classes, you can easily adapt the code), along with the code I use to calculate the FPS. This code is actually part of my DirectDraw class. I call it whenever I Flip(), so it's called once per frame. Again, you could easily adapt the code for your own needs:
|
Phew, this has been one hell of a post. I hope this helps fellow newbies. If anyone out there sees something wrong with my code/approach please let me know.
EDIT: Oops, forgot to mention that if you want to use timeGetTime and the other multimedia timer functions then you'll have to #include <mmsystem.h>. You can just #include <windows.h> if you like, but make sure that you don't have WIN32_LEAN_AND_MEAN defined because otherwise the compiler will skip the mulitmedia stuff when it compiles the windows header.
Moot
Edited by - Moot on December 22, 2000 8:35:20 AM
Thanks again Myself. You have once again solved my problem. Magmai, thanks but Myself''s code works well enough for me, so I don''t really need anything else.
Moot...wow! That''s a bit too complex for me. Thank you though.
Moot...wow! That''s a bit too complex for me. Thank you though.
--------------------Help Needed!Turn-based 20th century strategy wargameTitle still to be determined
And it was a lot less complicated than Moot's :p
Edited by - Magmai Kai Holmlor on December 24, 2000 1:33:50 AM
Edited by - Magmai Kai Holmlor on December 24, 2000 1:34:27 AM
|
Edited by - Magmai Kai Holmlor on December 24, 2000 1:33:50 AM
Edited by - Magmai Kai Holmlor on December 24, 2000 1:34:27 AM
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement