我一直在玩遊戲循環和物理。有一天,我添加了一些調試語句來查看我的遊戲循環中每幀的時間是多少。如預期的那樣,結果在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