Passing uniform 4x4 matrix to vertex shader progra

2020-07-06 07:45发布

问题:

I am trying to learn OpenGL and following this: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/

Up until the point where they started passing matrices to the vertex shader to translate the triangle they where drawing I was following along.

This is the shader program where it starts to go wrong:

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
uniform mat4 MVP;

void main(){
    vec4 v = vec4(vertexPosition_modelspace,1); // Transform an homogeneous 4D vector

    gl_Position = MVP * v;

    //mat4 M = mat4(
    // vec4(1.0, 0.0, 0.0, 0.0),
    // vec4(0.0, 1.0, 0.0, 0.0),
    // vec4(0.0, 0.0, 1.0, 0.0),
    // vec4(0.0, 0.0, 0.0, 1.0)
    //);
    //gl_Position = M * v;
}

If I use the commented out code instead of the line gl_Position = MVP * v;, everything works. A triangle is drawn to the screen. I can also change to M matrix to move the triangle around and scale it.

In order to keep things as simple as possible I am just passing the vertex shader an identity matrix in the MVP field. The code looks like this:

mat4x4 MVP;
mat4x4_identity(MVP);

int i,j;
for(i=0; i<4; ++i) {
    for(j=0; j<4; ++j)
        printf("%f, ", MVP[i][j]);
    printf("\n");
}

GLuint MatrixID = glGetUniformLocation(programID, "MVP");

// Send our transformation to the currently bound shader,
// in the "MVP" uniform
// For each model you render, since the MVP will be different (at least the M part)
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

I am using linmath.h instead of glm (https://github.com/datenwolf/linmath.h). The loop prints:

1.000000, 0.000000, 0.000000, 0.000000, 
0.000000, 1.000000, 0.000000, 0.000000, 
0.000000, 0.000000, 1.000000, 0.000000, 
0.000000, 0.000000, 0.000000, 1.000000, 

And confirms that MVP is indeed an identity matrix. However when I run the program, I see no triangle on the screen. Only the background (which is dark blue btw).

You can see slightly more of the main C program here: https://gist.github.com/avwhite/68580376ddf9a7ec9cb7

If needed I can also provide the whole source code for the main program, the vertex-, and the fragment shader.

I am thinking this has something to do with how the MVP matrix is passed to the shader program, but I am completely new to OpenGL, so I really have no idea what is going on.

回答1:

glUniform*() calls set values for the current program. You need to call glUseProgram() before the glUniform*() call. In this example:

glUseProgram(programID);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);


回答2:

Consider using value_ptr rather then &MVP[0][0]

glUniformMatrix4fv(MatrixID, 1, GL_FALSE, glm::value_ptr(MVP));

genType::value_type const* glm::value_ptr (genType const & vec)

Return the constant address to the data of the input parameter