具有 SDL2 上下文的 OpenGL 3.1 无法在屏幕上输出任何内容

OpenGL 3.1 with SDL2 context fails to output anything on screen

我正在尝试获取使用 SDL2 的 OpenGL 的简单演示。我使用的是 MacOS Big Sur 11.3.1,我的 SDL 版本是 2.0.16,我尝试的 OpenGL 版本是 3.1。

一开始似乎一切正常,假设 SDL 已成功初始化,SDL window 不为空,OpenGL 上下文也不为空。但是当试图打印出 OpenGL 的供应商名称、渲染器名称和版本名称时,所有的字符串都是空的:

vendor = (null)
renderer = (null)
version = (null)

这也解释了为什么 window 上什么也没有出现。我遵循了很多关于将 SDL2 与 OpenGL 结合使用的教程,但是 none 对我有用。

我是这样编译的:clang -O3 -lSDL2 -lGL gl_sdl.c.

如果有人知道是怎么回事,请告诉我;我很迷茫。我的代码如下。

#include <SDL2/SDL.h>
#include <GL/gl.h>

enum {w = 800, h = 600};

#define FAIL(msg) {fprintf(stderr, "Could not " msg "\n"); return 1;}

// https://www.khronos.org/opengl/wiki/Tutorial1:_Creating_a_Cross_Platform_OpenGL_3.2_Context_in_SDL_(C_/_SDL)
// clang -O3 -lSDL2 -lGL gl_sdl.c && ./a.out

int main(void) {
    if (SDL_Init(SDL_INIT_VIDEO) < 0) FAIL("initialize SDL");

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

    // Turn on double buffering with a 24bit Z buffer. You may need to change this to 16 or 32 for your system
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    SDL_Window* const window = SDL_CreateWindow("gl_sdl", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_OPENGL);
    if (window == NULL) FAIL("create a window");

    SDL_GLContext context = SDL_GL_CreateContext(window);
    if (context == NULL) FAIL("create a context");

    // This makes our buffer swap syncronized with the monitor's vertical refresh
    SDL_GL_SetSwapInterval(1);

    printf("vendor = %s\nrenderer = %s\nversion = %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION));

    SDL_Event event;
    while (1) {
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                SDL_GL_DeleteContext(context);
                SDL_DestroyWindow(window);
                SDL_Quit();
                return 0;
            }
        }

        // Blue
        glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        SDL_GL_SwapWindow(window);
        SDL_Delay(20);
    }
}

MacOS 使用与 Linux 和 Windows 不同的 OpenGL 库标志。使用 -framework OpenGL 而不是 -lGL。例如

clang -O3 gl_sdl.c -lSDL2 -framework OpenGL

附带说明一下,该程序请求 OpenGL 3.1 的上下文,但不使用 OpenGL Loading Library(或手动加载任何函数)。事实上,这恰好不会造成任何问题,只是因为没有使用 OpenGL >1.1 的函数。