Hi,

I’ve just started getting back into OpenGL and have started to write some matrix functions. I decided to separate out the 4x4 matrix into a 3x3 matrix for rotation and scale and use a 3 vector for the translation. Now, I worked out the proof that I needed to compose this into a 4x4 matrix.

Given that a 4x4 matrix is composed thus:

```
|M|T|
M1 = -----
|0|1|
```

Where M1 is a 3x3 matrix and T is a column vector representing the translation.

This is the formula for multiplying 2 4x4 matrices:

```
|m0 m4 m8 m12| |t0 t4 t8 t12|
M = |m1 m5 m9 m13| T = |t1 t5 t9 t13|
|m2 m6 m10 m14| |t2 t6 t10 t14|
|m3 m7 m11 m15| |t3 t7 t11 t15|
|(m0t0 + m4t1 + m8t2 + m12t3) (m0t4 + m4t5 + m8t6 + m12t7) (m0t8 + m4t9 + m8t10 + m12t11) (m0t12 + m4t13 + m8t14 + m12t15)|
MT = |(m1t0 + m5t1 + m9t2 + m13t3) (m1t4 + m5t5 + m9t6 + m13t7) (m1t8 + m5t9 + m9t10 + m13t11) (m1t12 + m5t13 + m9t14 + m13t15)|
|(m2t0 + m6t1 + m10t2 + m14t3) (m2t4 + m6t5 + m10t6 + m14t7) (m2t8 + m6t9 + m10t10 + m14t11) (m2t12 + m6t13 + m10t14 + m14t15)|
|(m3t0 + m7t1 + m11t2 + m15t3) (m3t4 + m7t5 + m11t6 + m15t7) (m3t8 + m7t9 + m11t10 + m15t11) (m3t12 + m7t13 + m11t14 + m15t15)|
```

So, substituting:

```
Proof 1:
|m0 m4 m8 0| |1 0 0 t0|
|m1 m5 m9 0| * |0 1 0 t1| =
|m2 m6 m10 0| |0 0 1 t2|
|0 0 0 1| |0 0 0 1 |
|(m0(1) + m4(0) + m8(0) + (0)(0)) (m0(0) + m4(1) + m8(0) + (0)(0)) (m0(0) + m4(0) + m8(1) + (0)(0)) (m0t0 + m4t1 + m8t2 + (0)(0))|
|(m1(1) + m5(0) + m9(0) + (0)(0)) (m1(0) + m5(1) + m9(0) + (0)(0)) (m1(0) + m5(0) + m9(1) + (0)(0)) (m1t0 + m5t1 + m9t2 + (0)(0))| =
|(m2(1) + m6(0) + m10(0) + (0)(0)) (m2(0) + m6(1) + m10(0) + (0)(0)) (m2(0) + m6(0) + m10(1) + (0)(0)) (m2t0 + m6t1 + m10t2 + (0)(0))|
|((0)(1) + (0)(0) + (0)(0) + (1)(0)) ((0)(0) + (0)(1) + (0)(0) + (1)(0)) ((0)(0) + (0)(0) + (0)(1) + (1)(0)) ((0)t0 + (0)t1 + (0)t2 + (1)(1))|
|(m0) (m4) (m8 ) (m0t0 + m4t1 + m8t2 )|
|(m1) (m5) (m9 ) (m1t0 + m5t1 + m9t2 )|
|(m2) (m6) (m10) (m2t0 + m6t1 + m10t2)|
|(0 ) (0 ) (0 ) (1 )|
```

And, now if I multiply a 3x3 matrix with a 3 vector:

```
Proof 2:
|m0 m4 m8 | |t0|
|m1 m5 m9 | * |t1| =
|m2 m6 m10| |t2|
|m0t0 + m4t1 + m8t2 |
|m1t0 + m5t1 + m9t2 |
|m2t0 + m6t1 + m10t2|
```

So, proof 2 is the same as the translation part of the matrix in proof 1, hence to compose a 4x4 matrix from a 3x3 and a vector, the final formula is:

```
|M|MT|
M2 = ------
|0|1 |
```

Now, from my code, this doesn’t quite work out. Yet, if I don’t multiply the translation by the 3x3 matrix when I compose the 4x4, everything is fine, yet I don’t quite understand why this works?

I have seen a post on here that noted that M1 is equal to a rotation followed by a translation, and M2 is the opposite. But, surely if this were correct, M2 would work as expected, yet it doesn’t; it’s almost as though the triangle I’m rotating is being sheared.

Can somebody shed some light on this problem?

Thanks,

Luke.