Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing uniform 4x4 matrix to vertex shader program

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.

like image 739
Andreas Vinter-Hviid Avatar asked Aug 16 '14 18:08

Andreas Vinter-Hviid


People also ask

How do you pass a uniform to a shader?

There is no "interface" between different shader programs. If you want to use the same uniform in your second shader program, then you simply need to declare and upload that same uniform in your second shader program, just like you did it for your first shader program.

Can uniform variables be declared in a fragment shader?

Uniform variables can appear in any shader within a shader program, and are always used as input variables. They can be declared in one or more shaders within a program, but if a variable with a given name is declared in more than one shader, its type must be the same in all shaders.

How do I change my OpenGL uniform?

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.


1 Answers

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

like image 89
kupihleba Avatar answered Sep 29 '22 18:09

kupihleba