Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting up a MVP Matrix in OpenGL

Tags:

c++

opengl

glsl

i'm trying to learn the basics of OpenGL, but i have a Problem with setting up the transformation matrices. I made the model, view and projection matrices, but i have a problem sending them to my vertex shader.

Here is the code:

//Set up MVP
glm::mat4 model = glm::mat4();
GLint uniModel = glGetUniformLocation(program, "model");
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));

glm::mat4 view = glm::lookAt(
    glm::vec3(2.5f, 2.5f, 2.0f),
    glm::vec3(0.0f, 0.0f, 0.0f),
    glm::vec3(0.0f, 0.0f, 1.0f));
GLint uniView = glGetUniformLocation(program, "view");
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));

glm::mat4 proj = glm::perspective(45.0f, 800.0f / 600.0f, 1.0f, 10.0f);
GLint uniProj = glGetUniformLocation(program, "proj");
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));

and the shader:

layout (location = 0) in vec3 position;

uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main() {
    gl_Position = proj * view * model * vec4(position, 1.0);
}

I think i did something wrong with setting up the uniforms, because it doesn't draw anything, even if i set model, view and proj to the identity. Could be i just mistyped something, but i really can't find the problem.

Edit: Solved it, the problem was that i forgot to use glUseProgram() first.

like image 346
0x40_hues Avatar asked Nov 01 '22 05:11

0x40_hues


1 Answers

The first thing to do is check all possible return codes, verify your shader program has compiled and linked correctly, and make sure your uniforms are valid, which means the location value is >= 0.

A binary search with glGetError() can also be very useful in these instances when you don't know where it's going wrong.

After compiling the shaders, make sure you check glGetProgram(GL_LINK_STATUS,...). And finally, you must call glUseProgram() to activate the shader.

As @Vallentin suggests, it is much more efficient to pass in your precalculated MVP matrix, since it will not change between the app and the shader. This simplifies your code somewhat, to something like this for your application code:

// Set up MVP matrices

glm::mat4 model = glm::mat4();

glm::mat4 view = glm::lookAt(
    glm::vec3(2.5f, 2.5f, 2.0f),
    glm::vec3(0.0f, 0.0f, 0.0f),
    glm::vec3(0.0f, 0.0f, 1.0f));

glm::mat4 proj = glm::perspective(45.0f, 800.0f / 600.0f, 1.0f, 10.0f);

glm::mat4 mvp = proj * view * model;

glUseProgram(prog);

GLint uniMvp = glGetUniformLocation(program, "mvp");
glUniformMatrix4fv(uniMvp, 1, GL_FALSE, glm::value_ptr(mvp));

and then the GLSL:

// Shader code

layout (location = 0) in vec3 position;
uniform mat4 mvp;

void main() {
    gl_Position = mvp * vec4(position, 1.0);
}

Also, you could cache the uniform locations, since they won't change once compiled. This will save a small amount per frame, rather than querying them for every redraw.

like image 191
gavinb Avatar answered Nov 04 '22 08:11

gavinb