Have you tried not enabling vertical sync? Both vertical sync and the timestep you have implemented may interfere with each other by both trying to control the framerate at the same time. On the SFML tutorial page for windows they state:
"Never use both setVerticalSyncEnabled
and setFramerateLimit
at the same time! They would badly mix and make things worse."
As you can see here from the source code for SFML:
void Window::setFramerateLimit(unsigned int limit)
{
if (limit > 0)
m_frameTimeLimit = seconds(1.f / limit);
else
m_frameTimeLimit = Time::Zero;
}
void Window::display()
{
// Display the backbuffer on screen
if (setActive())
m_context->display();
// Limit the framerate if needed
if (m_frameTimeLimit != Time::Zero)
{
sleep(m_frameTimeLimit - m_clock.getElapsedTime());
m_clock.restart();
}
}
SFML's setFramerateLimit
function is implemented in much the same way as your timestep, and thus I don't believe the situation would be any different here.
Upon testing your code on my machine I did see a slight lag on the square, however, disabling vertical sync fixed the issue.
Edit: It turns out this issue is more complex than I originally thought (and I also overlooked the obvious need for vsync if there's tearing). After days of research and messing around with the code, I've learned of a few things that fix the issue:
- Disabling vsync (though of course we already know this)
- Recording the program with Fraps
- Calling
glFinish()
after window.display()
- Creating a window in either fullscreen, or borderless (with sf::Style::None) at the same size as the desktop
- Disabling Windows Aero theme (though of course this only applies to Windows)
All of those except the first will fix it even when vsync is enabled. The main problem here seems to be that vsync doesn't work correctly in windowed mode, apparently it's a limitation due to how the program has to share screen space with other programs that don't necessarily have vsync enabled.
So my suggestion:
- Use
glFinish()
after every display()
call if using windowed mode, although this has a penalty, it halts the CPU and synchronizes it with the GPU and monitor when it could be processing asynchronously and uninterrupted, but if your program isn't particularly CPU intensive then this shouldn't be much of an issue. In SFML you can include "SFML/OpenGL.hpp" to get access to this function. Although if you are using Windows (Vista and 7 I believe, I don't know how 8 or 10 handles things though) then while using an Aero theme vsync is apparently automatically enabled and you may not have tearing to begin with. What operating system are you using?
- Use fullscreen and just accept that there will be stuttering in windowed mode. It may not even be noticeable in an actual game or other graphical application, as opposed to a rigid high contrast square moving continuously back and forth on a blank background. I know that in the game I am working on right now I have the same problem, but I hardly ever noticed it.
- Read up on the issue and see if you can find a true fix. Admittedly using glFinish is somewhat of a kludge, and dealing with stuttering or tearing in windowed mode may not be acceptable. I'm not entirely sure how glFinish manages to eliminate the stutter, and it's usually never recommended to call that function anyway.
Some further reading: