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.
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.
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)
来源:https://stackoverflow.com/questions/24240107/glsl-cant-get-uniforms-location