C++ SFML vsync是否始终打开?
我一直在玩游戏循环和物理。 前几天,我添加了一些调试语句,以查看游戏循环的每一帧占用了多少时间。 正如预期的那样,结果在16ms范围内。 然而,我尝试禁用vsync,这些结果没有改变。 显然,vsync仍在发生。我注释掉了SFML显示调用,果然帧加速了 好吧,那么为什么vsync被卡住了?起初我认为这一定是DSFML(用于D语言的SFML绑定)中的一个bug。我在C++中创建了一个简单的测试用例,它直接使用SFML,性能特征完全相同。p> 我的系统如下: $inxi-SMGC++ SFML vsync是否始终打开?,c++,sfml,mesa,vsync,C++,Sfml,Mesa,Vsync,我一直在玩游戏循环和物理。 前几天,我添加了一些调试语句,以查看游戏循环的每一帧占用了多少时间。 正如预期的那样,结果在16ms范围内。 然而,我尝试禁用vsync,这些结果没有改变。 显然,vsync仍在发生。我注释掉了SFML显示调用,果然帧加速了 好吧,那么为什么vsync被卡住了?起初我认为这一定是DSFML(用于D语言的SFML绑定)中的一个bug。我在C++中创建了一个简单的测试用例,它直接使用SFML,性能特征完全相同。p> 我的系统如下: $inxi-SMG 系统:主机:c7内核
系统:主机:c7内核:3.16.4-1-ARCH x86_64(64位)桌面:i3 4.8发行版:ARCH Linux 机器:系统:谷歌产品:鹦鹉v:1.0
Mobo:N/A型号:N/A Bios:coreboot v:4.0-4744-gac16405-dirty日期:2013年10月23日
图形:卡:英特尔第二代核心处理器系列集成图形控制器
显示服务器:X.Org 1.16.1驱动程序:英特尔分辨率:1366x768@60.02hz
GLX渲染器:Mesa DRI Intel Sandybridge Mobile GLX版本:3.0 Mesa 10.3.1 下面给出了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();
}
}
}
#包括
#包括
#包括“SFML/Graphics.hpp”
int main()
{
自动*窗口=新sf::RenderWindow(sf::VideoMode(640480),“测试”,
sf::Style::Titlebar | sf::Style::Close);
窗口->设置垂直同步已启用(真);
auto firstTime=std::chrono::高分辨率时钟::now();
同时(窗口->等参线()
{
//打印帧定时
{
auto secondTime=std::chrono::高分辨率时钟::现在();
使用dMsecs=std::chrono::duration;
自动运行=dMsecs(第二次-第一次);
第一次=第二次;
std::cout close();
}
}
//渲染
{
窗口->清除();
窗口->显示();
}
}
}
在谷歌上搜索这个问题,结果显示图形驱动程序正在强制开启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);
}
}
}
#包括
#包括
#包括“SDL2/SDL.h”
int main()
{
SDL_Init(SDL_Init_视频);
SDL_Window*Window=SDL_CreateWindow(“测试”,SDL_WINDOWPOS_未定义,SDL_WINDOWPOS_未定义,640,480,显示SDL_Window_);
SDL_Renderer*Renderer=SDL_CreateRenderer(窗口,-1,SDL_Renderer_加速| SDL_Renderer_PRESENTVSYNC);
auto firstTime=std::chrono::高分辨率时钟::now();
自动退出=错误;
而(!退出)
{
//打印帧定时
{
auto secondTime=std::chrono::高分辨率时钟::现在();
使用dMsecs=std::chrono::duration;
自动运行=dMsecs(第二次-第一次);
第一次=第二次;
std::cout这是一个有缺陷的驱动程序。glXSwapIntervalMESA可以工作。为glXSwapIntervalSGI返回的指针是有效的,因此如果不采取与SDL类似的方法,SFML就无法检测到这个问题。虽然理论上SFML中可能存在一些只有在非常特殊的情况下才会发生的缺陷,但这听起来确实更有可能是某种驱动程序问题(或者它实际上是一些奇怪的竞争条件或导致某些bug发生的一些奇怪的库星座)。您是否尝试过分析您的最小示例,以查看在哪里花费/等待的时间最多?