【问题标题】:SDL2 does not render without a delaySDL2 不会立即渲染
【发布时间】:2016-03-13 23:59:25
【问题描述】:

除非我取消注释 SDL_Delay 行,否则这个简单的 SDL2 程序会在我的系统上打开一个空窗口(即它不呈现任何内容)。

#include <SDL.h>

int main(int argc, char** argv) {

    constexpr unsigned width = 256, height = 256;

    if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
        SDL_Log("Failed to initialize SDL: %s", SDL_GetError());
        return 1;
    }

    SDL_Window* window = SDL_CreateWindow("Test",
                                          SDL_WINDOWPOS_UNDEFINED,
                                          SDL_WINDOWPOS_UNDEFINED,
                                          width, height,
                                          0);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
    SDL_RenderClear(renderer);
    // SDL_Delay(20);
    SDL_RenderPresent(renderer);

    bool quit{};
    SDL_Event event;
    while (!quit) {
        SDL_WaitEvent(&event);

        switch (event.type) {
        case SDL_QUIT:
            quit = true;
            break;
        }
    }

    SDL_Quit();

    return 0;
}

延迟必须在 10-20 毫秒左右,否则什么都不会显示,但这并不一致 - 如果将其设置为 10 毫秒,则大约有一半的时间可以工作。

阅读this answer 后,我添加了事件循环,但没有它我会得到相同的行为。 IRC 上#sdl 上的用户已经通过相同的代码获得了预期的蓝屏。

知道这里发生了什么/我做错了什么吗?

【问题讨论】:

  • 尝试将 clear 和 present 调用放在循环中,看看它是否会重现问题。
  • 无法重现(在 linux 上),但不会对这种行为感到惊讶。在创建窗口后泵送事件,然后在呈现呈现后再次泵送。
  • 玩过抽水事件。 render present 之后的调用无效,但 render clear 之前的调用有效。或者,在 clear 之前对 SetRenderDrawColor 的额外调用使其工作 - 可能包括对泵事件的调用。关键的事情似乎是在 before RenderClear 之前调用它。
  • 不幸的是,它仍然不一致。它在最初的几次工作,但现在我大多得到一个空白窗口(在清除之前和 RenderPresent 之后抽水)
  • 什么操作系统?是否启用了窗口管理器合成?使用什么 SDL 渲染后端 (wiki.libsdl.org/SDL_GetRendererInfo)?和SDL_RENDERER_PRESENTVSYNC一样吗?软件渲染后端是否有相同的结果?从来没有在没有主循环的情况下进行过 SDL 绘图,但很可能每次发生SDL_WINDOWEVENT_EXPOSED 事件时都必须重新绘制。

标签: c++ rendering sdl sdl-2


【解决方案1】:

您应该调用 SDL_PollEvent() 以避免阻塞绘图线程。

尝试以下方法:

while (!quit) {
    SDL_Delay(1000/25);
    SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);
    if(!SDL_PollEvent(&event)) continue;

    switch (event.type) {
    case SDL_QUIT:
        quit = true;
        break;
    }
}

或者,对于键盘和游戏手柄轮询的完整示例,编译并运行 GPL 游戏 Rock Dodger SDL2 Compact Edition,然后查看其源代码(它只是一个小文件)。

【讨论】:

    猜你喜欢
    • 2018-06-27
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多