title: Why does this Perspective Projection Matrix Calculation not give the correct result?
body: <p>I can't quite figure this out.
  I've got an OpenGL application I'm converting from the old fixed function pipeline to the programmable pipeline, and getting rid of the deprecated functions I've been using...
  I'm not the best when it comes to math, and matrixes are fairly new to me.</p>
  
  <p>However, I've gotten my ModelView matrix working okay, but I can't seem to get the Perspective matrix working right.</p>
  
  <p>By which, I mean, I can use the fixed function deprecated functions, get the value of the matrix, and match it to the calculated values I've generated... ModelView? No problem. Perspective? It doesn't match, and I don't understand why.</p>
  
  <p>The two methods can be toggled between by commenting out the preprocessor #define USEPROJMATRIX</p>
  
  <pre><code>
  typedef float vec_t;
  
  const static vec_t identityMatrix[16] = { 1.0, 0.0, 0.0, 0.0, 
                                            0.0, 1.0, 0.0, 0.0, 
                                            0.0, 0.0, 1.0, 0.0, 
                                            0.0, 0.0, 0.0, 1.0 };
  
  const static vec_t zeroMatrix[16] = { 0.0, 0.0, 0.0, 0.0,
                                        0.0, 0.0, 0.0, 0.0,
                                        0.0, 0.0, 0.0, 0.0,
                                        0.0, 0.0, 0.0, 0.0 };
  
  const double pi = 3.1415926535897932384626433832795;
  
  float Utils::Radians(const float& degrees)
  {
      return degrees * (pi / 180);
  }
  
  vec_t* Utils::FrustumMatrix(vec_t* out_matrix, const vec_t& left, const vec_t& right, const vec_t& bottom, const vec_t& top, const vec_t& znear, const vec_t& zfar) // Replaced glFrustum()
  {
      memcpy(out_matrix, zeroMatrix, 16*sizeof(vec_t));
  
      out_matrix[0] = (2.0 * znear) / (right - left);
      out_matrix[5] = (2.0 * znear) / (top - bottom);
      out_matrix[8] = (right + left) / (right - left);
      out_matrix[9] = (top + bottom) / (top - bottom);
      out_matrix[10] = -((zfar + znear) / (zfar - znear));
      out_matrix[11] = -1.0;
      out_matrix[14] = -((2.0 * zfar * znear) / (zfar - znear));
  
      return out_matrix;
  }
  
  vec_t* Utils::PerspectiveMatrix(vec_t* out_matrix, const vec_t& yFOVDegrees, const vec_t& aspectRatio, const vec_t& znear, const vec_t& zfar) // Replaces gluPerspective()
  {
      vec_t range, left, right, bottom, top;
  
      range = tan(Radians(yFOVDegrees / 2)) * znear;
      left = -range * aspectRatio;
      right = range * aspectRatio;
      bottom = -range;
      top = range;
  
      return FrustumMatrix(out_matrix, left, right, bottom, top, znear, zfar);
  }
  
  #define USEPROJMATRIX
  void GameLogic::OnResize(int width = 640, int height = 480)
  {
      glViewport(0, 0, width, height);
      glMatrixMode(GL_PROJECTION);
  #ifndef USEPROJMATRIX
      glLoadMatrixf(identityMatrix);
      gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 1000.0f);
  #else
      vec_t pMatrix[16];
      memcpy(pMatrix, identityMatrix, sizeof(vec_t) * 16);
      Utils::PerspectiveMatrix(pMatrix, 45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 1000.0f);
      glLoadMatrixf(pMatrix);
  #endif
  
      vec_t projectionmatrix[16];
      glGetFloatv(GL_PROJECTION_MATRIX, projectionmatrix);
  
      /* Matrix calculation results in projectionmatrix equalling this:
         1.8106601, 0.00000000, 0.00000000, 0.00000000, 
         0.00000000, 2.4142134, 0.00000000, 0.00000000, 
         0.00000000, 0.00000000, -1.0020020, -1.0000000,
         0.00000000, 0.00000000, -2.0020020, 0.0000000
      */
      /* GL calculation
         1.8106601, 0.00000000, 0.00000000, 0.00000000,
         0.00000000, 2.4142137, 0.00000000, 0.00000000,
         0.00000000, 0.00000000, -1.0020020, -1.0000000,
         0.00000000, 0.00000000, -2.0020020, 0.00000000
      */
  
      glMatrixMode(GL_MODELVIEW);
      glLoadMatrixf(identityMatrix);
  }
  </code></pre>
  
  <p>I'm checking my values both by direct observation and by comparing matrix values.
  The resultant values are listed in the comments above, and I've no idea why they don't match. The manually calculated matrix visually distorts the rendered scene(a simple cube offset to the lower-left of center) by not positioning it correctly, and I believe it's rendered smaller as well.</p>
  
  <p><em>edit</em>
  Fixed the stupid mistake as per Nicol Bolas' answer. This still doesn't work properly, though. Values in the comment have been updated as well.
  <em>edit2</em>
  Code above works fine now, question resolved. Stupid mistakes on my part.</p>