"GLSL 3.30 is not supported" when compiling GLSL shader on Ubuntu 18.04?
Asked Answered
S

2

9

I am trying to draw a triangle on a GLFW window with OpenGL.

Here is my complete code:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
using namespace std;

static unsigned int compileShader ( unsigned int type, const string& source ){
    unsigned int id = glCreateShader ( type );
    const char* src = source.c_str();
    glShaderSource ( id, 1, &src, nullptr );
    glCompileShader ( id );
    
    int result = 0;
    glGetShaderiv ( id, GL_COMPILE_STATUS, &result );
    if ( result == GL_FALSE ){
        int length = 0;
        glGetShaderiv ( id, GL_INFO_LOG_LENGTH, &length );
        char* message = ( char* ) alloca ( length * sizeof ( char ) );
        glGetShaderInfoLog ( id, length, &length, message );
        cout << "Failed to compile " << ( type == GL_VERTEX_SHADER ? "vertex" : "fragment" ) <<  "shader" << endl;
        cout << message << endl;
        glDeleteShader ( id );
    }
    return id;
}
static int createShader ( const string& vertexShader, const string& fragmentShader ){
    unsigned int program = glCreateProgram();
    unsigned int vs = compileShader ( GL_VERTEX_SHADER, vertexShader );
    unsigned int fs = compileShader ( GL_FRAGMENT_SHADER, fragmentShader );
    
    glAttachShader ( program, vs );
    glAttachShader ( program, fs );
    glLinkProgram ( program );
    glValidateProgram ( program );

    glDeleteShader ( vs );
    glDeleteShader ( fs );

    return program;
}

int main(void)
{
    GLFWwindow* window;  
    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }
   
    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    if ( glewInit() != GLEW_OK ) 
        cout << "error" << endl;

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    cout << glGetString ( GL_VERSION ) << endl;

    float positions [ 6 ] = {
        -0.5f, -0.5f,
         0.0f,  0.5f,
         0.5f, -0.5f
    };
    unsigned int buffer;
    glGenBuffers ( 1, &buffer );
    glBindBuffer ( GL_ARRAY_BUFFER, buffer );
    glBufferData ( GL_ARRAY_BUFFER, 6 * sizeof ( float ),positions, GL_STATIC_DRAW );
    glEnableVertexAttribArray ( 0 );
    glVertexAttribPointer ( 0, 2, GL_FLOAT, GL_FALSE, sizeof ( float ) * 2, 0 );

    string vertexShader = 
        "#version 320 core\n"
        "\n"
        "layout ( location = 0 ) in vec4 position;"
        "\n"
        "void main(){\n"
            "gl_Position = position;\n"
        "}\n";
    string fragmentShader = 
        "#version 320 core\n"
        "\n"
        "layout ( location = 0 ) out vec4 color;"
        "\n"
        "void main(){\n"
            "color = vec4(1.0,0.0,0.0,1.0);\n"
        "}\n";
    unsigned int shader = createShader(vertexShader, fragmentShader );
    glUseProgram ( shader );


    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

    glDrawArrays ( GL_TRIANGLES, 0, 3 );

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;

}

...and here is the output I am getting:

3.0 Mesa 18.0.5
Failed to compile vertexshader
0:1(10): error: GLSL 3.20 is not supported. Supported versions are: 1.10, 1.20, 1.30, 1.00 ES, 3.00 ES, 3.10 ES, and 3.20 ES

Failed to compile fragmentshader
0:1(10): error: GLSL 3.20 is not supported. Supported versions are: 1.10, 1.20, 1.30, 1.00 ES, 3.00 ES, 3.10 ES, and 3.20 ES

I am using Ubuntu 18.04.

Here is the output of sudo glxinfo | grep "OpenGL":

OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) HD Graphics 620 (Kaby Lake GT2) 
OpenGL core profile version string: 4.5 (Core Profile) Mesa 18.0.5
OpenGL core profile shading language version string: 4.50
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 18.0.5
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.2 Mesa 18.0.5
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20
OpenGL ES profile extensions:
Startle answered 1/10, 2018 at 13:31 Comment(7)
I tried changing the version name from 1.10 to 3.20 and nothing workedStartle
Have you tried using a core profile?Ferous
Please let me know how to do thatStartle
My bad, you have already done that. Though I'd wager that the glfwWindowHint calls should go before glfwCreateWindow to affect it.Ferous
I tried that, but the result is sameStartle
Unrelated tip: you can use raw string literals to embed your glsl snippets without manually adding quotes, and preserving line numbers.Ferous
thanks for that, I will make use of itStartle
M
12

