Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GLSL: Can't get uniforms location

Tags:

opengl

glsl

My problem is fact that I can't get some uniforms location, when location of others I get without problems.

For example I have in VS uniforms called "MVP" and "Model" and I have "MVP" location without problems, but I don't have "Model" location which I use symmetrically. In the same manner I can't get location of fields from Light structure in FS.

Its code passing data into shader:

bool Shader::SetShaderParameters(mat4 MVPMatrix,mat4 Model,GLint textureUnit)
{
  GLuint matrixLocation = glGetUniformLocation(programID,"MVP");
  if(matrixLocation==-1)
    return false;
  glUniformMatrix4fv(matrixLocation,1,GL_FALSE,&MVPMatrix[0][0]);
  GLuint modelLocation = glGetUniformLocation(programID,"Model");
  if(modelLocation==-1)
    return false;
  glUniformMatrix4fv(modelLocation,1,GL_FALSE,&Model[0][0]);
  return true;
}

bool Shader::SetShaderLights(vec3 lightColor,vec3 ambientIntensity,vec3 direction,vec3 diffuseIntensity)
{
    GLuint lightColorLocation = glGetUniformLocation(programID,"light.lightColor");
    if(lightColorLocation==-1)
        return false;
    glUniform3fv(lightColorLocation,1,&lightColor[0]);
    GLuint ambientIntensityLocation = glGetUniformLocation(programID,"light.ambientIntensity");
    if(ambientIntensityLocation==-1)
        return false;
    glUniform3fv(ambientIntensityLocation,1,&ambientIntensity[0]);
    GLuint directionLocation = glGetUniformLocation(programID,"light.direction");
    if(directionLocation==-1)
        return false;
    glUniform3fv(directionLocation,1,&direction[0]);
    GLuint diffuseIntensityLocation = glGetUniformLocation(programID,"light.diffuseIntensity");
    if(diffuseIntensityLocation==-1)
        return false;
    glUniform3fv(diffuseIntensityLocation,1,&diffuseIntensity[0]);
    return true;
}

It's code of shaders:

VS:

#version 440 core

layout(location=0) in vec3 vertexPosition;
layout(location=1) in vec2 vertexUV;
layout(location=2) in vec3 normal;

out vec2 uv;
out vec3 norm;

uniform mat4 Model;
uniform mat4 MVP;

void main()
{
  gl_Position = MVP*vec4(vertexPosition,1.0);
  uv = vertexUV;
  norm = (Model*vec4(normal,0.0)).xyz;
}

FS:

#version 440 core

struct Light
{
  vec3 lightColor;
  vec3 ambientIntensity;
  vec3 direction;
  vec3 diffuseIntensity;
};

in vec2 uv;
in vec3 norm;

out vec3 color;

uniform sampler2D texSamp;
uniform Light light;

void main()
{
  color = texture(texSamp,uv).rgb*light.ambientIntensity;
}

What can be problem in various behaviours while getting location of uniforms? Maybe I use bad version of shaders or it's somelike optimisations of data in shaders. I was debugging my solution and I'm pretty sure that shader program IDs are correct.

[EDIT]: When I try to use norm in FS nothing changes, and after glGetUniformLocation() which can't get location I got zero error code.

like image 320
CppMonster Avatar asked Jun 16 '14 09:06

CppMonster


People also ask

How do you use uniforms in OpenGL?

Uniforms are intended to be set by the user from OpenGL, rather than within the shader. However, you can initialize them to a default value using standard GLSL initalizer syntax: uniform vec3 initialUniform = vec3(1.0, 0.0, 0.0); This will cause the uniform to have this vector as its value, until the user changes it.

Is gl_FragColor deprecated?

Yes, gl_FragColor is deprecated. You should use the following syntax: layout(location = 0) out vec4 diffuseColor; It is included in the GLSL 4.60 spec under the section 7.1.

What is sampler2D?

A sampler2D is used to do lookup in a standard texture image; a samplerCube is used to do lookup in a cubemap texture (Subsection 5.3. 4). The value of a sampler variable is a reference to a texture unit. The value tells which texture unit is invoked when the sampler variable is used to do texture lookup.

What is gl_FragCoord?

The input variable gl_FragCoord is an input variable that allows us to read screen-space coordinates and get the depth value of the current fragment, but it is a read-only variable. We can't influence the screen-space coordinates of the fragment, but it is possible to set the depth value of the fragment.


2 Answers

The compiler is allowed to optimize away any unused uniforms, which is why you get this error.

You can safely ignore this. If the uniform isn't found, glGetUniformLocation returns -1. From the OpenGL 4.3 specs, section 7.6.1:

If the value of location is -1, the Uniform* commands will silently ignore the data passed in, and the current uniform values will not be changed.

like image 55
Andreas Haferburg Avatar answered Sep 25 '22 10:09

Andreas Haferburg


This is an extension to Andreas's answer.

In my case, when I put glGetUniformLocation or glUniform* before glUseProgram, I got -1; however, when I put those two after glUseProgram, I can get the correct uniform location.

( My version is OpenGL 3.3, GLSL 3.30)

like image 34
Jiang Avatar answered Sep 21 '22 10:09

Jiang