Row major vs Column Major in 4.1

So I’ve recently gotten my basic camera functionality working to the point where I can declare a camera as a matrix, and have GL show me the scene from that camera’s point of view.

My matrices are declared as GLfloat[16], with the translation elements in 12, 13, & 14, counting from 0 (indexing C array style).

Originally, I was using glPosition=myvertexviewprojection, but I had to either use the transpose of the view matrix, or reverse the order of multiplications to make the camera move and rotate properly (about it’s own origin).

My question is whether there’s a “natural” matrix order for GL4.1, or does it matter?

By a natural matrix order, I mean whether there’s a preference for row major or column major matrices implied by the API?

My matrices are declared as GLfloat[16], with the translation elements in 12, 13, & 14

But that doesn’t say whether it’s row-major or column-major. Is every 4 elements a column of the matrix or a row?

See, all column-major and row-major do is define how a matrix is encoded as an array of floats. It tells whether each 4 elements is a row or a column of the matrix.

So the question you need to ask yourself is whether you intend for your last 4 elements to be the last column of the matrix or the last row of the matrix.

The mathematical convention is, and always has been, that the columns of a transformation matrix represent the axis vectors and origin point of the coordinate system. If you are using the standard mathematical convention, then the matrices as you have defined them should be column-major. But that also means that your vector/matrix multiplication is backwards.

If you are using the standard math conventions, then you multiply vectors on the right. The space ordering goes right-to-left.

Now for some reason, various graphics developers decided to invert the conventions mathematicians have been using for decades. This means that the rows of the matrix represent the axis vectors and origin point. This is what has given rise to so much shader code using left-multiplication, as yours does.

And that’s the reason you needed to transpose your matrices.

BTW: right-multiplication may also be faster than left-multiplication for vectors. A mat4vec4 means just doing four MAD operations; they may even be FMA operations for increased precision. A vec4mat4 means doing 4 dot-products. This requires a lot of cross-addition, which may not be the fastest thing ever these days. At the very least, right-multiplcation will be no slower. And since it may be a good deal faster, it’s best to stick with the mathematicians.

Hi Alfonse,

Many thanks for the reply.

Not entirely sure I followed you (or maybe I got my first post mixed up or explained badly).

My array is filled out as follows, where Xx is X axis.x component:

Xx, Xy, Xz, 0.0, Yx, Yy, Yz, 0.0, Zx, Zy, Zz, 0.0, Tx, Ty, Tz, 1.0

(The last four floats are the last column)

So I think I’m following the mathematical convention, and yes, indeed my multiplication is backwards, in that the vector in my current, working shader, is last in the expression, ie:

glPosition = projection * view * myvertex

  • which is right-multiplication, correct?
  • and which is potentially faster (and at worst no slower) than left-multiplication, correct?

PS - as far as I remember, I’m NOT transposing any of my matrices in the call to glUniformMatrix…

It doesn’t matter.

Column-major versus row-major is purely a notational convention. Note that post-multiplying with column-major matrices produces the same result as pre-multiplying with row-major matrices. The OpenGL Specification and the OpenGL Reference Manual both use column-major notation. You can use any notation, as long as it’s clearly stated.

Sadly, the use of column-major format in the spec and blue book has resulted in endless confusion in the OpenGL programming community.

To be honest, sweating over the performance of matrix multiplication is optimizing something that isn’t even a bottleneck. You will be doing very few of these per-frame in your program (unless you’ve screwed things up royally) so you’re better off putting in the effort where you’ll actually get some measurable gain.

I was actually concerned about writing the code in such a way that I didn’t have to go back later and try and track down odd errors in places where I need to insert a transpose, or do my math “backwards”.

Added to this was the concern that I might be doing my math “the wrong way”, given that most of the shaders I’ve seen, as Alfonse pointed out, use left-multiplication.

As far as doing very few of these goes, it’s probably true as far as calculations for “modelview” matrices go. However doesn’t most perpixel lighting involve a matrix calculation of some sort? If so, I would have thought that it would be worth optimising that, and if you get your matrices right in the first place (and for little effort), then you can avoid having to transpose them in a shader.

Mmmm, I think your head might still be in CPU-land for this one. By the time the GPU actually does a matrix multiply all of the necessary data has already been moved into hardware registers and the multiplication itself occurs entirely in hardware.

Understand also that GPU hardware has been developed and optimized for this kind of operation for over 10 years now; hardware T&L is a commodity mass-market feature. This is an already solved problem and if it actually was an issue worth worrying about then it would have been addressed ages ago.

Rules and concepts that apply in software-land have limited applicability when you move into hardware land, and you frequently find that the way you do or understand things in each contradicts the way you would do things in the other.

So just use whichever order suits your program here, and trust the hardware to do the right thing.