我一直在玩游戏循环和物理。有一天,我添加了一些调试语句来查看我的游戏循环中每帧的时间是多少。如预期的那样,结果在16ms范围内。 但是,我尝试禁用vsync,并且这些结果没有改变。 显然vsync仍然存在。我评论了SFML显示调用,并确信帧速度加快。SFML vsync始终在?
好吧,为什么然后vsync卡在?起初我认为它一定是DSFML(用于D语言的SFML绑定)中的一个错误。我用C++直接使用SFML创建了一个简单的测试用例,性能特点完全相同!
我的系统如下:
$ inxi -SMG
系统:主持人:C7 内核:3.16.4-1-ARCH x86_64的(64位)桌面:I3 4.8发行版:拱Linux 机器:系统:Google产品:Parrot v:1.0
Mobo:N/A型号:不适用Bios:coreboot v:4.0-4744-gac16405-dirty日期:10/23/2013
显卡: 英特尔第二代核心处理器家族集成图形控制器
显示服务器:X.Org 1.16.1驱动程序:英特尔分辨率:[email protected]
GLX渲染:梅萨DRI英特尔的Sandy Bridge移动GLX版本:3.0梅萨10.3.1
的SFML VSYNC测试情况如下,与垂直同步开启:
#include <chrono>
#include <iostream>
#include "SFML/Graphics.hpp"
int main()
{
auto* window = new sf::RenderWindow(sf::VideoMode(640, 480), "test",
sf::Style::Titlebar | sf::Style::Close);
window->setVerticalSyncEnabled(true);
auto firstTime = std::chrono::high_resolution_clock::now();
while(window->isOpen())
{
//print frame timing
{
auto secondTime = std::chrono::high_resolution_clock::now();
using dMsecs = std::chrono::duration<double, std::chrono::milliseconds::period>;
auto elapsed = dMsecs(secondTime - firstTime);
firstTime = secondTime;
std::cout << elapsed.count() << '\n';
}
//event handler
{
sf::Event e;
while(window->pollEvent(e))
{
if(e.type == sf::Event::EventType::Closed)
window->close();
}
}
//render
{
window->clear();
window->display();
}
}
}
谷歌搜索这个问题与结果暗示图形驱动程序迫使sync上出现。 但后来我想知道为什么vsync适用于我系统上的其他程序?
我使用SDL2又写测试用例,此时:
#include <chrono>
#include <iostream>
#include "SDL2/SDL.h"
int main()
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
auto firstTime = std::chrono::high_resolution_clock::now();
auto quit = false;
while(!quit)
{
//print frame timing
{
auto secondTime = std::chrono::high_resolution_clock::now();
using dMsecs = std::chrono::duration<double, std::chrono::milliseconds::period>;
auto elapsed = dMsecs(secondTime - firstTime);
firstTime = secondTime;
std::cout << elapsed.count() << '\n';
}
//event handler
{
SDL_Event e;
while(SDL_PollEvent(&e))
{
if(e.type == SDL_QUIT) quit = true;
}
}
//render
{
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
}
}
现在我禁用垂直同步是本次测试的情况下,看帧时间在0毫秒范围内,符合市场预期! 所以,然后SFML实现vsync的方式在我的系统上很麻烦,而SDL似乎正确地处理它。
导致这种不同行为的两个库之间的实现有什么区别,是否可以解决?我将如何着手使用SFML获得正确的行为?
虽然从理论上讲,SFML中某处可能存在一些只在非常特殊情况下才会发生的bug,但这听起来确实更可能是某种驱动程序问题(或者它确实是一些奇怪的竞争条件或一些奇怪的库星座,错误发生)。 你有没有尝试分析你的最小例子,看看大部分时间花在哪里/等待? – Mario 2014-10-20 06:31:57