PDA

View Full Version : GLSL matrix uniforms acting wierd



fiodis
02-19-2013, 11:42 AM
I have a very simple vertex shader that takes in vertex position and normals and a MVP matrix:

#version 130

in vec3 in_Position;
in vec3 in_Normal;
out vec4 ex_Color;
//wierd stuff - works if MVPMatrix uniform is updated, even if it's not used in main()
uniform mat4 PMatrix;
uniform mat4 VMatrix;
uniform mat4 MMatrix;
uniform mat4 MVPMatrix;
void main(void)
{
ex_Color = vec4(0.0, 1.0, 1.0, 1.0);
gl_Position = (PMatrix * VMatrix * MMatrix) * vec4(in_Position, 1.0);
}
I want to try out basic diffuse lighting; to do that I need the model matrix to put the normals in world space. So instead of passing a MVP matrix, I pass seperate model, view, and projection matrices, then multiply them in the shader.

The strange thing is, this only works if I also upload the MVP matrix multiplied on the C++ side to the MVPMatrix uniform, even if that uniform is not actually used to calculate gl_Position. So in the above shader, if I comment out uniform mat4 MVPMatrix and don't upload it in the C++ code, the shader doesn't work and nothing is rendered. Also strange, if I upload the MVP matrix to a uniform called mvpMatrix, it doesn't work. The name of the uniform has to be MVPMatrix, and I have no idea why.

Here's my code to upload the uniform, part of a shader class:

void Shader::updateUniform(const char * name, glm::vec2 uniform){
glUseProgram(this->progId);
GLuint dimenUniLoc = glGetUniformLocation(this->progId, name);
glUniform2fv(dimenUniLoc, 1, &uniform[0]);
glUseProgram(0);
}

void Shader::updateUniform(const char * name, glm::vec3 uniform){
glUseProgram(this->progId);
GLuint posUniLoc = glGetUniformLocation(this->progId, name);
glUniform3f(posUniLoc, uniform.x, uniform.y, uniform.z);
glUseProgram(0);
}

void Shader::updateUniform(const char * name, glm::mat4 uniform){
glUseProgram(this->progId);
GLuint matUniLocBrush = glGetUniformLocation(this->progId, name);
glUniformMatrix4fv(matUniLocBrush, 1, GL_FALSE, &uniform[0][0]);
glUseProgram(0);
}
And on the C++ side I have:

modelMat = mat4(1.0f);
viewMat = mat4(1.0f);
projMat = mat4(1.0f);

propShader.loadShaders("propVertShader.glsl", "propFragShader.glsl");

projMat = perspective(60.0f, 16.0f/9.0f, 0.001f, 1000.0f);
viewMat = lookAt(vec3(4, 10, 3), vec3(0, 0, 0), vec3(0, 1, 0));

mat4 mvpMat = projMat * viewMat * modelMat;
propShader.updateUniform("PMatrix", projMat);
propShader.updateUniform("MMatrix", modelMat);
propShader.updateUniform("VMatrix", viewMat);
propShader.updateUniform("MVPMatrix", mvpMat);

Does anyone have some idea how this could happen?

tonyo_au
02-25-2013, 09:40 PM
GLuint matUniLocBrush = glGetUniformLocation(this->progId, name);
if (matUniLocBrush != -1) glUniformMatrix4fv(matUniLocBrush, 1, GL_FALSE, &uniform[0][0]);


I don't know why your code is doing what it is but you must test that matUniLocBrush is not -1 before loading as the compile may optimise a uniform out of existance.

Also with the glm library I would use glm::value_ptr() to retrieve data pointers.