Search code examples
copenglsdlsdl-2

SDL_GL_ExtensionsSupported alway returns SDL_False


According to the SDL2 documentation, you should always ask when you load an OpenGL extension whether the extension is supported. See: https://wiki.libsdl.org/SDL_GL_GetProcAddress

I'm on KUbuntu 16.04, but also want to support other platforms,

Currently I'm always getting a valid pointer to an extension, but SDL_GL_ExtensionSupported always tells that it is not supported.

I use CMake to find the opengl libraries via FindPackage(OpenGL REQUIRED) and then link to them via. target_link_libraries(MyTarget ${OPENGL_gl_LIBRARIES})

If I ask glewinfo:

$glewinfo | grep -i glcompileshader
  glCompileShader:                                             OK
  glCompileShaderARB:                                          OK
  glCompileShaderIncludeARB:                                   OK

I'm Opening a window with:

SDL_Window* window;
SDL_GLContext context;
int flags =  SDL_WINDOW_RESIZABLE|SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN;
window = SDL_CreateWindow("name", x, y, z, flags);
context = SDL_GL_CreateContext(window);

And then I call allocate_glextension_for_context(context); from the fragment below.

// casting function pointers generates pedantic errors
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"

#define LOAD_AND_CHECK_EXTENSION(name)                              \
    ext->name = (ext_##name) SDL_GL_GetProcAddress(#name);          \
    if (ext->name != NULL) {                                        \
        if (SDL_GL_ExtensionSupported(#name) != SDL_TRUE) {         \
            ext->name = NULL;                                       \
            failed_to_load = 1;                                     \
            fprintf(stderr, "failed to load %s\n", #name);          \
        }                                                           \
    }                                                               \


/**
 * \brief This function loads the extensions for a given context.
 *
 * @param [in] The SDL_GLContext that should be active.
 * @param extensions The set of extensions.
 * @return PSY_GL_LOAD_OK if everything is alright.
 */
static int
load_extentions(GLExtensions* ext)
{
    int failed_to_load = 0;

    // Here below we load functions from the opengl library via SDL2
    // via a macro, this is roughly what it does.
    ext->glShaderSource  = SDL_GL_GetProcAddress("glShaderSource");
    if (ext->glShaderSource != NULL) {
        if (SDL_GL_ExtensionSupported("glShaderSource") != SDL_TRUE) {
            ext->glShaderSource = NULL;
            failed_to_load = 1;
        }
    }

    // Is already done here above.
    //LOAD_AND_CHECK_EXTENSION(glShaderSource);
    LOAD_AND_CHECK_EXTENSION(glCompileShader);
    LOAD_AND_CHECK_EXTENSION(glGetShaderiv);
    LOAD_AND_CHECK_EXTENSION(glGetShaderInfoLog);

    if (failed_to_load)
        return PSY_GL_LOAD_EXTENSION_MISSING;
    else
        return PSY_GL_LOAD_OK;
}

//reenable all warnings
#pragma GCC diagnostic pop

int
allocate_glextension_for_context(SDL_GLContext context)
{
    ExtensionPair pair = {
        .context = context,
        .extensions = {0}
    };

    int ret;
    if (context != SDL_GL_GetCurrentContext())
        return PSY_GL_LOAD_CONTEXT_NOT_CURRENT;

    if (g_array) {
        for (size_t i = 0; i < see_dynamic_array_size(g_array); i++) {
            ExtensionPair* pair = see_dynamic_array_get(g_array, i);
            if (pair->context == context)
                return PSY_GL_LOAD_CONTEXT_EXISTS;
        }
    }
    else {
        ret = see_dynamic_array_new(
            &g_array,
            sizeof (ExtensionPair),
            NULL,
            NULL,
            NULL
            );
        if (ret != SEE_SUCCESS)
            return PSY_GL_LOAD_NO_MEMORY;
    }

    ret = load_extentions(&pair.extensions);
    if (see_dynamic_array_add(g_array, &pair) != SEE_SUCCESS)
        return PSY_GL_LOAD_NO_MEMORY;

    return ret;
}

If I run the code I always get and many others:

failed to load glCompileShader

Indictating that SDL_ExtensionSupported("glCompileShader") returns SDL_False...

However, above I showed that glew indicates that these extensions are all supported. What am I doing wrongly?


Solution

  • There's no extension called "glShaderSource".

    GL extension strings generally look something like this: GL_EXT_framebuffer_blit

    glShaderSourceARB was added by ARB_shader_objects but has been a core feature since OpenGL 2.0.

    Unless you're targeting pre-2.0 GL implementations and actually plan on supporting the ARB entry-points I recommend doing a GL version check instead.