为什么我不能使用 SDL2 创建 OpenGL ES 3.0 上下文?

Why can't I create an OpenGL ES 3.0 context using SDL2?

我在 Debian 稳定版上使用 SDL2 2.0.2,我正在尝试使用它获取 OpenGL ES 3.0 上下文。这在我请求 OpenGL ES 2.0 上下文时有效,但如果我直接请求 OpenGL ES 3.0 上下文则无效。

考虑以下程序:

#include <GLES3/gl3.h>
#include <SDL2/SDL.h>

int main(
    int argc,
    char **argv
) {
    SDL_GLContext context;
    int rc;
    const GLubyte *version;
    SDL_Window *window;

    rc = SDL_Init(SDL_INIT_VIDEO);

    if (rc < 0) {
        return EXIT_FAILURE;
    }

    atexit(SDL_Quit);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
#ifdef THIS_SHOULD_WORK_TOO
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#else
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif

    window = SDL_CreateWindow("OpenGL", 100, 100, 800, 600, SDL_WINDOW_OPENGL);
    context = SDL_GL_CreateContext(window);
    version = glGetString(GL_VERSION);

    if (version == 0) {
        printf(
            "Unable to get OpenGL ES version string: %d\n",
            glGetError()
        );
        return EXIT_FAILURE;
    }

    printf("Version string: %s\n", version);

    SDL_GL_DeleteContext(context);

    return EXIT_SUCCESS;
}

当我正常编译时,它请求一个 OpenGL ES 2.0 上下文,程序接收一个 OpenGL ES 3.0 上下文:

$ c99 example.c -lSDL2 -lGLESv2
$ ./a.out 
Version string: OpenGL ES 3.0 Mesa 10.3.2

但是,当我请求 OpenGL ES 3.0 上下文时,此程序失败且没有明确的错误消息:

$ c99 -DTHIS_SHOULD_WORK_TOO example.c -lSDL2 -lGLESv2
$ ./a.out
Unable to get OpenGL ES version string: 0

这是为什么?

我怀疑这是因为 -lGLESv2,主要是因为 OpenGL ES 上下文报告它是 3.0 版,并且因为确实发布 libGLESv3.so 的平台将其作为符号链接发布到 libGLESv2.so(例如Android does this)。

这是a bug in SDL2:

SDL's EGL code (used for OpenGL ES context creation on Windows / Linux / Android / etc.) only seems to properly support OpenGL ES 1 and 2 contexts.

In particular, the current code sets the EGL_RENDERABLE_TYPE config attribute to EGL_OPENGL_ES2_BIT if GLES2 is requested and EGL_OPENGL_ES_BIT in all other cases. It never uses EGL_OPENGL_ES3_BIT / EGL_OPENGL_ES3_BIT_KHR even when GLES3.0+ is requested. It also doesn't use EGL_CONTEXT_MINOR_VERSION_KHR to set the version to 3.1 rather than 3.0 in SDL_EGL_CreateContext, when 3.1 is requested.

这意味着对 OpenGL ES 3.0 的请求被转换为对 OpenGL ES 1.0 的请求。由于 OpenGL ES 3.0 向后不兼容 OpenGL ES 1.0,请求最终失败(我认为)。

The fix has been merged into the master branch, and is scheduled to be released as part of SDL2 version 2.0.4:

  • Added EGL_KHR_create_context support to allow OpenGL ES version selection on some platforms