【问题标题】:SDL_RenderPresent() not waiting for vsync - how to wait?SDL_RenderPresent() 不等待 vsync - 如何等待?
【发布时间】:2017-09-07 23:35:50
【问题描述】:

我使用以下代码初始化 SDL:

SDL_Init(SDL_INIT_VIDEO);

SDL_Window* win = SDL_CreateWindow(
    "SDL Window",
    SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,
    WIDTH,
    HEIGHT,
    SDL_WINDOW_SHOWN
);

SDL_Renderer* ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE);
SDL_GL_SetSwapInterval(1); // probably has no effect since it's not using GL

然后我使用非 SDL 软件渲染器进行渲染,并使用以下代码将其呈现给窗口:

SDL_UpdateTexture(screenBuffer, NULL, screenData, WIDTH*4);

SDL_RenderClear(ren);
SDL_RenderCopy(ren, screenBuffer, NULL, NULL);
SDL_RenderPresent(ren);

帧率完全没有上限,我不知道为什么。

| SDL_RENDERER_PRESENTVSYNC 添加到 SDL_CreateRenderer 标志只会使窗口变成一个空白屏幕。虽然我需要使用 SDL_RENDERER_SOFTWARE 标志(即使我没有使用 SDL 的软件渲染器来呈现屏幕),否则 SDL_RenderPresent() 会停止很长时间,导致每秒大约 1 帧.

如何让SDL_RenderPresent() 等待垂直同步,或者自己(准确地)等待?

【问题讨论】:

  • SDL 的 UpdateWindowSurface 似乎没有 vsync 支持(我想这在某些平台上可能非常困难,而在其他平台上则不太可能),因此 SDL 软件渲染器也没有。不过,Vsync 在 3d API 上非常强大,因此解决您的减速问题可能会更简单。
  • 我不希望依赖 GPU API 浪费二进制空间并降低兼容性。
  • @genpfault 是的,感谢您的关注。我会重新发表评论。
  • 改用SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1");SDL_GL_SetSwapInterval 似乎仅适用于 GL 上下文。

标签: c++ windows-10 sdl-2 vsync


【解决方案1】:

垂直同步是一项硬件功能。启用 VSync 后,视频卡会停止渲染器呈现帧,直到来自监视器的指示垂直同步的信号到达(这意味着它完成了最后一帧的显示)。

如果您使用的是软件渲染器,则无法检测到此信号,因为您没有使用视频卡进行渲染。您可以设置帧速率并等待下一帧。

每秒 60 帧的示例:

#define TICKS_FOR_NEXT_FRAME (1000 / 60)

int lastTime = 0;

void update() {
    while (lastTime - SDL_GetTicks() < TICKS_FOR_NEXT_FRAME) {
        SDL_Delay(1);
    }

    ... // SDL_RenderCopy...

    SDL_RenderPresent(renderer);
    lastTime = SDL_GetTicks();
}

update 的调用仅在至少 15 毫秒后才会显示帧。 15 毫秒是 60 FPS 帧率所需的时间。

我知道这个问题很老了,但我决定将答案发布给其他可能需要它的人。

编辑

正如 cmets 中所述,这不会防止撕裂,因为您没有同步到 vblank 信号。此代码仅有助于限制帧速率。据我所知,使用软件渲染器时无法防止撕裂(因为您无法检测到 vblank 信号)。

【讨论】:

  • vsync 与帧速率无关。您的代码不会阻止撕裂。帧限制和同步到 vblank 信号是两件完全不同的事情。
  • 这是真的。它不会阻止撕裂,它只会将帧速率限制为 60FPS。
猜你喜欢
  • 1970-01-01
  • 2019-12-15
  • 2018-12-09
  • 1970-01-01
  • 2015-07-28
  • 2018-05-04
  • 2020-05-09
  • 2021-09-15
  • 1970-01-01
相关资源
最近更新 更多