title: 4x4 Matrix Pre-multiplication vs Post-multiplication
body: <p>I have the following functions:</p>
  
  <pre><code>void Matrix::Scale(const float xScale, const float yScale, const float zScale)
  {
      Matrix scaleMatrix;
      scaleMatrix.m_data[M11] = xScale;
      scaleMatrix.m_data[M22] = yScale;
      scaleMatrix.m_data[M33] = zScale;
      *this *= scaleMatrix;
  }
  
  void Matrix::Translate(const float xTranslation, const float yTranslation, const float zTranslation)
  {
      Matrix translationMatrix;
      translationMatrix.m_data[M14] = xTranslation;
      translationMatrix.m_data[M24] = yTranslation;
      translationMatrix.m_data[M34] = zTranslation;
      *this *= translationMatrix;
  }
  </code></pre>
  
  <p>And I'm unsure about the last lines of both functions. Should I be doing pre-multiplication, or post-multiplication (i.e. what I'm doing now). What implications does it have for the use of this class? I'm using the class with OpenGL, so any similarities to that would probably be useful.</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>My shader code looks like this:</p>
  
  <pre><code>void main()
  {
      gl_Position = vec4(v_xy, 0.0, 1.0) * v_ModelMatrix * v_ViewMatrix * v_ProjectionMatrix;
      f_uv = v_uv;
  }
  </code></pre>
  
  <p>My matrix multiplication function looks like this:</p>
  
  <pre><code>// Row 1
  result[M11] = lhs[M11] * rhs[M11]   +   lhs[M12] * rhs[M21]   +   lhs[M13] * rhs[M31]   +   lhs[M14] * rhs[M41];    // Column 1
  result[M12] = lhs[M11] * rhs[M12]   +   lhs[M12] * rhs[M22]   +   lhs[M13] * rhs[M32]   +   lhs[M14] * rhs[M42];    // Column 2
  result[M13] = lhs[M11] * rhs[M13]   +   lhs[M12] * rhs[M23]   +   lhs[M13] * rhs[M33]   +   lhs[M14] * rhs[M43];    // Column 3
  result[M14] = lhs[M11] * rhs[M14]   +   lhs[M12] * rhs[M24]   +   lhs[M13] * rhs[M34]   +   lhs[M14] * rhs[M44];    // Column 4
  
  // Row 2
  result[M21] = lhs[M21] * rhs[M11]   +   lhs[M22] * rhs[M21]   +   lhs[M23] * rhs[M31]   +   lhs[M24] * rhs[M41];    // Column 1
  result[M22] = lhs[M21] * rhs[M12]   +   lhs[M22] * rhs[M22]   +   lhs[M23] * rhs[M32]   +   lhs[M24] * rhs[M42];    // Column 2
  result[M23] = lhs[M21] * rhs[M13]   +   lhs[M22] * rhs[M23]   +   lhs[M23] * rhs[M33]   +   lhs[M24] * rhs[M43];    // Column 3
  result[M24] = lhs[M21] * rhs[M14]   +   lhs[M22] * rhs[M24]   +   lhs[M23] * rhs[M34]   +   lhs[M24] * rhs[M44];    // Column 4
  
  // Row 3
  result[M31] = lhs[M31] * rhs[M11]   +   lhs[M32] * rhs[M21]   +   lhs[M33] * rhs[M31]   +   lhs[M34] * rhs[M41];    // Column 1
  result[M32] = lhs[M31] * rhs[M12]   +   lhs[M32] * rhs[M22]   +   lhs[M33] * rhs[M32]   +   lhs[M34] * rhs[M42];    // Column 2
  result[M33] = lhs[M31] * rhs[M13]   +   lhs[M32] * rhs[M23]   +   lhs[M33] * rhs[M33]   +   lhs[M34] * rhs[M43];    // Column 3
  result[M34] = lhs[M31] * rhs[M14]   +   lhs[M32] * rhs[M24]   +   lhs[M33] * rhs[M34]   +   lhs[M34] * rhs[M44];    // Column 4
  
  // Row 4
  result[M41] = lhs[M41] * rhs[M11]   +   lhs[M42] * rhs[M21]   +   lhs[M43] * rhs[M31]   +   lhs[M44] * rhs[M41];    // Column 1
  result[M42] = lhs[M41] * rhs[M12]   +   lhs[M42] * rhs[M22]   +   lhs[M43] * rhs[M32]   +   lhs[M44] * rhs[M42];    // Column 2
  result[M43] = lhs[M41] * rhs[M13]   +   lhs[M42] * rhs[M23]   +   lhs[M43] * rhs[M33]   +   lhs[M44] * rhs[M43];    // Column 3
  result[M44] = lhs[M41] * rhs[M14]   +   lhs[M42] * rhs[M24]   +   lhs[M43] * rhs[M34]   +   lhs[M44] * rhs[M44];    // Column 4
  </code></pre>
  
  <p>I was under the impression that if you post-multiply your matrices (i.e. <code>viewMatrix = transform * viewMatrix;</code>) then your shader code needs to apply MVP in the opposite order that I currently have?</p>
  
  <p><strong>Edit2:</strong></p>
  
  <p>The summary table on <a href="http://scratchapixel.com/lessons/3d-basic-lessons/lesson-4-geometry/conventions-again-row-major-vs-column-major-vector/" rel="noreferrer">http://scratchapixel.com/lessons/3d-basic-lessons/lesson-4-geometry/conventions-again-row-major-vs-column-major-vector/</a> is confusing me, as I'm using post-multiply with OpenGL (indicating column-major), yet my matrix is laid out in memory as row-major?</p>