GLSL Syntax error at #version, GL Version is Metal?

I am having a very confusing issue with my glsl shaders. The loading code looks like this:

                std::string vertCodeStr;
                std::string fragCodeStr;
                std::ifstream vertFile;
                std::ifstream fragFile;
                vertFile.open(vertName);
                fragFile.open(fragName);
                if(!vertFile.good() || !fragFile.good()) exit(1);
                std::stringstream vertStream;
                std::stringstream fragStream;
                vertStream << vertFile.rdbuf();
                fragStream << fragFile.rdbuf();
                vertFile.close();
                fragFile.close();
                vertCodeStr = vertStream.str();
                fragCodeStr = fragStream.str();
                const char* vertCodeChar = vertCodeStr.c_str();
                const char* fragCodeChar = fragCodeStr.c_str();

                unsigned int vertsh;
                unsigned int fragsh;
                int success;
                char log[512];

                // Compile the shaders
                vertsh = glCreateShader(GL_VERTEX_SHADER);
                glShaderSource(vertsh, 1, &vertCodeChar, NULL);
                glCompileShader(vertsh);

                glGetShaderiv(vertsh, GL_COMPILE_STATUS, &success);
                if(!success) {
                    glGetShaderInfoLog(vertsh, 512, NULL, log);
                    std::cout << "Vertex shader didn't compile properly. GL Log: \n" << log << std::endl;
                };  

                fragsh = glCreateShader(GL_FRAGMENT_SHADER);
                glShaderSource(fragsh, 1, &fragCodeChar, NULL);
                glCompileShader(fragsh);

                glGetShaderiv(fragsh, GL_COMPILE_STATUS, &success);
                if(!success) {
                    glGetShaderInfoLog(fragsh, 512, NULL, log);
                    std::cout << "Fragment shader didn't compile properly. GL Log: \n" << log << std::endl;
                };                  

                program = glCreateProgram();
                glAttachShader(program, vertsh); 
                glAttachShader(program, fragsh);
                glLinkProgram(program);

                glGetProgramiv(program, GL_LINK_STATUS, &success);
                if(!success) {
                    glGetProgramInfoLog(program, 512, NULL, log);
                    std::cout << "Linking didn't work. GL Log:\n" << log << std::endl;
                }

                glDeleteShader(vertsh);
                glDeleteShader(fragsh);

Shaders look like:

#version 100 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

void main()
{
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor;
    TexCoord = aTexCoord;
}

And:

#version 100 core
out vec4 FragColor;
  
in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D ourTexture;

void main()
{
    FragColor = texture(ourTexture, TexCoord);
}

Finally, the output is:

GL Version (glGetString(GL_VERSION): 2.1 Metal - 83.1
Vertex shader didn't compile properly. GL Log: 
ERROR: 0:1: '' :  version '100' is not supported
ERROR: 0:1: '' : syntax error: #version
ERROR: 0:2: 'layout' : syntax error: syntax error

Fragment shader didn't compile properly. GL Log: 
ERROR: 0:1: '' :  version '100' is not supported
ERROR: 0:1: '' : syntax error: #version

Linking didn't work. GL Log:
ERROR: One or more attached shaders not successfully compiled

I am very confused why the version is Metal instead of GL 4.1. I have also tried versions 410 and 330 but they do not work either. Help needed!
EDIT: Version 120 works. However, the syntax errors remain.

Does it matter? I would think that the ERROR: 0:1: '' : version '100' is not supported would be far more important. Because GLSL 1.00 does not have the #version directive.

Also, GLSL 1.00 does not have layout as a keyword.

I thought that OSX has OpenGL 4.1? Why does only GLSL version 120 work even if the newest OpenGL version should be 4.1? Do I have to specify that I want that version to GL or the function loader?

Because OpenGL tries to be backwards compatible; GLSL 1.20 is required to be accepted by 4.1 implementations.

But 1.20 does not feature the layout keyword, which is why you keep getting syntax errors. If you declare a shader to be of version 1.20, then the implementation will read it as such. It won’t import higher-versioned features because… you specifically asked it not to do so.

I understand that; however when the version is the what the current version should be (4.1 = 410) the errors still look like this:

2.1 Metal - 83.1
Vertex shader didn't compile properly. GL Log: 
ERROR: 0:1: '' :  version '410' is not supported
ERROR: 0:1: '' : syntax error: #version
ERROR: 0:2: 'layout' : syntax error: syntax error

Fragment shader didn't compile properly. GL Log: 
ERROR: 0:1: '' :  version '410' is not supported
ERROR: 0:1: '' : syntax error: #version

Linking didn't work. GL Log:
ERROR: One or more attached shaders not successfully compiled

I can’t figure out why it doesn’t support 410 because the OpenGL version should be 4.1. 410 should also support #version and layout, fixing the other issues. Secondarily, I was asking if 2.1 Metal = 2.1 OpenGL for debugging purposes so I could fix the issues.

SOLUTION: Before the context is fully initialized you have to set the profile to core. Otherwise it will use an outdated version. In my case (I am using SDL):

// Make window here

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 

// Do the rest of the initialization stuff here

Or, if using GLFW:

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

// Make the window

Thank you for your help!

1 Like