Yeah, it frustrated me a lot too. It’s because in oF the matrices are defined in row major order instead of column major. I don’t like it much but I’ve learnt to use it.
One trick you could use is to transpose each matrix before the multiplication and then you’ll be able to use it in the M * V * P order but it’s an additional step that’s honestly not worth it.
If you dig in to the source code of ofMatrix4x4 you’ll find this though…
/// oF uses row-vector style by default, meaning that when transforming a vector
/// by multiplying with a matrix, you should put the vector on the left side and
/// the matrix (or matrices) to its right. When multiplying by multiple matrices,
/// the order of application of the transforms is left-to-right. This means that
/// the standard order of manipulation operations is
/// vector * scale * rotate * translate.
/// Note that in GLSL, this convention is reversed, and column-vector style is
/// used. oF uploads the matrices to the GL context correctly, but you should
/// reverse the order of your vertex manipulations to right-to-left style, e.g.
/// translate * rotate * scale * vector.
/// On the application side, oF has operators which let you do matrix-vector
/// multiplication with the vector on the right if that's your preferred style.
/// To set up a combined transformation matrix for working in this style, you
/// should do matrix transformations with the functions like glTranslate,
/// glRotate, and glScale.
/// Although OpenGL uses post-multiplication (vector-on-the-right) with
/// column-major matrix memory layout, oF uses pre-multiplication
/// (vector-on-the-left) with row-major matrix memory layout by default.
/// | | | | |
/// | 0 | 4 | 8 | 12|
/// | 1 | 5 | 9 | 13|
/// | 2 | 6 | 10| 14|
/// | 3 | 7 | 11| 15|
/// | | | | |
/// | 0 | 1 | 2 | 3 |
/// | 4 | 5 | 6 | 7 |
/// | 8 | 9 | 10| 11|
/// | 12| 13| 14| 15|
/// However, the two memory layouts are compatible because of a funny trick.
/// When the ofMatrix4x4 is uploaded into OpenGL's memory, OpenGL treats it
/// like a column-major matrix. The rows of the ofMatrix4x4 are loaded as
/// columns for the GLSL mat4. The result is that the matrix is transposed.
/// This seems like a bug, but it's in fact exactly what we want, because to
/// do the transition from pre-multiplication to post-multiplication style,
/// we need to perform the very same transpose.
/// By using pre-multiplication, oF treats vectors as 1x4 matrices, since
/// that provides a valid 1x4 * 4x4 operation. When moving to
/// post-multiplication, OpenGL is treating vectors like columns,
/// providing a similarly valid 4x4 * 4x1 operation. This means that the
/// resulting vector in OGL-land is the transpose of the result when
/// done in oF-land.
/// Recall that in matrix multiplication,
/// (V * M * S)^T = (S^T) * (M^T) * (V^T)
/// What this means is that to convert from pre-multiplication to
/// post-multiplication, we need to transpose our matrices (and vectors)
/// and reverse the order of multiplication. You're already reversing
/// the order of multiplication by writing your shaders with the vector
/// on the right, and the implicit transpose that happens when your matrix
/// is uploaded to GL memory accomplishes the transposition for free!
/// For more information on this subject, check out
/// [this post](http://seanmiddleditch.com/matrices-handedness-pre-and-post-multiplication-row-vs-column-major-and-notations/).