Send an array of matrices using uniforms

Started by taquionm, February 27, 2016, 20:24:00

Previous topic - Next topic

taquionm

I'm currently using LWJGL 3 (3.0.0b) and trying to send an array of matrices using uniforms in a vertex shader.

I've been struggiling with the shader and finally discovered that the values of the array of matrices are not received ok at the shader. I ended sending an array of identity matrices and the values I get are not ok. I'm using also JOML and had no problem in sending single matrices. The problem is with array of matrices.

If the matrix is called, let's say, "arrMatr", I basically create a uniform for each row with the names "arrMatr", "arrMatr[1]" and so on.

Later on I set the values for each row, using the method:

glUniformMatrix4fv(location, false, fb);


Where "location" is the location of each row and "fb" is a FloatBuffer that has the values of each matrix.

Could you provide any clues on what I'm doing wrong ? Could you someone post a snipet about creating and setting an array of matrices ?

Thanks in advance.

Kai

You can declare a uniform mat4 array in the shader like so:
uniform mat4 arrMatr[64];

lookup its single location once using:
int arrMatrLocation = glGetUniformLocation(program, "arrMatr");

and send a sequence of matrices to that uniform with:
FloatBuffer fb = BufferUtils.createFloatBuffer(16 * 64);
Matrix4f[] matrices = new Matrix4f[64];
// ... instantiate and fill the matrices with sane values
for (int i = 0; i < matrices.length; i++) {
  matrices[i].get(16*i, fb);
}
glUniformMatrix4fv(arrMatrLocation, false, fb);

taquionm

Many thanks,

I guess then that creating separate uniforms for each matrix row is not needed. Instead I should just create a uniofrm for thw whole matrix array:

glGetUniformLocation(program,  "arrMatr");


Am I rigght ?

I will try to create a simple demo to test this. In order to check if this is working for me or If I have additional problems.

Many thanks again.

Kai

Yes. You only need one single mat4[] uniform declaration in your shader. Not multiple.

However, your wording of "each matrix row" irritates me a bit. :)
Indexing into an array of type mat4[] will give you a single mat4 matrix at that index, not some row of some matrix.
When you then index into a single mat4, also using the [] operator, in the shader it would give you a _column_ of the matrix and not a row - where a row vector 'w' together with a 4-component vector 'v' would form the dot product dot(w, v) when post/right-multiplying 'v' against the matrix.

If you wanted, you could also query the location of a single specific matrix in that uniform mat4[] array by using the following syntax in glGetUniformLocation:
int locationOfFirstMatrix = glGetUniformLocation(program, "arrMatr[0]");
int locationOfSecondMatrix = glGetUniformLocation(program, "arrMatr[1]");
...
int locationOfSixtyfourthMatrix = glGetUniformLocation(program, "arrMatr[63]");

The obtained locations will be sequential and without gaps, and you can use them to upload each matrix individually.
So when the first matrix with index 0 gets location 7 then the matrix with index 5 will have location 7+5.
This means that once you queried the location of the first matrix in that array, by either doing glGetUniformLocation(program, "arrMatr[0]") or equally glGetUniformLocation(program, "arrMatr"), you can just add to that location the index of the matrix you want to change/upload in glUniformMatrix4fv().

taquionm

Ok, no need to irritate  ;). I just meant array row, not matrix row. Sorry for the missunderstanding.

With your solution it seems that values get ok to the shader. I've created a simple example that uses the values of the array of matrices to set the colour of a triangle and everything is correct.

So, question solved ! Many thanks. My sample is still not working but now it's not because the array of matrices has incorrect values. :P.

Many thanks.