我有一个简短的问题。我正在学习SFML,我使用它制作了一些应用程序。有一天,我学会了在编写游戏时使用固定时间步骤,如果有效的话会很棒。但。即使我正在制作简单的项目,如从窗口左侧移动到右侧的方形 - 它是滞后的!可能是造成这个问题的原因是什么?这是我的代码:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "Window");
window.setVerticalSyncEnabled(true);
sf::Event event;
sf::Clock clock;
sf::Time accumulator = sf::Time::Zero;
const sf::Time timePerFrame = sf::seconds(1.f / 60.f);
sf::RectangleShape square;
square.setSize(sf::Vector2f(32, 32));
square.setOrigin(16, 16);
square.setPosition(400, 300);
square.setFillColor(sf::Color::Red);
int direction = 1;
int speed = 300;
while(window.isOpen())
{
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
{
window.close();
}
}
while(accumulator >= timePerFrame)
{
if(square.getPosition().x <= 16 || square.getPosition().x >= 784) direction *= (-1);
square.move(sf::Vector2f(speed * direction * timePerFrame.asSeconds(), 0));
accumulator -= timePerFrame;
}
accumulator += clock.restart();
window.clear(sf::Color::Black);
window.draw(square);
window.display();
}
return 0;
}
正如您所看到的,我知道垂直同步,但它并没有多大帮助。我的固定时间步循环错了吗?任何帮助表示赞赏!
答案 0 :(得分:1)
您是否尝试过不启用垂直同步?垂直同步和您实现的时间步长都可能会同时干扰,同时尝试控制帧速率。在SFML tutorial page for windows上,他们声明:
&#34;永远不要同时使用setVerticalSyncEnabled
和setFramerateLimit
!他们会严重混合并使事情变得更糟。&#34;
正如您可以从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的setFramerateLimit
功能与您的时间步长大致相同,因此我不相信这里的情况会有所不同。
在我的机器上测试你的代码后,我确实看到了方块上的轻微延迟,但是,禁用垂直同步解决了这个问题。
编辑:事实证明这个问题比我原先想象的要复杂得多(而且我也忽略了如果出现撕裂,显然需要vsync)。经过几天的研究和乱码,我已经了解了一些解决问题的方法:
glFinish()
window.display()
除了第一个之外的所有内容都会修复它,即使启用了vsync也是如此。这里的主要问题似乎是vsync在窗口模式下无法正常工作,显然它是一个限制因为程序必须与其他不必启用vsync的程序共享屏幕空间。
所以我的建议是:
glFinish()
调用后使用display()
,虽然这会受到惩罚,但它会暂停CPU并将其与GPU同步并监视它何时可以异步和不间断地处理,但是如果你的程序不是特别密集CPU,那么这不应该是一个大问题。在SFML中,您可以包含&#34; SFML / OpenGL.hpp&#34;访问此功能。虽然如果你使用Windows(我认为Vista和7,我不知道8或10如何处理事情),那么使用Aero主题vsync时显然会自动启用,你可能没有开始尝试。你在使用什么操作系统?进一步阅读: