title: How do you calculate the transformation matrix for a camera?
body: <p>I have a camera with the position, forward, right, and down vectors defined as class members <code>_position</code>, <code>_forward</code>, <code>_right</code>, and <code>_down</code>. For the rotation part of the problem, I simply load the rows of the destination coordinate system (view space) with <code>_forward</code>, <code>_right</code>, and <code>_down</code> and then apply a rotation matrix to go into "OpenGL" view space.</p>
  
  <p>Before that I translate by the negative of <code>_position</code>. Is this correct, or do I need to do more math to determine the actual translation to pre- or post- multiply by my rotation?</p>
  
  <p>Below is the code I have that doesn't seem to work. Specifically, I am rendering an object (a small quad facing down the z-axis) at the origin of world space and when I run the program that object appears distorted. (Note that the mat4 constructor takes elements in ROW major order though it stores them in column major internally).</p>
  
  <pre><code>mat4 Camera::matrix() const
  {
      return
          mat4(
              0.0f, 0.0f, -1.0f, 0.0f,
              1.0f, 0.0f, 0.0f, 0.0f,
              0.0f, -1.0f, 0.0f, 0.0f,
              0.0f, 0.0f, 0.0f, 1.0f) *
          mat4(
              _forward.x, _forward.y, _forward.z, 0.0f,
              _right.x, _right.y, _right.z, 0.0f,
              _down.x, _down.y, _down.z, 0.0f,
              0.0f, 0.0f, 0.0f, 1.0f) *
          translate(
              -_position.x,
              -_position.y,
              -_position.z
          );
  }
  </code></pre>
  
  <p>Here is the code for the look at function that is being used before the above.</p>
  
  <pre><code>void Camera::look_at(const vec3&amp; position, const vec3&amp; point)
  {
      _position = position;
      _forward = normalize(point - position);
      _right = cross(_forward, vec3(0.0f, 1.0f, 0.0f));
      _down = cross(_forward, _right);
  }
  </code></pre>
  
  <p>In my initialization, I use this code:</p>
  
  <pre><code>camera.look_at(vec3(1.0f, 1.0f, 1.0f), vec3(0.0f, 0.0f, 0.0f));
  view = camera.matrix();
  proj = perspective(60.0f, SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.001f, 100.0f);
  view_proj = proj * view;
  </code></pre>