3

I am trying to get a simple demo of OpenGL working with SDL2. I am using MacOS Big Sur 11.3.1, my SDL version is 2.0.16, and my attempted OpenGL version is 3.1.

Everything seems to work fine at first, given that SDL is initialized successfully, the SDL window is not null, and the OpenGL context is not null either. But when trying to print out the vendor name, renderer name, and version name of OpenGL, all of the strings are null:

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

This also explains why nothing appears on the window. I have followed plenty of tutorials that go over using SDL2 with OpenGL, but none of them have worked for me.

I am compiling like this: clang -O3 -lSDL2 -lGL gl_sdl.c.

If anyone knows what is going on, please let me know; I am very confused. My code is below.

#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);
    }
}
Yun
  • 3,056
  • 6
  • 9
  • 28
Caspian Ahlberg
  • 934
  • 10
  • 19
  • I cannot reproduce this. Are you sure the OpenGL library and appropriate drivers are installed correctly? Does changing the order of the arguments help, e.g.: `clang -O3 gl_sdl.c -lSDL2 -lGL`? – Yun Sep 09 '21 at 09:14
  • Do the `SDL_GL_SetAttribute` calls return 0? ([ref](https://wiki.libsdl.org/SDL_GL_SetAttribute)) There is a mismatch between requesting OpenGL 3.1, yet not using an OpenGL Loading Library, but the given code should still work, as no OpenGL >1.1 functions are called. – Yun Sep 09 '21 at 09:30
  • @Yun Yes, I think that OpenGL is installed correctly, given that I have a Hello Triangle demo up and running with GLFW and OpenGL. I also checked that SDL_GL_SetAttribute was returning 0 in each call, and it was. – Caspian Ahlberg Sep 09 '21 at 12:36
  • Does it work if you set it to create an OpenGL 1.0 (or 1.1) context? Does adding and initializing an OpenGL loading library make it work? – Yun Sep 09 '21 at 13:22
  • @Yun I tried setting the version to 1.0 and 1.1 via SDL_GL_CONTEXT_MAJOR_VERSION and SDL_GL_CONTEXT_MINOR_VERSION, but nothing changed in the end. Also, what is an OpenGL loading library? Should I be using one along with SDL2? – Caspian Ahlberg Sep 09 '21 at 13:30
  • See [here](https://www.khronos.org/opengl/wiki/OpenGL_Loading_Library). Only needed if you're using functions from OpenGL >1.1. I thought this was the case with `glGetString` at first, but it wasn't (pointed out by derhass), so I deleted my answer. Perhaps it's worth a try to see if it changes anything. You'll need it sooner or later anyway. – Yun Sep 09 '21 at 13:40
  • I tried using glew as an extension handler. This is my snippet that I used after SDL_GL_CreateContext: `glewExperimental = GL_TRUE; GLenum maybe_error = glewInit(); if (maybe_error != GLEW_OK) puts("Bad!!"); else puts("Glew was set up correctly");` No error appeared, oddly enough. – Caspian Ahlberg Sep 09 '21 at 13:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236942/discussion-between-yun-and-caspian-ahlberg). – Yun Sep 09 '21 at 13:42
  • First of all, OSX **does not support OpenGL 3.1**. OSX support up to GL 2.0 as a legacy context, or GL 3.2 to 4.1 in _core profile_ only. – derhass Sep 09 '21 at 17:11

1 Answers1

2

MacOS uses a different library flag for OpenGL than Linux and Windows. Instead of -lGL, use -framework OpenGL. E.g.

clang -O3 gl_sdl.c -lSDL2 -framework OpenGL

On a side note, the program requests a context for OpenGL 3.1, but does not use an OpenGL Loading Library (or loads any functions manually). As is, this happens to cause no problems, only because no functions from OpenGL >1.1 are used.

Yun
  • 3,056
  • 6
  • 9
  • 28