SFML community forums

Help => Window => Topic started by: Nemykal on September 24, 2011, 12:07:08 pm

Title: SetFramerateLimit() not working precisely
Post by: Nemykal on September 24, 2011, 12:07:08 pm
Hi, I want to limit my program to 60fps, but when I call
Code: [Select]
window->SetFramerateLimit(60); it results in an FPS that fluctuates between 62.5 and 67 FPS.

I made a sample test program to demonstrate this:

Code: [Select]
#include <stdint.h>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>


sf::Text* fpstext;
sf::Font* pixelfont;
sf::RenderWindow* window;
sf::Event event;

double gameFPS = 0.0f;
bool PROGRAM_EXIT = false;

void handleEvents()
{
while (window->PollEvent(event))
{
// Close window : exit
if (event.Type == sf::Event::Closed)
{
PROGRAM_EXIT = true;
}
}
}

void init()
{
window = new sf::RenderWindow(sf::VideoMode(1024, 768), "FPS Test", sf::Style::Default | sf::Style::Resize, sf::ContextSettings(32, 8, 0));
window->SetFramerateLimit(60);
window->EnableVerticalSync(false);

sf::Event event = sf::Event();
pixelfont = new sf::Font();
fpstext = new sf::Text("Fps!");
fpstext->SetCharacterSize(16);
fpstext->SetPosition(0, 0);
//fpstext->SetFont(*pixelfont);
fpstext->SetColor(sf::Color::Red);
}

void drawFPS()
{
static sf::String fps;
static char buf[128];
memset(buf, 0, 128);
sprintf(buf, "FPS: %8.4f", gameFPS);
fps = buf;
fpstext->SetString(fps);
window->Draw(*fpstext);
}

int main(int argc, char** argv)
{
init();
while (!PROGRAM_EXIT)
{
handleEvents();
window->Clear();
drawFPS();
window->Display();
gameFPS = 1.f / window->GetFrameTime() * 1000;
}

return 0;
}


For what it's worth, I am using the latest git of SFML 2.0, compiled for VS2010 64 bit. I am also using SFML_STATIC and linking with the static libs.

Any help or advice is appreciated, I just want to know why I can't get a flat 60fps.
Title: SetFramerateLimit() not working precisely
Post by: Laurent on September 24, 2011, 12:22:15 pm
The framerate is limited with sf::Sleep. The precision of sf::Sleep depends on the thread scheduler of the OS, and can be as high as 16 ms. So don't expect your FPS to be exactly 60. If you need precision you definitely need another solution, relying only on the FPS limit is not a good idea.
Title: SetFramerateLimit() not working precisely
Post by: Nemykal on September 24, 2011, 12:40:54 pm
Is there some way to modify sf::Sleep to be more precise? I would think that stuff like QueryPerformanceCounter() should at least give enough precision. 1 / 60 isn't that precise...
Title: SetFramerateLimit() not working precisely
Post by: Hiura on September 24, 2011, 01:13:19 pm
As Laurent said, if you need precision use find another solution. Using Sleep to manage time is NOT a reliable solution even on the most common OSes.

For example, if you want an object to move at a precise velocity use a formula like this one : new_pos = old_pos + speed * elapsed_time.

GetFrameTime can be useful here. http://www.sfml-dev.org/documentation/2.0/classsf_1_1Window.php#a81164bb845cd6ccc6c8ac981bca44ac4
Title: SetFramerateLimit() not working precisely
Post by: Laurent on September 24, 2011, 01:20:09 pm
Quote
Is there some way to modify sf::Sleep to be more precise?

There's no way to tell the OS be more precise, no.

Quote
I would think that stuff like QueryPerformanceCounter() should at least give enough precision.

The problem is in sf::Sleep, not in measuring time.

You want to rely on something that is not reliable. Why do you want the framerate limit to be precise?