Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting a mat4 in OpenGL

Tags:

opengl

glsl

I've been reading a few (basic) tutorials about shaders. So far they've covered how to set variables in your shader. But this was only about ints, floats or vectors. I can't find anything about how to set a mat4 variable. My shader expects the following:

uniform vec3 CameraPos;
uniform mat4 ModelWorld4x4;

So the camera position and the world matrix of a model. I think i have the CameraPos right, but how on earth do i set the ModelWorld4x4 variable??


This is how i set the vector3

campos = glGetUniformLocation(shader.id(), "CameraPos");
glUniform3f(campos, 0.0f, 0.0f, 3.0f);

This is (one of the methods) how i tried to set the mat4

glGetFloatv(GL_MODELVIEW_MATRIX, modelworld);
modelw = glGetUniformLocation(shader.id(), "ModelWorld4x4");
glUniformMatrix4fv(g_modelworld4x4, modelworld); // Not working

I'm using the Assimp library to load a model, so currently the world matrix is stored in the aiMatrix4x4 struct.

// world matrix of the model
aiMatrix4x4 m = nd->mTransformation;

// Save in a global variable
g_modelworld4x4 = m;
like image 478
w00 Avatar asked Jan 26 '12 18:01

w00


People also ask

What is opengl mat4?

mat4 is a type representing a 4x4 matrix. It consists of 16 floating point values. That means it needs to be passed to shader as a float[16] type or float* pointer which contains at least 16 floating point values.

How many bytes is a vec4?

So, the alignment of a mat4 is like that of a vec4, which is 16 bytes. And the size of a mat4 is 4*sizeof(vec4) = 4*16 bytes.

What is GLSL uniform?

A uniform is a global Shader variable declared with the "uniform" storage qualifier. These act as parameters that the user of a shader program can pass to that program. Their values are stored in a program object.


2 Answers

Make sure that you are using ModelWorld4x4 in your shader so that it doesn't simply get compiled out. Assuming g_modelworld4x4 is a float *, this works for me:

int location = glGetUniformLocationARB(program, "ModelWorld4x4");
glUniformMatrix4fvARB(location, 1 /*only setting 1 matrix*/, false /*transpose?*/, g_modelworld4x4;

You might need to drop the ARB from the function names depending on how your function calls are declared.

like image 162
Sir_Lagsalot Avatar answered Oct 13 '22 00:10

Sir_Lagsalot


You cannot call glUniformMatrix4fv the way you wrote it. The function is defined as

void glUniformMatrix4fv(    GLint   location,
GLsizei     count,
GLboolean   transpose,
const GLfloat *     value);

In your case, you must call it with glUniformMatrix4fv (modelw, 1, GL_FALSE, modelworld) which should work (assuming the matrix is stored column-major on the host.) Otherwise, pass GL_TRUE to transpose it on-the-fly.

like image 29
Anteru Avatar answered Oct 13 '22 00:10

Anteru