SFML community forums

Help => Graphics => Topic started by: Ganado on July 21, 2014, 12:59:30 am

Title: Limiting framerate with mouse-window interactions causing lag
Post by: Ganado on July 21, 2014, 12:59:30 am
I was trying to make an efficient way to drag-and-drop sprites or other objects. I got it to work, but when doing this, I noticed that when my code limited the framerate of the program in order to save processor usage (whether I'm using a fixed timestep or not), it caused updates that relied on mouse click/move and window interaction to lag.

The following code is a slight modification to one of the site's tutorials (https://github.com/SFML/SFML/wiki/Tutorial:-Change-Cursor ) that I used as a minimal way to show the problem I'm having:

I have the framerate-limiting code at the beginning commented out, if you uncomment either the FramerateLimit line or the V-sync line (the latter especially, not at same time, I know), it causes lag. Please, what can I do to prevent this?

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Hidden Cursor");

    ///***Uncommented so that you can see the "lag".***
    //window.setMouseCursorVisible(false); // Hide cursor

    //***UNCOMMENT ONE OF THESE***
    //window.setVerticalSyncEnabled(true);
    //window.setFramerateLimit(60);

    sf::View fixed = window.getView(); // Create a fixed view

    // Load image and create sprite
    sf::Texture texture;
    texture.loadFromFile("cursor.png");
    sf::Sprite sprite(texture);

    while(window.isOpen())
    {
        sf::Event event;
        while(window.pollEvent(event))
        {
            if(event.type == sf::Event::Closed)
            {
                window.close();
            }
        }

        // Set position
        sprite.setPosition(static_cast<sf::Vector2f>(sf::Mouse::getPosition(window)));

        window.clear();
        window.setView(fixed);
        window.draw(sprite);
        window.display();
    }

    return EXIT_SUCCESS;
}

I'm sorry but I am just getting so frustrated at this frame stuff, how do all of you not have problems with stuff like this?
Title: Re: Limiting framerate with mouse-window interactions causing lag
Post by: Strelok on July 21, 2014, 01:56:26 am
You could use http://www.sfml-dev.org/tutorials/2.1/window-events.php#the-mousemoved-event  (http://www.sfml-dev.org/tutorials/2.1/window-events.php#the-mousemoved-event) instead of statically asking for the cursor position.
Also the debug build costs a lot in terms of performance.
Title: Re: Limiting framerate with mouse-window interactions causing lag
Post by: Ganado on July 21, 2014, 02:01:07 am
Like this?
(click to show/hide)
It's virtually the same lag, can't tell a difference, but thanks for the reply.
Edit: It's also not a problem with debug, the performance gain/decreased lag in release optimizations for this is barely noticeable as well.
Title: Re: Limiting framerate with mouse-window interactions causing lag
Post by: Strelok on July 21, 2014, 02:14:25 am
I don't have any knowledge of what SFML internally does, you could run the program with a profiler but the code is of a tutorial, so it must be some specific behaviour that SFML devs have already encountered.
Title: AW: Limiting framerate with mouse-window interactions causing lag
Post by: eXpl0it3r on July 21, 2014, 08:34:51 am
Can you describe what you mean by "lag"?
Title: Re: Limiting framerate with mouse-window interactions causing lag
Post by: Ganado on July 21, 2014, 05:02:57 pm
Input lag, as in, when moving the cursor around while letting it be visible, the "custom cursor" significantly trails behind the actual cursor. I first noticed this when implementing a drag-and-drop feature to one of the programs I was working on, having vsync turn on in the code would make it very annoying for the user.

I'm not just talking about inherent input lag from having a sprite follow the cursor to begin with, if I don't set a cap on the CPU and let my processor go all out, there isn't a noticeable problem.

This can also be seen if I make vsync be on in https://github.com/SFML/SFML/wiki/Tutorial:-Using-View

Does anyone else besides me get the input lag when the vsync line is not commented in the first example code? Setting the framerate limit makes the lag significantly lower, but it's still there and either way doesn't solve the original problem. Or do most of you guys just let even simple applications take up so much processor energy, heating up your computer unnecessarily... I just don't understand.
Title: Re: Limiting framerate with mouse-window interactions causing lag
Post by: Strelok on July 21, 2014, 06:54:49 pm
I tested your code and the input lag is surely noticeable but not that annoying, disabling vsync does indeed reduce the input lag.
Edit: I edited the code a little
#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800,600), "Hidden Cursor");
        sf::Texture texture;
    texture.loadFromFile("cursor.png");
    sf::Sprite sprite(texture);
        sf::Font font;
        font.loadFromFile("font.ttf");
        sf::Text fps;
        fps.setFont(font);
        bool vsync = false;
        bool limit = false;
        sf::Clock clock;

    while(window.isOpen())
    {
        sf::Event event;
                int frames = static_cast<int>(1 / clock.restart().asSeconds());
                fps.setString(std::to_string(frames) + " FPS");
                while (window.pollEvent(event))
                {                      
                        if (event.type == sf::Event::Closed)
                        {
                                window.close();
                        }
                        else if (event.type == sf::Event::MouseMoved)
                        {
                                sprite.setPosition(
                                        sf::Vector2f(
                                        static_cast<float>(event.mouseMove.x),
                                        static_cast<float>(event.mouseMove.y)));
                        }
                        else if (event.type == sf::Event::KeyReleased)
                        {
                                if (event.key.code == sf::Keyboard::F1)
                                {
                                        vsync = !vsync;
                                        window.setVerticalSyncEnabled(vsync);
                                }
                                else if (event.key.code == sf::Keyboard::F2)
                                {
                                        limit = !limit;
                                        window.setFramerateLimit((limit)?60:0);
                                }
                        }
                }
        window.clear();
                window.draw(fps);
        window.draw(sprite);
        window.display();
    }

    return EXIT_SUCCESS;
}