Search code examples
openglglslopengl-3

Why comment glBindFragDataLocation, the GL also works correctly?


const GLchar* vertexSource1 = "#version 330 core\n"
    "layout (location = 0) in vec2 position;\n"
    "layout (location = 1) in vec3 color;\n"
    "out vec3 Color;\n"
    "void main()\n"
    "{\n"
    "gl_Position = vec4(position, 0.0, 1.0);\n"
    "Color = color;\n"
    "}\0";
const GLchar* fragmentSource1 = "#version 330 core\n"
"    in vec3 Color;\n"
"    out vec4 outColor;\n"
"    void main()\n"
"    {\n"
"        outColor = vec4(Color, 1.0);\n"
"    }\n";


GLuint shaderProgram1 = glCreateProgram();
glAttachShader(shaderProgram1, vertexShader1);
glAttachShader(shaderProgram1, fragmentShader1);
//    glBindFragDataLocation(shaderProgram1, 0, "Color");
glLinkProgram(shaderProgram1);

Whether I add glBindFragDataLocation or not, the GL works correctly, Why?


Solution

  • Because you're "lucky". The OpenGL specification provides no guarantees about how fragment shader output locations are assigned if you don't assign them. It only says that each one will have a separate location; what locations those are is up to the implementation.

    However, considering the sheer volume of code that writes to a single output variable without explicitly assigning it to a location, it's highly unlikely that an OpenGL implementation would ever assign the first FS output location to anything other than 0. So while it isn't a spec guarantee, at this point, it is a de-facto requirement of implementations.

    Note: That doesn't mean you shouldn't assign that location manually. It's always best to be on the safe and explicit side.

    FYI: layout(location) works for fragment shader outputs too. So you should use that if you're using it on vertex attributes. Then you don't have to worry about doing it from code.