Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: GLSL matrix uniforms acting wierd

Hybrid View

  1. #1
    Intern Contributor
    Join Date
    Jun 2012
    Posts
    63

    GLSL matrix uniforms acting wierd

    I have a very simple vertex shader that takes in vertex position and normals and a MVP matrix:
    Code :
    #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:
    Code :
    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:
    Code :
        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?

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,097
    Code :
     
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •