我一直在创建/移植我在C#中制作的游戏到C ++,当我开始每秒查看我的帧时,我注意到了一些奇怪的事情。
我最初用C#编写游戏,帧速率始终非常一致。当我打开VSync时,我会得到一个稳定的60fps,而且没有,大约在600-700左右。它总是一个静态的数字。现在,在c ++环境中,我注意到帧速率下降了很多,看起来非常不稳定/不一致(非常确定这与我的实现有关)。
我打算设置一个日志,让应用程序在捕获帧数时运行,然而,这会导致帧速率下降,因此我决定不通过该路径向您展示。相反,我只会说当应用程序启动时,帧速率显示为0大约20ms,然后跳跃到大约2500fps。然后应用程序将跳转到+500或-500左右,有时甚至会有效地加倍到接近4000fps的位置。 使用OpenTK时,帧速率在首次启动时始终显示为60fps(启用了Vsync),并且没有在几毫秒内显示0fps的问题。
我很确定帧速率正在下降,增加,下降,增加等等。对我来说,当它达到最大值时,它看起来像一个变量。
我也应该提一下我没有使用OpenGL库。我想从头开始编写所有内容,我一直在做得非常成功。我只是不知道为什么帧速率如此不一致。
这是初始化所有内容并计算帧速率本身的主类。希望有人可以帮我发现我做错的事情。我提前道歉,因为该课程大约有220行代码。
我只渲染一个三角形,这是通过立即模式完成的。
以下是三张快速图片,以进一步展示我所说的内容: 这个持续约20-30ms,然后超过2000fps。
这个显示了一个突然的低峰值(我实际上什么都不做,只是渲染一个三角形!)
再次高峰,只渲染1个三角形。没有别的事情发生了!
这些图片只是一个简单的例子,有时甚至更糟或更好。
收到帮助后的最终想法: 这个问题是由我在visual studio中的实现和调试引起的。我创建了一个发布版本,关闭了所有内容,并运行了可执行文件。帧的偏差仅为+ -50左右;它在2700-2800fps附近健康地挂起。所以,经验教训:在Visual Studio中调试并不是所见即所得。
答案 0 :(得分:2)
timeGetTime()
是衡量时间的极其错误的方法。所以我怀疑你首先有准确的FPS值。使用boost::chrono
(请注意,std::chrono
目前在Visual Studio 2013实施中并未提供良好的准确性)或原生QueryPerformanceCounter
。
另一件事,即实际的FPS跳跃问题,是你的主要循环:
while (isGameRunning)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
draw();
}
}
如果您没有要继续使用Win32消息(PeekMessage()
返回false
时),则只绘制。因此,对于任何消息,您都会丢失帧。
你应该这样做:
while (isGameRunning)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD)) // add PM_NOYIELD
{
// Move it to `WndProc`.
// Break loop by setting `isGameRunning` to `false`
//if (msg.message == WM_QUIT)
//{
// break;
//}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Draw unconditionnaly
draw();
}
HTH。