Search code examples
c++macosopenglopengl-3sdl-2

Segmentation fault when trying to wrap glGenVertexArrays call in a method


I'm trying to use "modern" OpenGL (3+) with SDL 2.0.3 and C++ on Mac OS and it works if I call the OpenGL functions directly, but as soon as I try to wrap it in a class it does not work. More specifically I wanted to store a Vertex Array Object as a class member and call glGenVertexArrays in a class method on it, but this results in a segfault.

Minimal working example with direct call (does nothing useful but does not crash):

#include <cstdlib>
#include <SDL.h>
#include <OpenGL/gl3.h>

int main()
{
    SDL_Init(SDL_INIT_VIDEO);

    SDL_Window *sdlWindow = SDL_CreateWindow(
        "OpenGL Works",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        640,
        480,
        SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI
    );
    SDL_GLContext sdlGLContext = SDL_GL_CreateContext(sdlWindow);

    unsigned int vertexArrayObject;

    // This works
    glGenVertexArrays(1, &vertexArrayObject);

    // Wait some seconds before closing the window
    SDL_Delay(3000);

    SDL_GL_DeleteContext(sdlGLContext);
    SDL_DestroyWindow(sdlWindow);

    return EXIT_SUCCESS;
}

Not working using a simple class (segmentation fault):

#include <cstdlib>
#include <memory>
#include <SDL.h>
#include <OpenGL/gl3.h>

class Graphics
{
    public:
        void createVAO();

    private:
        unsigned int vertexArrayObject;
};

void Graphics::createVAO()
{
    glGenVertexArrays(1, &this->vertexArrayObject);
}

int main()
{
    SDL_Init(SDL_INIT_VIDEO);

    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, 2);

    SDL_Window *sdlWindow = SDL_CreateWindow(
        "OpenGL Shit",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        640,
        480,
        SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI
    );
    SDL_GLContext sdlGLContext = SDL_GL_CreateContext(sdlWindow);

    std::unique_ptr<Graphics> g;

    g->createVAO();

    // Wait some seconds before closing the window
    SDL_Delay(3000);

    SDL_GL_DeleteContext(sdlGLContext);
    SDL_DestroyWindow(sdlWindow);

    return EXIT_SUCCESS;
}

The same happens for glGenBuffers. I wonder if it is just a "simple" C++ problem caused by my lack of c++ skills or if it is a more serious problem related to OpenGL and/or SDL. I found a lot of questions on Stack Overflow with similar symptoms but most of them where caused by the missing option glewExperimental = GL_TRUE; for GLUT or GLEW which I am not using at all or a missing OpenGL context which I have, because I am able to draw on the screen:

I hope somebody can explain why this is crashing, because I can't :(

I'm using Mac OS 10.9.3 and the compiler is Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) and this is the compiler invocation: c++ -o OpenGLTest main.cpp -I /usr/local/include/SDL2 -lSDL2 -framework OpenGL


Solution

  • std::unique_ptr<Graphics> g;
    g->createVAO();
    

    Where do you actually populate g with something?

    Right now it looks like you're dereferencing a NULL pointer.

    Try this:

    std::unique_ptr<Graphics> g( new Graphics );