SFML community forums
Help => Graphics => Topic started by: efeX on September 12, 2009, 11:18:26 pm
-
I noticed when i use SetFramerateLimit(60) the FPS actually seems to be 30-32... When i use SetFramerateLimit(30) the FPS is 20-21. When I use SetFramerateLimit(90) the FPS is 60-62....
Am I using it wrong or is the parameter the FPS you want to limit it to?
Code...
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::RenderWindow Window(sf::VideoMode(800, 600, 32), "Test");
Window.SetFramerateLimit(60);
while (Window.IsOpened())
{
sf::Event Event;
while (Window.GetEvent(Event))
{
if (Event.Type == sf::Event::Closed)
Window.Close();
}
Window.Clear();
std::cout << 1 / Window.GetFrameTime() << std::endl;
Window.Display();
}
}
[/code]
-
You're not printing the right thing :
std::cout << 1 / Window.GetFrameTime() << std::endl;
doesn't print FPS because there are some Sleep call inside Display so you're not measuring the right among of time. ( Sorry if you don't understand what I'm saying. I don't find my words. )
-
doesn't print FPS because there are some Sleep call inside Display so you're not measuring the right among of time
GetFrameTime takes this in account. Otherwise it would be completely useless ;)
I noticed when i use SetFramerateLimit(60) the FPS actually seems to be 30-32...
Do you have vertical synchronization enabled (in your display driver settings)?
-
I would also guess this has to do with VSync.
However, you should write 1.0 instead of 1 ;)
-
However, you should write 1.0 instead of 1 ;)
Here it doesn't change anything : Window.GetFrameTime()'s type is float.
But it's cleaner yeah.
you can also write 1.f .
Laurent, 8 hours later I agree. :P
-
doesn't print FPS because there are some Sleep call inside Display so you're not measuring the right among of time
GetFrameTime takes this in account. Otherwise it would be completely useless ;)
I noticed when i use SetFramerateLimit(60) the FPS actually seems to be 30-32...
Do you have vertical synchronization enabled (in your display driver settings)?
It's set to "Let the application decide"
-
Which version of SFML do you use?
-
1.5... tempted to just get the svn and build
-
I think that it wouldn't solve your problem :(
-
Yes, I got this problem too. I am using SFML 1.5 on WinXP SP3....some ATI GFX card, latest drivers.
I worked around this using my own timing functions but since other people have that problem too, maybe we can find out what the problem with it is?
-
I worked around this using my own timing functions
Does it work? Can you show it?
-
All I do is looping until a specific time has passed...
I dont use the SFML functions so I guess it wont help you in any way. It's just something like:
...
while (main_game_loop) {
framestart = getMilliSecSinceMidnight();
PrepareAllSprites();
DoDisplay();
while (getMilliSecSinceMidnight()-framestart < 25) { // use at least 25 msec per Frame since I want 40 Frames Per Sec.
LetWindowsHandleEvents(); // I am using windows....
}
}
...
So it's actually just a delay added to the loop. Well the original code is way better done but still nothing really super clever. Just a little work around...
If you still want to see the original code I can post it this evening. currently I am at work so I can access it =(
-
Ok I see, thanks.
But what's the point of this code? There's nothing to make the main thread sleep, so your CPU will just be busy looping instead of being busy rendering more frames.
-
Oh I just checked your sources and found out you are doing some timing with QPC.... I didnt check if you get the frame time with QPC too, but if so, this might be the problem.
QPC is known to be buggy in many ways:
- If you have more then one CPU core the frequency might change depending on the core your thread is running on.
- The frequency can be dynamic if you are running this on a CPU that changes it's speed (for energy saving purposes, e.g Laptops and some low energy using desktop CPUs)
- some CPUs have dynamic clock skip feature used for thermal throttling
- If you are using it in virutalized environment, e.g. VMWare, Xen, VirtualBox etc you will get most likely not get real values.
...
Well, therefore most programmes do this:
check if the frequency from QPC is "stable" over time and if it fits to the values returned from getTickCount. If not, consider it as bugged and use getTickCount or timeGetTime().
Another way would be a nice callback timer....this one calls a function to increase a counter....:
// Some variables to put somewhere:
MMRESULT timer_id = 0;
TIMECAPS timer_caps;
unsigned int volatile GlobalInternalTimerValue = 0;
// Timer init:
if( timeGetDevCaps(&timer_caps,sizeof(TIMECAPS)) != TIMERR_NOERROR)
return Error("Unable to retrieve timing capabilities");
if( timeBeginPeriod(timer_caps.wPeriodMin) != TIMERR_NOERROR )
return Error("Unable to set timer resolution" );
timer_id = timeSetEvent(1,timer_caps.wPeriodMin,timer_func,0,TIME_PERIODIC);
if( timer_id == 0 )
return Error("Unable to create timer");
// Timer callback:
void CALLBACK timer_func(unsigned int,unsigned int,DWORD,DWORD,DWORD)
{
GlobalInternalTimerValue++;
}
// Timer release:
unsigned int hr = timeEndPeriod( timer_caps.wPeriodMin );
// make sure hr == TIMERR_NOERROR
hr = timeKillEvent( timer_id );
// make sure hr == TIMERR_NOERROR
-
But what's the point of this code? There's nothing to make the main thread sleep, so your CPU will just be busy looping instead of being busy rendering more frames.
Well, the problem was that Windows was using 100% CPU to just draw frames. So the LetWindowsHangleEvents() thing lets windows clear the message stack....as I said, just a quick work around. The main problem is the QPC I guess.... (see above ;))
-
You're right, QPC is not known to be very stable, I should have checked that first.
It would be great if someone having this problem could comment the contents of the Platform::GetSystemTime function in src\SFML\System\Win32\Platform.cpp, just keeping this line
return GetTickCount() * 0.001;
(I know it's not timeGetTime, but this will be enough for tests)
Then recompile SFML and test again :)
-
I will do it this weekend (if not someone already did that then....=))
-
Any news?