Matrix Shenanigans

Ok, so the vertex v’ that is passed into the clip matrix is given by…

v’=PMv

…where v is the current vertex, P is the projection matrix and M is the modelview matrix. Correct?

Now assume that we perform some transformations on the modelview matrix, as we often do, then the transformation becomes:

v’=P(MAB)v

…where A and B are the transformation matrices we multiply by. Now if the modelview matrix originates in identity form, then the transformation is:

v’=P(IAB)v=P(AB)v

…but what if we want to move the transformations A and B into the projection matrix? If we say that they are being applied to the projection matrix, we can say this:

v’=PMv=P(MAB)v=P(IAB)v=P(AB)v=P(AB)Iv=(PAB)Iv

[For the last 2 expressions, assume we simply keep the modelview matrix in identity form (hence the new I that appears), now the transformations apply directly to the projection matrix.]

So instead of:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glDoOtherMatrixStuffARB();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixd(MatrixA);
glMultMatrixd(MatrixB);

We do:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glDoOtherMatrixStuffARB();
glMultMatrixd(MatrixA);
glMultMatrixd(MatrixB);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

The math seems to work out, but the results are very different! Why is this?

In what way are the results different?

Matrix multiplication is not commutative, meaning that the order the multiplications are applied changes the result.

look at the difference between PAB and P(AB).

In the latter, A is multiplied by B, then P is multiplied by that result. In the former, P is multiplied by A and the reult is multiplied by B.

Matrix multiplication is not commutative but I do believe it is associative, which is what you are talking about.

Commutative: AB = BA
Associative: ABC = (AB)C = A(BC)

This is why you can translate and then rotate, or translate and rotate in the same transformation and end up with the same result.

I looked that up, and you are correct. In that case, I am not sure why it doesnt work. I will be interested to find out if someone else can explain it.

Just a guess (without looking stuff up)
Try:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMultMatrixd(MatrixA);
glMultMatrixd(MatrixB);
glDoOtherMatrixStuffARB();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Doesn’t anyone know the answer? I would like to know.

I remember in some previous posts that doing stuff in the projection matrix that are normally intended for the modelview matrix messes up some lighting and fog calculations. Don’t know if this is correct though.

See “8.030 Where should my camera go, the ModelView or projection matrix?” of http://www.opengl.org/resources/faq/technical/index.html.
Lighting calculation of P(AB) is different from that of (PAB)I. I think this is a reason that the scene result is different.

The lighting was not different. What was different was that objects were appearing completely different sizes.

I replaced the modelview matrix with a matrix that gave me billboard effects, but I thought that would better go on the projection matrix, and I just wanted to see if it would work for kicks.

So I replaced the modelview matrix by the identity matrix and simply multiplied the projection matrix by the billboard matrix, that WOULD have been the modelview matrix.

The rendered objects were fine if I did it with the modelview matrix, but when I did the projection matrix trick they came out much smaller and would shrink excessively with depth.

I’ve moved on from that problem though. If my billboard effects require the modelview matrix, who cares, I do my own lighting anyway.

The only differences are in the calculations that depend on the modelview matrix alone, of which moucard pointed out a couple. If you are seeing geometric differences, it’s because you have produced them in your matrix setup, not because the combination is somehow different - it’s not.

(P V) M = P (V M) = (P V M) I

This is true mathematically, and in the gl. The gl separates these matrices for our benefit, for convenience.