How to specify a matrix vertex attribute

According to GLSL specifications (http://www.opengl.org/registry/doc/GLSLangSpec.Full.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/xhtml/glVertexAttribPointer.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

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.

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.

This works for me:

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:

attribute mat3 mymatrix;

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

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 :slight_smile:

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. :wink:

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” :slight_smile:

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.

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

Yes, it does.

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 :slight_smile:
mic

Would you mind sharing how you’re setting up your vertex attribute pointers? I’m attempting and this isn’t working for me. For example, I’m using:

glVertexAttribPointer(MyMatID+0,  4, GL_FLOAT, GL_FALSE, 0, NULL);
glVertexAttribPointer(MyMatID+1,  4, GL_FLOAT, GL_FALSE, 0, NULL);
glVertexAttribPointer(MyMatID+2,  4, GL_FLOAT, GL_FALSE, 0, NULL);
glVertexAttribPointer(MyMatID+3,  4, GL_FLOAT, GL_FALSE, 0, NULL);

but I’m not sure whether the stride and offset are correct.

Also, do those 4 attribute locations represent the rows or the columns of the matrix?

Of course that it doesn’t work. Do you know the meaning of the last two parameters? If you are referring to the same VBO, offsets cannot be 0 for all attributes, as well as stride.

  1. Look at the specification of the glVertexAttribPointer function.
  2. Never revive such old posts! This is almost 5 years old post, and there is no purpose asking OP anything now.

Request for the administrator (web master): Is it possible to automatically lock threads after 6 months of inactivity?

Agreed! Suggested that recently at the bottom of the OpenGL forum upgrade thread. Might follow up there or PM Khronos_webmaster to request this.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.