在我实现的2D OpenGL引擎中,我采用了著名的fix your timestep文章所描述的固定时间步长和混合技术。我有一个测试对象在垂直方向(y轴)移动。在移动过程中存在抖动(预编程移动,非用户输入),这意味着物体不能在屏幕上平滑移动。请查看我提供的未压缩视频链接:LINK。游戏帧率保持在60fps(使用Nvidia驱动程序中的Vsync)。游戏逻辑以我设定的每秒20个更新/刻度的固定速度进行更新,这是正常的。对象每次更新移动50像素。然而,在屏幕上的移动却严重抖动。编辑:通过逐帧检查记录的视频,我注意到抖动是由于一帧被显示了两次造成的。编辑2:将应用程序优先级设置为任务管理器中的实时完全消除了抖动!但显然这不是解决方案。
以下是关闭VSync时不同时间的对象y轴移动增量 第一列是自上一帧以来经过的时间,以微秒为单位(例如
现在已经开启了垂直同步(VSync)。
我会说它们看起来还不错。
这已经让我疯狂了好几天,我错过了什么?
以下是我的Frame函数,在循环中被调用:
以下是关闭VSync时不同时间的对象y轴移动增量 第一列是自上一帧以来经过的时间,以微秒为单位(例如
4403
)
第二列是自上一帧以来对象在y轴上的移动。
实际上,对象每秒移动1000像素,下面的日志证实了这一点。time since last frame: 4403 ypos delta since last frame: 4.403015
time since last frame: 3807 ypos delta since last frame: 3.806976
time since last frame: 3716 ypos delta since last frame: 3.716003
time since last frame: 3859 ypos delta since last frame: 3.859009
time since last frame: 4398 ypos delta since last frame: 4.398010
time since last frame: 8961 ypos delta since last frame: 8.960999
time since last frame: 7871 ypos delta since last frame: 7.871002
time since last frame: 3985 ypos delta since last frame: 3.984985
time since last frame: 3684 ypos delta since last frame: 3.684021
现在已经开启了垂直同步(VSync)。
time since last frame: 17629 ypos delta since last frame: 17.628906
time since last frame: 15688 ypos delta since last frame: 15.687988
time since last frame: 16641 ypos delta since last frame: 16.641113
time since last frame: 16657 ypos delta since last frame: 16.656738
time since last frame: 16715 ypos delta since last frame: 16.715332
time since last frame: 16663 ypos delta since last frame: 16.663086
time since last frame: 16666 ypos delta since last frame: 16.665771
time since last frame: 16704 ypos delta since last frame: 16.704102
time since last frame: 16626 ypos delta since last frame: 16.625732
我会说它们看起来还不错。
这已经让我疯狂了好几天,我错过了什么?
以下是我的Frame函数,在循环中被调用:
void Frame()
{
static sf::Time t;
static const double ticksPerSecond = 20;
static uint64_t stepSizeMicro = 1000000 / ticksPerSecond; // microseconds
static sf::Time accumulator = sf::seconds(0);
gElapsedTotal = gClock.getElapsedTime();
sf::Time elapsedSinceLastFrame = gElapsedTotal - gLastFrameTime;
gLastFrameTime = gElapsedTotal;
if (elapsedSinceLastFrame.asMicroseconds() > 250000 )
elapsedSinceLastFrame = sf::microseconds(250000);
accumulator += elapsedSinceLastFrame;
while (accumulator.asMicroseconds() >= stepSizeMicro)
{
Update(stepSizeMicro / 1000000.f);
gGameTime += sf::microseconds(stepSizeMicro);
accumulator -= sf::microseconds(stepSizeMicro);
}
uint64_t blendMicro = accumulator.asMicroseconds() / stepSizeMicro;
float blend = accumulator.asMicroseconds() / (float) stepSizeMicro;
if (rand() % 200 == 0) Trace("blend: %f", blend);
CWorld::GetInstance()->Draw(blend);
}
根据评论请求的更多信息:
卡顿出现在全屏 1920x1080 和窗口模式 1600x900 中
这是一个简单的SFML项目设置。我不知道在渲染纹理矩形时是否在内部使用了VBO/VAO
没有在电脑上做其他事情。请记住,此问题也会在其他计算机上发生,不仅仅是我的电脑
正在主显示器上运行。显示器并不真正起到作用。无论是全屏还是窗口模式都会出现此问题。