gpt4 book ai didi

c++ - SFML vsync 始终开启?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:52:13 25 4
gpt4 key购买 nike

我一直在研究游戏循环和物理。前几天,我添加了一些调试语句来查看我的游戏循环的每一帧花费了多少时间。正如预期的那样,结果在 16 毫秒范围内。但是,我尝试禁用 vsync,这些结果并没有改变。显然 vsync 仍在发生。我注释掉了 SFML 显示调用,果然帧加快了。

好的,那么为什么 vsync 卡住了?起初我认为这一定是 DSFML(D 语言的 SFML 绑定(bind))中的错误。我用C++创建了一个简单的测试用例,直接使用SFML,性能特征完全一样!

我的系统如下:

$ inxi -SMG
System: Host: c7 Kernel: 3.16.4-1-ARCH x86_64 (64 bit) Desktop: i3 4.8 Distro: Arch Linux Machine: System: Google product: Parrot v: 1.0
Mobo: N/A model: N/A Bios: coreboot v: 4.0-4744-gac16405-dirty date: 10/23/2013
Graphics: Card: Intel 2nd Generation Core Processor Family Integrated Graphics Controller
Display Server: X.Org 1.16.1 driver: intel Resolution: 1366x768@60.02hz
GLX Renderer: Mesa DRI Intel Sandybridge Mobile GLX Version: 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();
}
}
}

谷歌搜索此问题得出的结果表明图形驱动程序正在强制启用垂直同步。但后来我想知道为什么 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 是这个测试用例,并且看到帧时间在 0 毫秒范围内,正如预期的那样!那么 SFML 实现 vsync 的方式在我的系统上是错误的,而 SDL 似乎可以正确处理它。

导致这种不同行为的两个库在实现上有何不同,是否可以解决?我将如何使用 SFML 获得正确的行为?

最佳答案

这是一个有问题的驱动程序。 glXSwapIntervalMESA 有效。为 glXSwapIntervalSGI 返回的指针是有效的,因此如果不采用类似于 SDL 的方法,SFML 无法检测到此问题。

关于c++ - SFML vsync 始终开启?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26437078/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com