title: OpenTK matrix transformations
body: <p>Here's the vertex shader:</p>
  
  <pre><code>uniform mat4 projection;
  uniform mat4 view;
  uniform mat4 model;
  
  void main(void)
  {
      gl_Position = projection * view * model * gl_Vertex;
      gl_TexCoord[0] = gl_MultiTexCoord0;
  }
  </code></pre>
  
  <p>My understanding is that using various transformations, the model space is eventually turned to clip space, which is a box bound by each unit in each axis drawn directly to the viewport, i.e. something at (-1, 1,0) is at the top left of the viewport. When I remove all matrix transforms from the shader,</p>
  
  <pre><code>gl_Position = gl_Vertex;
  </code></pre>
  
  <p>and pass in, as the model, a simple quad</p>
  
  <pre><code>public Vector3[] verts = new Vector3[] {
      new Vector3(-1f, -1f, 0),
      new Vector3(1f, -1f, 0),
      new Vector3(1f, 1f, 0),
      new Vector3(-1f, 1f, 0),
  };
  
  public Vector2[] coords = new Vector2[] {
      new Vector2(0, 1f),
      new Vector2(1f, 1f),
      new Vector2(1f, 0f),
      new Vector2(0f, 0f),
  };
  
  public uint[] indices = new uint[] {
      0,1,2,
      0,2,3,
  };
  </code></pre>
  
  <p>I get the expected full screen image. When I apply the transformations, the image appears as
  a small square in the centre of the screen, as you'd expect. The problem arises when I try to calculate the position of a vertex of the model in clip coordinates on the CPU:</p>
  
  <pre><code>public Vector4 testMult(Vector4 v, Matrix4 m)
  {
      return new Vector4(
          m.M11 * v.X + m.M12 * v.Y + m.M13 * v.Z + m.M14 * v.W,
          m.M21 * v.X + m.M22 * v.Y + m.M23 * v.Z + m.M24 * v.W,
          m.M31 * v.X + m.M32 * v.Y + m.M33 * v.Z + m.M34 * v.W,
          m.M41 * v.X + m.M42 * v.Y + m.M43 * v.Z + m.M44 * v.W);
  }
  
  Matrix4 test = (GlobalDrawer.projectionMatrix * GlobalDrawer.viewMatrix) * modelMatrix;
  
  Vector4 testv = (new Vector4(1f, 1f, 0, 1));
  Console.WriteLine("Test Input: " + testv);
  Console.WriteLine("Test Output: " + Vector4.Transform(testv, test));
  Vector4 testv2 = testMult(testv, test);
  Console.WriteLine("Test Output: " + testv2);
  Console.WriteLine("Test Output division: " + testv2 / testv2.W);
  </code></pre>
  
  <p>(The matrices passed in are identical to the ones passed to the shader)</p>
  
  <p>The program then proceeds to give output outside of clip space, and the division by W leads to divisions by 0:</p>
  
  <pre><code>Test Input: (1, 1, 0, 1)
  Test Output: (0.9053301, 1.207107, -2.031746, 0)
  Test Output: (0.9053301, 1.207107, -1, 0)
  Test Output division: (Infinity, Infinity, -Infinity, NaN)
  </code></pre>
  
  <p>The matrices are created as follows:</p>
  
  <pre><code>projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, window.Width / (float)window.Height, 1.0f, 64.0f);
  projectionMatrix =
  (1.81066, 0, 0, 0)
  (0, 2.414213, 0, 0)
  (0, 0, -1.031746, -1)
  (0, 0, -2.031746, 0)
  
  viewMatrix = Matrix4.LookAt(new Vector3(0,0,4), -Vector3.UnitZ, Vector3.UnitY);
  viewMatrix = 
  (1, 0, 0, 0)
  (0, 1, 0, 0)
  (0, 0, 1, 0)
  (0, 0, -4, 1)
  
  modelMatrix = 
  (0.5, 0  , 0  , 0)
  (0  , 0.5, 0  , 0)
  (0  , 0  , 1  , 0)
  (0  , 0  , 0  , 1)
  </code></pre>
  
  <p>So, the question is why; what am I doing wrong?</p>