Skip to main content
GameDev.net gamedev.net
🔒 Locked

GLSL mat4 array issues

Started by elurahu Mar 31, 2011 at 8:22 AM 5 replies 3.1k views
Original Post
elurahu
elurahu
Hey all.

I'm currently trying to upload an array of mat4 to a GLSL shader problem. I'm however having quiet a bit of difficulty finding out what I'm doing wrong (If it's not a driver bug).

Silly test GLSL code:

// Attributes
in vec4 m_kColor;

out vec4 FRAGDATA0;

uniform mat4 akTest[4];

// Shader code
void main()
{
vec4 kTest = m_kColor;
for (int i = 0; i < 4; i++)
{
kTest = akTest * kTest;
}

FRAGDATA0 = kTest;
}


Silly test CPU program:

int loc0 = pkTest->GetUniformLocation("akTest[0]"); // <-- Returns 0
int loc1 = pkTest->GetUniformLocation("akTest[1]"); // <-- Returns 1 (Should be 4)
int loc2 = pkTest->GetUniformLocation("akTest[2]"); // <-- Returns 2 (Should be 8)
int loc3 = pkTest->GetUniformLocation("akTest[3]"); // <-- Returns 3 (Should be 12)


As you can see from the above test code I'm not getting the matrix locations I would expect. Afaik a matrix in a GLSL shader takes up 4 128bit registers. When trying to upload the matrices using glUniformMatrix4fv(m_iLocation, 4, GL_FALSE, akMatrices);
Hodgman
Hodgman
I'm guessing that it's treating it as a vec4 array when doing the array offset calculations (as that's what it will be using internally to store the matrices in). Not sure if that's a bug or not.
If you know that loc1 should be 4 higher than loc0, is there any reason you can't just write that?
e.g. [font="Lucida Console"]int loc1 = loc0 + 4[/font]
[font="Lucida Console"][font="arial, verdana, tahoma, sans-serif"][/font][/font]
Actually, why do you need to know [font="Lucida Console"]loc1/2/3[/font] at all? You're already passing 4 for the count value to glUniformMatrix4fv, so it should be uploading the whole array of 4 matrices.
Bow_vernon
Bow_vernon
I think glGetUniformLocation doesnt return the memory position, it just return the index of the variable, regardless of its size or byte offset from previous variable. Might be good to look up on the spec though...
21st Century Moose
21st Century Moose
Maybe try unrolling the array and loop like so:

// Attributes
in vec4 m_kColor;

out vec4 FRAGDATA0;

uniform mat4 akTest1;
uniform mat4 akTest2;
uniform mat4 akTest3;
uniform mat4 akTest4;
// Shader code
void main()
{
vec4 kTest = m_kColor;

kTest = akTest1 * kTest;
kTest = akTest2 * kTest;
kTest = akTest3 * kTest;
kTest = akTest4 * kTest;

FRAGDATA0 = kTest;
}


then use "int loc0 = pkTest->GetUniformLocation("akTest1");" etc for your uniform locations, and see if that gives anything more like what you expect.
Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls. 
elurahu
elurahu
I have already tried uploading an array of floats using only the first location - Which doesn't work hence me asking

According to the specs the locations should return the register, but I cannot get it working. Running the newest Nvidia drivers.
V-man
V-man
You should just get the location with
[color=#1C2837][size=2][color=#000088]int[color=#000000] loc0 [color=#666600]=[color=#000000] pkTest[color=#666600]->[color=#660066]GetUniformLocation[color=#666600]([color=#008800]"akTest"[color=#666600]);[color=#666600]
[color=#666600]I've done it and it is fine according to the specification. I can upload an array of matrices.
elurahu
elurahu
Really really wierd - I've just tried implementing a simple program here at home and it's just working without issues. However I've spend a few hours at work not getting it to functional. There's definitely something fishy going on!

Anyhow - Thanks all for the input and validation.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.