我使用以下代码初始化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,或者自己等待(准确)?
答案 0 :(得分:0)
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();
}
如果至少 15毫秒已过,则update
的调用只会显示该帧。 15 ms是帧速率为60 FPS所需的时间。
我知道这个问题已经过时了,但我决定将答案发给其他可能需要它的人。
修改强>
如评论中所述,这不会阻止撕裂,因为您没有同步到vblank信号。此代码仅有助于限制帧速率。据我所知,使用软件渲染器时无法防止撕裂(因为你无法检测到vblank信号)。