Multiple issues:

  • #version 320 never existed, it went from #version 150 with GL 3.2 to #version 330 in GL 3.3.
  • Set your glfwWindowHint()s before calling glfwCreateWindow(). They only affect the next glfwCreateWindow() so calling them after creating your window doesn't do much for you.
  • In Core contexts you need to have a vertex array object (VAO) bound before drawing anything.
  • You need to have a VAO bound before glEnableVertexAttribArray() & glVertexAttribPointer() do anything useful.

All together:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
using namespace std;

static unsigned int compileShader( unsigned int type, const string& source )
{
    unsigned int id = glCreateShader( type );
    const char* src = source.c_str();
    glShaderSource( id, 1, &src, nullptr );
    glCompileShader( id );

    int result = 0;
    glGetShaderiv( id, GL_COMPILE_STATUS, &result );
    if( result == GL_FALSE )
    {
        int length = 0;
        glGetShaderiv( id, GL_INFO_LOG_LENGTH, &length );
        char* message = (char*)alloca( length * sizeof( char ) );
        glGetShaderInfoLog( id, length, &length, message );
        cout << "Failed to compile " << ( type == GL_VERTEX_SHADER ? "vertex" : "fragment" ) << "shader" << endl;
        cout << message << endl;
        glDeleteShader( id );
    }
    return id;
}

static int createShader( const string& vertexShader, const string& fragmentShader )
{
    unsigned int program = glCreateProgram();
    unsigned int vs = compileShader( GL_VERTEX_SHADER, vertexShader );
    unsigned int fs = compileShader( GL_FRAGMENT_SHADER, fragmentShader );

    glAttachShader( program, vs );
    glAttachShader( program, fs );
    glLinkProgram( program );
    glValidateProgram( program );

    glDeleteShader( vs );
    glDeleteShader( fs );

    return program;
}

int main( void )
{
    GLFWwindow* window;
    /* Initialize the library */
    if( !glfwInit() )
        return -1;

    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow( 640, 480, "Hello World", NULL, NULL );
    if( !window )
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent( window );
    if( glewInit() != GLEW_OK )
        cout << "error" << endl;

    cout << glGetString( GL_VERSION ) << endl;

    GLuint vao = 0;
    glCreateVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    string vertexShader =
        "#version 330 core\n"
        "\n"
        "layout ( location = 0 ) in vec4 position;"
        "\n"
        "void main(){\n"
        "gl_Position = position;\n"
        "}\n";
    string fragmentShader =
        "#version 330 core\n"
        "\n"
        "layout ( location = 0 ) out vec4 color;"
        "\n"
        "void main(){\n"
        "color = vec4(1.0,0.0,0.0,1.0);\n"
        "}\n";
    unsigned int shader = createShader( vertexShader, fragmentShader );
    glUseProgram( shader );

    float positions[ 6 ] = {
        -0.5f, -0.5f,
         0.5f, -0.5f,
         0.0f,  0.5f,
    };
    unsigned int buffer;
    glGenBuffers( 1, &buffer );
    glBindBuffer( GL_ARRAY_BUFFER, buffer );
    glBufferData( GL_ARRAY_BUFFER, 6 * sizeof( float ), positions, GL_STATIC_DRAW );
    glEnableVertexAttribArray( 0 );
    glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof( float ) * 2, 0 );

    /* Loop until the user closes the window */
    while( !glfwWindowShouldClose( window ) )
    {
        /* Render here */
        glClear( GL_COLOR_BUFFER_BIT );

        glDrawArrays( GL_TRIANGLES, 0, 3 );

        /* Swap front and back buffers */
        glfwSwapBuffers( window );

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}
Manzano answered 1/10, 2018 at 13:51 Comment(2)
Hats off man, I have been working on this for a long time, It is working perfectly now, thanks for the helpStartle
@Vijin: You're welcome! And thank you for the revision-1 minimal reproducible example, those help immensely.Manzano
L
37

I solved the problem by running the following command on Linux:

