glewInit() returns an unknown error

Hello,

I’m trying to follow the OpenGL - drawing polygons tutorial and I get an error when I try to run the program.

I was trying to create a VBO, but it wouldn’t let me, saying

Call to undeclared function 'glGenBuffers'; ISO C99 and later do not support implicit function declarations

After some research I found out that even though I specified the SDL_GL_SetAttribute to use OpenGL version 4.6, the dynamic linking meant the system might not have that version to load, so I added GLEW to the mix and that seems to fix it.

Except now I get a runtime error

Unable to initialize GLEW: Unknown error

I’m not sure how to debug this or what to do as it is my first time using OpenGL and C, so it’s all a learning process and I don’t know what to look up since the error doesn’t provide enough info.

#include <stdio.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <GL/glew.h>

int main (int argc, char *argv[]) {
    SDL_Window* window;
    SDL_GLContext context;
    GLenum glew_init;
    int vsync;
    bool isRunning = true;

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("Unable to init SDL: %s\n", SDL_GetError());
        return 1;
    }

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    window = SDL_CreateWindow(
        "OPENGL SDL C TEST",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        900,
        600,
        SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
    );
    if (window == NULL) {
        printf("Unable to create renderer: %s\n", SDL_GetError());
        return 1;
    }

    context = SDL_GL_CreateContext(window);
    if (context == NULL) {
        printf("Unable to create context: %s\n", SDL_GetError());
        return 1;
    }

    vsync = SDL_GL_SetSwapInterval(-1);
    if(vsync < 0) {
        printf("Unable to set adaptive VSync: %s\nSetting default VSync\n", SDL_GetError());
        SDL_GL_SetSwapInterval(1);
    }

    glew_init = glewInit();
    if (glew_init != GLEW_OK) {
        printf("Unable to initialize GLEW: %s\n", glewGetErrorString(glew_init));
        return 1;
    }

    // create vertex data
    GLfloat vertices[] = {
        -0.5f, -0.5f, 0.0f, // vertex 1
        0.5f, -0.5f, 0.0f, // vertex 2
        0.0f, 0.5f, 0.0f // vertex 3
    };

    // // create VBO to store vertex data
    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    SDL_Log("GL version %s", glGetString(GL_VERSION));
    SDL_Log("GLEW version %s", glewGetString(GLEW_VERSION));

    glClearColor(0.3, 0.3, 0.3, 1.0);

    while (isRunning) {
        SDL_Event event;

        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                isRunning = false;
            }
        }

        glClear(GL_COLOR_BUFFER_BIT);
        SDL_GL_SwapWindow(window);
    }

    // Free pointers and quit. The order of free matters (segfault)
    // glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

// gcc src/sdl_opengl.c -o test_opengl_sdl_c -lSDL2 -lGL -lGLEW