gpt4 book ai didi

c++ - SDL_RenderPresent() 不等待 vsync - 如何等待?

转载 作者:太空狗 更新时间:2023-10-29 22:57:03 29 4
gpt4 key购买 nike

我用这段代码初始化 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() 等待 vsync,或者我自己(准确地)等待它?

最佳答案

VSync 是一项硬件功能。启用 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 帧速率所需的时间。

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

编辑

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

关于c++ - SDL_RenderPresent() 不等待 vsync - 如何等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46106543/

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