export MESA_GL_VERSION_OVERRIDE=3.3
Lagasse answered 17/9, 2019 at 3:19 Comment(6)
Can you elaborate?Alaynaalayne
@MikeW is there anything to elaborate? You just run that command on a Linux terminal before running the executable that's causing the problem, that solved the problem for me.Eulogist
I meant why does it work? some more contextAlaynaalayne
I mean it's quite clear what it does right? It overrides the version of your OpenGL implementation, provided you got that from Mesa (which is usually the case for Ubuntu users). It doesn't magically add the higher version functionalities so I suppose you'd still error out if you bump into any newer version calls..Fistic
This does do the trick for me when using WSL2 or other X-forwarding where for some reason the OpenGL version of my Linux box is checked and not those of the graphics card actually powering my X-serverFistic
I was having problems compiling shaders on v330, ran this and it worked like a charm. Tested on Debian 10,Poriferous
M
12

Multiple issues:

  • #version 320 never existed, it went from #version 150 with GL 3.2 to #version 330 in GL 3.3.
  • Set your glfwWindowHint()s before calling glfwCreateWindow(). They only affect the next glfwCreateWindow() so calling them after creating your window doesn't do much for you.
  • In Core contexts you need to have a vertex array object (VAO) bound before drawing anything.
  • You need to have a VAO bound before glEnableVertexAttribArray() & glVertexAttribPointer() do anything useful.

All together:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
using namespace std;

static unsigned int compileShader( unsigned int type, const string& source )
{
    unsigned int id = glCreateShader( type );
    const char* src = source.c_str();
    glShaderSource( id, 1, &src, nullptr );
    glCompileShader( id );

    int result = 0;
    glGetShaderiv( id, GL_COMPILE_STATUS, &result );
    if( result == GL_FALSE )
    {
        int length = 0;
        glGetShaderiv( id, GL_INFO_LOG_LENGTH, &length );
        char* message = (char*)alloca( length * sizeof( char ) );
        glGetShaderInfoLog( id, length, &length, message );
        cout << "Failed to compile " << ( type == GL_VERTEX_SHADER ? "vertex" : "fragment" ) << "shader" << endl;
        cout << message << endl;
        glDeleteShader( id );
    }
    return id;
}

static int createShader( const string& vertexShader, const string& fragmentShader )
{
    unsigned int program = glCreateProgram();
    unsigned int vs = compileShader( GL_VERTEX_SHADER, vertexShader );
    unsigned int fs = compileShader( GL_FRAGMENT_SHADER, fragmentShader );

    glAttachShader( program, vs );
    glAttachShader( program, fs );
    glLinkProgram( program );
    glValidateProgram( program );

    glDeleteShader( vs );
    glDeleteShader( fs );

    return program;
}

int main( void )
{
    GLFWwindow* window;
    /* Initialize the library */
    if( !glfwInit() )
        return -1;

    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow( 640, 480, "Hello World", NULL, NULL );
    if( !window )
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent( window );
    if( glewInit() != GLEW_OK )
        cout << "error" << endl;

    cout << glGetString( GL_VERSION ) << endl;

    GLuint vao = 0;
    glCreateVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    string vertexShader =
        "#version 330 core\n"
        "\n"
        "layout ( location = 0 ) in vec4 position;"
        "\n"
        "void main(){\n"
        "gl_Position = position;\n"
        "}\n";
    string fragmentShader =
        "#version 330 core\n"
        "\n"
        "layout ( location = 0 ) out vec4 color;"
        "\n"
        "void main(){\n"
        "color = vec4(1.0,0.0,0.0,1.0);\n"
        "}\n";
    unsigned int shader = createShader( vertexShader, fragmentShader );
    glUseProgram( shader );

    float positions[ 6 ] = {
        -0.5f, -0.5f,
         0.5f, -0.5f,
         0.0f,  0.5f,
    };
    unsigned int buffer;
    glGenBuffers( 1, &buffer );
    glBindBuffer( GL_ARRAY_BUFFER, buffer );
    glBufferData( GL_ARRAY_BUFFER, 6 * sizeof( float ), positions, GL_STATIC_DRAW );
    glEnableVertexAttribArray( 0 );
    glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof( float ) * 2, 0 );

    /* Loop until the user closes the window */
    while( !glfwWindowShouldClose( window ) )
    {
        /* Render here */
        glClear( GL_COLOR_BUFFER_BIT );

        glDrawArrays( GL_TRIANGLES, 0, 3 );

        /* Swap front and back buffers */
        glfwSwapBuffers( window );

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}
Manzano answered 1/10, 2018 at 13:51 Comment(2)
Hats off man, I have been working on this for a long time, It is working perfectly now, thanks for the helpStartle
@Vijin: You're welcome! And thank you for the revision-1 minimal reproducible example, those help immensely.Manzano

© 2022 - 2024 — McMap. All rights reserved.