Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Problem with setFramerateLimit()  (Read 4120 times)

0 Members and 1 Guest are viewing this topic.

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Problem with setFramerateLimit()
« on: December 19, 2013, 12:46:08 pm »
Hi!

When I set the window's framerate limit to 60 I get ~35 FPS. When I set the limit to 120 I get ~65 FPS. When I don't define a limit I get over 8000 FPS.

Now, I want my game to run at 60 FPS. I can't really set the framerate limit to 60 though because then for some reason it stays at ~35 FPS.

Can someone please help me? What am I doing wrong?!

Edit: I made a quick example code (untested)

int main() {
  sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Test", sf::Style::Close);
  window.setFramerateLimit(60);

  sf::Font font;
  if (!font.loadFromMemory(fontChar, fontSize)) {
    return -1;
  }

  sf::Clock c;
  sf::Text t = sf::Text("", font, 30);
  t.setColor(sf::Color(0, 0, 0));

  while (window.isOpen()) {
    sf::Event evt;
    while (window.pollEvent(evt)) {
      switch (evt.type) {
      case sf::Event::Closed:
        window.close();
        break;
      default:
        break;
      }
    }

    window.clear(sf::Color(255, 255, 255));

    float fps = 1.f / c.restart().asSeconds();
    std::stringstream ss;
    ss << "FPS: " << (int)fps;
    t.setString(ss.str());

    window.draw(t);
    window.display();
  }

  return 0;
}
« Last Edit: December 19, 2013, 12:57:58 pm by smguyk »

Rhimlock

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: Problem with setFramerateLimit()
« Reply #1 on: December 19, 2013, 01:02:45 pm »
I suppose this is quite inaccurate
float fps = 1.f / c.restart().asSeconds();

You should rather try:
int fps = 1000000 / c.restart().asMicroseconds();


(untested) ;-)

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Re: Problem with setFramerateLimit()
« Reply #2 on: December 19, 2013, 01:08:11 pm »
I suppose this is quite inaccurate
float fps = 1.f / c.restart().asSeconds();

You should rather try:
int fps = 1000000 / c.restart().asMicroseconds();


(untested) ;-)


It yields the same results for me.

Am I calculating the FPS correctly? Maybe that's the issue here but I don't see what's wrong with my code.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Problem with setFramerateLimit()
« Reply #3 on: December 19, 2013, 01:10:55 pm »
What version of SFML are you using? Not too long ago we've had an improvement to the inaccuracy of sf::sleep, which is the cause of the issue here. I think it's already included in SFML 2.1, but I'm not certain - might want to look at the commit history.

Overall the framelimit with sf::sleep will always be a bit inaccurate, so if possible one should use VSync, but since that can be deactivated in the driver, one will still want to use framelimit.
Nexus implemented for Zloxx II an interesting idea, where you measure the frametime in the beginning and if it's not at the desired point, you can move the framelimit up. That way you could start with a fixed 60 limit and if the measured time is too far away from 1/60, you could move the limit up (or down) a bit to get closer to 60fps.

I suppose this is quite inaccurate
float fps = 1.f / c.restart().asSeconds();

You should rather try:
int fps = 1000000 / c.restart().asMicroseconds();
It's not really that inaccurate given that we're dealing with frametimes of 0.008 - 0.01s and don't care too much about the microseconds. And if you want to be accurate than your integer division isn't the best way to go about it either... ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Re: Problem with setFramerateLimit()
« Reply #4 on: December 19, 2013, 01:19:36 pm »
What version of SFML are you using? Not too long ago we've had an improvement to the inaccuracy of sf::sleep, which is the cause of the issue here. I think it's already included in SFML 2.1, but I'm not certain - might want to look at the commit history.

I'm using SFML 2.1.

Overall the framelimit with sf::sleep will always be a bit inaccurate, so if possible one should use VSync, but since that can be deactivated in the driver, one will still want to use framelimit.

I read about sf::sleep being inaccurate but the range was only a few FPS like 55 instead of 60 FPS and not 35 instead of 60. I'd be perfectly fine with +-5 FPS but -25 is too much... it's driving me crazy!
« Last Edit: December 19, 2013, 01:21:40 pm by smguyk »

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: Problem with setFramerateLimit()
« Reply #5 on: December 19, 2013, 01:22:56 pm »
I would just remove setFrameLimit and use setVerticalSyncEnabled, because random sleeps, which are naturally not synchronized to the gpu/monitor, are not a good way of handling this in a game.
If someone chooses to disable vsync in the driver (presumably for benchmarking) then its their choice and not the application programmers. Therefore it should just run as fast as possible, but the application should have logic updates decoupled from the framerate to prevent malfunction.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Problem with setFramerateLimit()
« Reply #6 on: December 19, 2013, 01:30:27 pm »
I read about sf::sleep being inaccurate but the range was only a few FPS like 55 instead of 60 FPS and not 35 instead of 60. I'd be perfectly fine with +-5 FPS but -25 is too much... it's driving me crazy!
I know, it's most likely your hardware/driver not playing nice then... :-[

I would just remove setFrameLimit and use setVerticalSyncEnabled, because random sleeps, which are naturally not synchronized to the gpu/monitor, are not a good way of handling this in a game.
If someone chooses to disable vsync in the driver (presumably for benchmarking) then its their choice and not the application programmers. Therefore it should just run as fast as possible, but the application should have logic updates decoupled from the framerate to prevent malfunction.
While I agree, I don't see a reason for not providing a fallback. :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Problem with setFramerateLimit()
« Reply #7 on: December 19, 2013, 01:30:56 pm »
Cliking on the FAQ link in eXpl0it3r's signature:
https://github.com/SFML/SFML/wiki/FAQ#wiki-window-set-framerate-limit

tl;dr version: Learn to live with it, making your game depend on having a fixed FPS isn't a good idea anyway.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

smguyk

  • Jr. Member
  • **
  • Posts: 79
    • View Profile
Re: Problem with setFramerateLimit()
« Reply #8 on: December 19, 2013, 01:36:20 pm »
Thanks for your replies.

I think I'm going to be using setVerticalSyncEnabled(true) in the future then.

I still kind of want to have a fallback position though, so I was thinking to maybe call setVerticalSyncEnabled, then check if VSync is enabled and if not, set a framerate limit. There's no function for checking if VSync is enabled though, or is there?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Problem with setFramerateLimit()
« Reply #9 on: December 19, 2013, 01:39:29 pm »
There's no function for checking if VSync is enabled though, or is there?
Not with SFML. You could however check the frametime a few times and if it's way too high, then it's not set (bad). ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/