我一直在玩游戏循环和物理。
前几天,我添加了一些调试语句,以查看游戏循环的每一帧花费了多少时间。
如预期的那样,结果在16ms范围内。
但是,我尝试禁用vsync,并且这些结果没有改变。
显然,vsync仍在发生。我注释掉了SFML显示调用,并确保足够的帧加速了。
好吧,那为什么还要继续使用vsync?起初,我认为这一定是DSFML(D语言的SFML绑定(bind))中的错误。我用C++创建了一个简单的测试用例,它直接使用SFML,并且性能特征完全相同!
我的系统如下:
SFML vsync测试用例在下面给出,其中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();
}
}
}
谷歌搜索此问题,结果表明图形驱动程序正在强制启用vsync。
但是后来我想知道为什么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);
}
}
}
现在我禁用了vsync这个测试案例,并看到了预期的0ms范围内的帧时间!
因此,SFML实现vsync的方式在我的系统上是有问题的,而SDL似乎可以正确处理它。
导致这种不同行为的两个库之间在实现上有什么区别,可以解决吗?如何使用SFML获得正确的行为?
最佳答案
这是一辆 buggy 司机。 glXSwapIntervalMESA起作用。为glXSwapIntervalSGI返回的指针是有效的,因此SFML如果不采取与SDL类似的方法就无法检测到此问题。
关于c++ - SFML vsync始终打开?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26437078/