0
votes

I'm drawing a triangle on screen with OpenGL and SDL2.

My problem resides at the shaders compiling stage.

Here are the errors I get :

ERROR::SHADER::VERTEX::COMPILATION_FAILED 0:1(10): error: GLSL 3.30 is not supported. Supported versions are: 1.10, 1.20, 1.30, 1.40, 1.00 ES, and 3.00 ES

ERROR::SHADER::FRAGMENT::COMPILATION_FAILED 0:1(10): error: GLSL 3.30 is not supported. Supported versions are: 1.10, 1.20, 1.30, 1.40, 1.00 ES, and 3.00 ES

ERROR::SHADER::PROGRAM::LINKING_FAILED error: linking with uncompiled/unspecialized shadererror: linking with uncompiled/unspecialized shader

I saw on some forums people having the same error messages, and they were told that by default MESA will switch to compatibility profile instead of core profile, but the thing is that I've explicitly told SDL2 to create a core context profile :

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

By the way, I've already used OpenGL version 3.30 with GLSL 3.30 on that same computer without any issues by using it with GLFW and GLAD, but now I just want to have it working with SDL2 and GLEW.

Here is the result of the glxinfo | grep "version" command :

server glx version string: 1.4
client glx version string: 1.4
GLX version: 1.4
    Max core profile version: 3.3
    Max compat profile version: 3.1
    Max GLES1 profile version: 1.1
    Max GLES[23] profile version: 3.1
OpenGL core profile version string: 3.3 (Core Profile) Mesa 19.1.7
OpenGL core profile shading language version string: 3.30
OpenGL version string: 3.1 Mesa 19.1.7
OpenGL shading language version string: 1.40
OpenGL ES profile version string: OpenGL ES 3.1 Mesa 19.1.7
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10
    GL_EXT_shader_implicit_conversions, GL_EXT_shader_integer_mix,

And the content of my main function :

int main(int argc, char* argv[])
{
    // =====> INIT VARS
    SDL_Window* window;
    SDL_Renderer* renderer;
    SDL_GLContext glContext;
    GLenum err;
    // INIT VARS <=====

    if(SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        std::cout << SDL_GetError() << std::endl;
        return -1;
    }
    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, 3);
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    window = createWindow(WIDTH, HEIGHT, "TP_PROGRAMMATION_3D");
    if(window == nullptr)
    {
        std::cout << SDL_GetError() << std::endl;
        SDL_Quit();
        return -1;
    }
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if(renderer == nullptr)
    {
        std::cout << SDL_GetError() << std::endl;
        SDL_DestroyWindow(window);
        SDL_Quit();
        return -1;
    }

    // OPENGL CONTEXT FOR THE WINDOW
    glContext = SDL_GL_CreateContext(window);

    // GLEW INIT
    err = glewInit();
    if(err != GLEW_OK)
    {
        std::cout << glewGetErrorString(err) << std::endl;
        SDL_GL_DeleteContext(glContext);
        SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window);
        SDL_Quit();
        return -1;
    }

    // EVERYTHING'S FINE : TIME TO PAINT IT GREY
    glViewport(0, 0, WIDTH, HEIGHT);
    SDL_GL_SetSwapInterval(1);
    glClearColor(Color::LIGHT_GREY[0], Color::LIGHT_GREY[1], Color::LIGHT_GREY[2], Color::LIGHT_GREY[3]);

    // OPENGL DRAWING CALLS AND MAIN DRAWING LOOP
    draw_gl(window);

    // END
    SDL_GL_DeleteContext(glContext);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

And the shader code:

const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}";

const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"   color = vec4(1.0f, 1.0f, 0.0f, 1.0f);\n"
"}";
1

1 Answers

0
votes

Alright, I got it working, but honestly I don't know why it works now with the little changes I made, since it seems to be nearly the same thing.

Here is the code:

#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <iostream>
#include "color.hpp"

#define WIDTH 800
#define HEIGHT 600

float triangle[] =
{
    -0.5f, -0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    0.0f, 0.5f, 0.0f
};

const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}";

const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"   color = vec4(1.0f, 1.0f, 0.0f, 1.0f);\n"
"}";

SDL_Window* createWindow(int w, int h, std::string title)
{
    SDL_Window* window = nullptr;

    if(SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        std::cout << SDL_GetError() << std::endl;
        return nullptr;
    }

    // OPENGL VERSION
    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, 3);

    // DOUBLE BUFFER
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

    if(w == 0 and h == 0)
    {
        window = SDL_CreateWindow(
                title.c_str(),
                SDL_WINDOWPOS_CENTERED,
                SDL_WINDOWPOS_CENTERED,
                w,
                h,
                SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN);
    }
    window = SDL_CreateWindow(
            title.c_str(),
            SDL_WINDOWPOS_CENTERED,
            SDL_WINDOWPOS_CENTERED,
            w,
            h,
            SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

    if(window == nullptr)
    {
        std::cout << SDL_GetError() << std::endl;
        return nullptr;
    }

    return window;
}

int processInput()
{
    SDL_Event event;

    if(SDL_PollEvent(&event))
    {
        if(event.type == SDL_QUIT)
            return -1;
        if(event.type == SDL_WINDOWEVENT_RESIZED)
            glViewport(0, 0, event.window.data1, event.window.data2);
    }
    return 1;
}

void draw_gl(SDL_Window* window)
{
    // VAO
    GLuint vao1;
    glGenVertexArrays(1, &vao1);
    glBindVertexArray(vao1);

    // VBO for a triangle
    GLuint vbo1;
    glGenBuffers(1, &vbo1);
    glBindBuffer(GL_ARRAY_BUFFER, vbo1);
    glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);

    // VertexAttribPointer
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // Vertex shader
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShader);

    // Fragment shader
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);

    // Check for compile errors if any
    int success;
    char infoLog[512];

    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if(! success)
    {
        glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }

    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if(! success)
    {
        glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
        std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
    }

    // Shader program
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if(! success)
    {
        glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
        std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
    }

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    glUseProgram(shaderProgram);

    while(true)
    {
        if(processInput() == -1)
            break;

        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        SDL_GL_SwapWindow(window);
    }
}

int main(int argc, char* argv[])
{
    // =====> INIT VARS
    SDL_Window* window;
    SDL_Renderer* renderer;
    SDL_GLContext glContext;
    GLenum err;
    // INIT VARS <=====

    window = createWindow(WIDTH, HEIGHT, "OPENGL");
    if(window == nullptr)
    {
        SDL_Quit();
        return -1;
    }

    // OPENGL CONTEXT FOR THE WINDOW
    glContext = SDL_GL_CreateContext(window);

    // GLEW INIT
    glewExperimental = true;
    err = glewInit();
    if(err != GLEW_OK)
    {
        std::cout << glewGetErrorString(err) << std::endl;
        SDL_GL_DeleteContext(glContext);
        SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window);
        SDL_Quit();
        return -1;
    }

    // EVERYTHING'S FINE : TIME TO PAINT IT GREY
    glViewport(0, 0, WIDTH, HEIGHT);
    SDL_GL_SetSwapInterval(1);
    glClearColor(Color::LIGHT_GREY[0], Color::LIGHT_GREY[1], Color::LIGHT_GREY[2], Color::LIGHT_GREY[3]);

    // OPENGL DRAWING CALLS AND MAIN DRAWING LOOP
    draw_gl(window);

    // END
    SDL_GL_DeleteContext(glContext);
    //SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}