Search code examples
javaopenglglsllwjgl

Why are my uniform locations showing incorrectly?


I'm attempting to get the uniform locations of variables in my shader.

@Override
public void getAllUniformLocations(){
    location_transformationMatrix = super.getUniformLocation("transformationMatrix");
    location_lightPosition = super.getUniformLocation("lightPosition");
    location_lightColour = super.getUniformLocation("lightColour");
    System.out.println(location_transformationMatrix + " | "
            + location_lightPosition + " | " + location_lightColour);
}
public int getUniformLocation(String name){
    return GL20.glGetUniformLocation(programID, name);
}

However, when it prints out, it prints completely incorrectly:

0 | -1 | -1

0 is for the fixed-function pipeline, so having something bound there is going to completely crash the program, and the other two are simply returning -1, which is a null value.

Here is my shader loading code:

public ShaderProgram(String vertexFile,String fragmentFile){
    System.out.println("Comiling shader!");
    vertexShaderID = loadShader(vertexFile,GL20.GL_VERTEX_SHADER);
    fragmentShaderID = loadShader(fragmentFile,GL20.GL_FRAGMENT_SHADER);
    programID = GL20.glCreateProgram();
    GL20.glAttachShader(programID, vertexShaderID);
    GL20.glAttachShader(programID, fragmentShaderID);
    bindAttributes();
    getAllUniformLocations();
    GL20.glLinkProgram(programID);
    GL20.glValidateProgram(programID);
    start();
    System.out.println(GL11.glGetError());
    System.out.println("Comiled shader!");
}

The shaders bind, attach, validate, compile, etc, completely successfully, and the game does successfully run at this point. However, the uniform locations are missing and so I am unable to achieve things like lighting.

Here is my vertex shader:

#version 130

in vec3 position;
in vec2 textureCoords;
in vec3 normal;

out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;

uniform mat4 transformationMatrix;
uniform vec3 lightPosition;

void main(void){
    gl_Position = ftransform();
    pass_textureCoords = textureCoords;
    surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz;
    toLightVector = (vec3(0, 20000, 0)) - (transformationMatrix * vec4(position, 1.0)).xyz;
}

Variables 0, 1, 2, and 3 are all bound to attributes, so I would expect the numbers to return something along the lines of "4 | 5 | 6".

Here is my fragment shader:

#version 130

in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;

out vec4 out_Color;

uniform sampler2D textureSampler;

uniform vec3 lightColour;

void main(void){
    vec3 unitNormal = normalize(surfaceNormal);
    vec3 unitLightVector = normalize(toLightVector);

    float nDot1 = dot(unitNormal, unitLightVector);
    float brightness = max(nDot1, 0.5);
    brightness = brightness * 1.5;
    vec3 diffuse = brightness * vec3(1, 1, 1);
    vec4 text = texture(textureSampler, pass_textureCoords);
    vec4 textureColor = vec4(diffuse, 1.0) * text;
    if(textureColor.a<0.01){
        discard;
    }
    out_Color = vec4(textureColor.r, textureColor.g, textureColor.b, textureColor.a);

}

Solution

  • The results you are getting are absoutely correct, your interpretations of them are not:

    0 is for the fixed-function pipeline, so having something bound there is going to completely crash the program,

    No. 0 is a perfectly valid uniform location, which has nothing to do the fixed function pipeline. You somehow seem to confuse the program object 0 (which represents the fixed-function pipeline in legacy GL and compatibility profiles) with the per-program uniform locations.

    and the other two are simply returning -1, which is a null value.

    Well, more or less. -1 means that there is no acivte uniform of that name. Note that calling glUniform*() functions with location -1 is explicitely defined to be no error - such calls just have no effect.

    The shader code you have pasted simply does not use the lightPosition and lightColour uniforms, so they are not there. You might intend to use them in the fragment shader, but I'd bet my life on it that you don't do it there in the correct way - i.e. even if you declare and use them in the code, they might still have no effect on the shader outputs, so are still not active.