SDL2 窗口无法显示(MacOS + VSCode)

654 阅读2分钟

SDL2 Hello World 窗口,代码如下:

#include <SDL2/SDL.h>

const int SCREEN_WIDTH = 1080;
const int SCREEN_HEIGHT = 720;

int main(int argc, char *argv[]){
    SDL_Window *window = NULL;
    SDL_Surface *windowSurface = nullptr;
    //初始化SDL
    if(SDL_Init(SDL_INIT_VIDEO) < 0){
        SDL_Log("Video Initialization Fail! SDL_Error:%s\n",SDL_GetError());
     }
    SDL_Log("Hello SDL world!\n");
    window = SDL_CreateWindow("SDL2 Hello World", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    if(window == NULL){
        SDL_Log("Failed to create window! SDL_ERROR:%s\n",SDL_GetError());
        SDL_Quit();
        return 0;
    }
    SDL_Log("Create SDL Hello World Window success!\n");
    /* 获取window窗口一个面板 */
    windowSurface = SDL_GetWindowSurface(window);
    /* 窗口面板填充白色 */
    SDL_FillRect(windowSurface, NULL, SDL_MapRGB(windowSurface->format, 0xFF, 0xFF, 0xFF));
    SDL_UpdateWindowSurface(window);

    SDL_FreeSurface(windowSurface);
    SDL_DestroyWindow(window);
    windowSurface = nullptr;
    window = nullptr;
    SDL_Quit();
    return 0;
}

兴致重重的运行,发现没有显示窗口,什么问题问题呢? Debug运行发现“程序坞”窗口一闪而是,说明窗口创建了,只是一闪而过... ... 网上搜索说加入delay延时,尝试修改如下:

// 在SDL_UpdateWindowSurface(window) 后加入延时10秒
SDL_Delay(10000);

运行结果:在”程序坞“中显示图标快捷窗口,但是点击无反应,主屏幕上没有窗口; 什么原因呢?查看SDL_Delay源码:

void
SDL_Delay(Uint32 ms)
{
    int was_error;

#if HAVE_NANOSLEEP
    struct timespec elapsed, tv;
#else
    struct timeval tv;
    Uint64 then, now, elapsed;
#endif

#ifdef __EMSCRIPTEN__
    if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) {
        /* pseudo-synchronous pause, used directly or through e.g. SDL_WaitEvent */
        emscripten_sleep(ms);
        return;
    }
#endif

    /* Set the timeout interval */
#if HAVE_NANOSLEEP
    elapsed.tv_sec = ms / 1000;
    elapsed.tv_nsec = (ms % 1000) * 1000000;
#else
    then = SDL_GetTicks64();
#endif
    do {
        errno = 0;

#if HAVE_NANOSLEEP
        tv.tv_sec = elapsed.tv_sec;
        tv.tv_nsec = elapsed.tv_nsec;
        was_error = nanosleep(&tv, &elapsed);
#else
        /* Calculate the time interval left (in case of interrupt) */
        now = SDL_GetTicks64();
        elapsed = (now - then);
        then = now;
        if (elapsed >= ((Uint64)ms)) {
            break;
        }
        ms -= (Uint32)elapsed;
        tv.tv_sec = ms / 1000;
        tv.tv_usec = (ms % 1000) * 1000;

        was_error = select(0, NULL, NULL, NULL, &tv);
#endif /* HAVE_NANOSLEEP */
    } while (was_error && (errno == EINTR));
}

#endif /* SDL_TIMER_UNIX */

调试发现:

image.png 只是程序运行延时了10s时间后关闭,所以“程序坞”中图标显示了10s; 但是桌面窗口还是一闪而过,若何让桌面窗口不关闭,给窗口加入事件,一直显示,直到触发关闭事件,所以修改代码如下:

#include <SDL2/SDL.h>

const int SCREEN_WIDTH = 1080;
const int SCREEN_HEIGHT = 720;

int main(int argc, char *argv[]){
    SDL_Window *window = NULL;
    SDL_Surface *windowSurface = nullptr;
    SDL_Event event;
    bool quit = true;
    //初始化SDL
    if(SDL_Init(SDL_INIT_VIDEO) < 0){
        SDL_Log("Video Initialization Fail! SDL_Error:%s\n",SDL_GetError());
     }
    SDL_Log("Hello SDL world!\n");
    window = SDL_CreateWindow("SDL2 Hello World", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    if(window == NULL){
        SDL_Log("Failed to create window! SDL_ERROR:%s\n",SDL_GetError());
        SDL_Quit();
        return 0;
    }
    SDL_Log("Create SDL Hello World Window success!\n");
    /* 获取window窗口一个面板 */
    windowSurface = SDL_GetWindowSurface(window);
    /* 窗口面板填充白色 */
    SDL_FillRect(windowSurface, NULL, SDL_MapRGB(windowSurface->format, 0xFF, 0xFF, 0xFF));
    SDL_UpdateWindowSurface(window);
    do{
        //增加窗口事件,知道SDL_QUIT事件退出窗口
        SDL_WaitEvent(&event);
        //SDL_PollEvent(&event);
        switch (event.type){
        case SDL_QUIT:
            quit = false;
            break;
        default:
            SDL_Log("Event type is %d\n",event.type);
        }
    }while(quit);
    SDL_FreeSurface(windowSurface);
    SDL_DestroyWindow(window);
    windowSurface = nullptr;
    window = nullptr;
    SDL_Quit();
    return 0;
}

再次调试运行:窗口注册了事件,窗口一直显示,知道点击触发关闭事件(SDL_QUIT).

image.png

运行结果:

image.png