how to specify a matrix vertex attribute

According to GLSL specifications (http://www.opengl.org/registry/doc/G...ull.1.20.8.pdf) page 23 "The attribute qualifier can be used only with float, floating-point vectors, and matrices" but the glVertexAttribPointer specification (http://www.opengl.org/sdk/docs/man/x...ribPointer.xml) states that the maximum value that the "size" parameter can get is 4, meanwhile we would need 16 to fill up a whole mat4. Am I missing something? How can I use a vertex attribute of type mat4?

Thanks,

mic

Re: how to specify a matrix vertex attribute

You can store each row or column in a separate vertex attribute...

Do you mind me asking what it is your trying to do?

N.

Re: how to specify a matrix vertex attribute

attribute vec4 MyMat0,MyMat1,MyMat2,MyMat3;

If you stored the above attributes as transposed (row-major), multiplication of a vector with this "matrix" will be:

vec4 res; // result

res.x = dot(gl_Vertex,MyMat0);

res.y = dot(gl_Vertex,MyMat1);

res.z = dot(gl_Vertex,MyMat2);

res.w = dot(gl_Vertex,MyMat3);

if I remember correctly.

I've just been reading the ATi R500 full hardware whitepaper (http://www.x.org/docs/AMD/) and there's no way to directly specify a matrix as an attribute on their Shader3 gpus.

P.S when you specify

attribute mat4 MyMat; , it probably automatically generates 4 vertex attributes (vec4 each), with consecutive Index.

So, you'll use this to set matrices:

glVertexAttribPointer(MyMatID+0, ....);

glVertexAttribPointer(MyMatID+1, ....);

glVertexAttribPointer(MyMatID+2, ....);

glVertexAttribPointer(MyMatID+3, ....);

I've only verified this with looking at the assembly code, generated by the compiler.

Re: how to specify a matrix vertex attribute

This works for me:

Code :

glEnableVertexAttribArray(attribloc);
glEnableVertexAttribArray(attribloc + 1);
glEnableVertexAttribArray(attribloc + 2);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(attribloc, 3, GL_FLOAT, 0, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glVertexAttribPointer(attribloc + 1, 3, GL_FLOAT, 0, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
glVertexAttribPointer(attribloc + 2, 3, GL_FLOAT, 0, 0, NULL);
...

Where attribloc refers to an attribute in the shader like this:

Re: how to specify a matrix vertex attribute

Thank you guys I know that I can "emulate" a matrix just sending four vectors, what I am trying to understand is: what is the "official way" of doing it given the fact that according to the documentation there should be a way to do it.

Mine is actually more and intellectual challenge than a real need, but since I am writing some wrapper functions around GLSL I would like to know how to deal, in a clean way, with this feature.

I tryed to put the whole matrix as a vertex attribute giving 4 GL_FLOAT components to glVertexAttribPointer but if for example I read the first column of the matrix from the vertex shader, (using nVidia 8600GT) I get the first row of the first matrix when processing the first vertex, the second row of the first matrix when processing the second vertex and so on. I know I probably did't explain in the best way...

But the interesting thing is that the matrix attribute eats up 4 indices! If anyone knows a possible usage of this feature I would like to hear it, otherwise I will probably just skip the support for it.

Cheers,

mic

Re: how to specify a matrix vertex attribute

Thank you HexCat,

it actually turned out also for me that you have to specify each column of the matrix on a different vertex attribute, which as you showed are allocated consecutively, finally everything is clear!

... now we just have to invent a useful way to use this feature :)

Re: how to specify a matrix vertex attribute

Personally, I use this feature to consolidate three vertex attributes (Tangent, Bitangent, and gl_Normal) into one mat3 attribute for transforming normal map normals into eye space for reflective bumpmapping. ;)

Re: how to specify a matrix vertex attribute

Thank you very much HexCat, this usage is a text-book level one! this moves this feature from my "almost deprecated wish list" to the "must have features list" :)

Re: how to specify a matrix vertex attribute

Quote:

Thank you guys I know that I can "emulate" a matrix just sending four vectors, what I am trying to understand is: what is the "official way" of doing it given the fact that according to the documentation there should be a way to do it.

This *is* the official way to do it. An attribute in OpenGL is defined as a vector, not a matrix. So the only way to actually send a matrix attribute is to send it as multiple vectors.

Quote:

But the interesting thing is that the matrix attribute eats up 4 indices!

Yes, it does.

Re: how to specify a matrix vertex attribute

Got it,

maybe is useful to recap then, taking Ilian example, he wasn't sure about it but it seems that we can "officialize" it:

attribute mat4 MyMat;

generates 4 vertex attributes (vec4 each), with consecutive indices: this is why a mat4 eats up 4 indices. Infact if you try to bind a matrix to index 14 for example, the GLSL linker it will give you an error if your GLSL implemententation supports maximum 16 indices like on my Geforce 8600 GT.

// sends the matrix:

glVertexAttribPointer(MyMatID+0, ....); // column 0

glVertexAttribPointer(MyMatID+1, ....); // column 1

glVertexAttribPointer(MyMatID+2, ....); // column 2

glVertexAttribPointer(MyMatID+3, ....); // column 3

thanks again to every one :)

mic