title: Opengl View Transformation matrix Rotation
body: <p>Recently i implemented a simple Opengl program that composes of a scene of objects, i've applied most of the transformation &amp; projection matrices, in such away that i am able to <code>rotate transform &amp; scale objects, move my camera through z &amp; x coordinates and applied perspective projection</code> however when it comes to camera rotation things get weird, my rotation matrix for my camera is simply a rotation matrix that rotates the world uniformly, however when i rotate the world so that i look in the up direction;<code>+y</code>; and when i move forward, the camera doesn't seem to advance in the direction where it is looking at;<code>as it is the case in FPS games</code> my camera moves relative to the world space, i know that i am missing the vectors that specify directions in <code>x,y,z</code> coordinates, but i am unable to incorporate these vectors with my camera (view Transformation) matrix, most of the tutorial on internet either describes it in a block diagram or uses the conventional gluLookAt() function, i really need a brief explanation about view Transformations and specifically camera rotation and how i should implement it in my matrices, my my final matrix is as follows:</p>
  
  <blockquote>
    <blockquote>
      <p>resultTransform = perspectiveTrans * cameraTrans * modelTrans;</p>
    </blockquote>
  </blockquote>
  
  <p>where:</p>
  
  <p>perspectiveTrans = applies only a perspective projection transformation</p>
  
  <p>cameraTrans = is a combination of rotate,translate matrices that affect all obj.s in the scene</p>
  
  <p>modelTrans  =is the transformation that is applied to the models</p>
  
  <p>Matrix4X4.cpp file:</p>
  
  <pre><code>#include "Matrix4X4.h"
  
  using namespace std;
  
  
  ////////////////////////////////// Constructor Declerations ////////////////////////////////
  
  Matrix4X4::Matrix4X4()
  {
  setIdentity();
  }
  
  Matrix4X4::Matrix4X4(float value)
  {
  for(int i = 0 ; i &lt; 4; i++)
      for ( int j = 0; j &lt; 4; j++)
          Matrix[i][j] = value;
  
  }
  
  /////////////////////////////////////////////////////////////////////////////////
  
  
  
  
  
  
  
  ////////////////////////////// Destructor Decleration //////////////////////////////
  Matrix4X4::~Matrix4X4()
  {
  
  }
  
  ///////////////////////////////////////////////////////////////////////////////////
  
  
  
  
  
  
  
  /////////////////////// Set Identity Matrix /////////////////////////////////////////
  
  void Matrix4X4::setIdentity()
  {
  Matrix[0][0] =1;   Matrix[0][1] = 0;  Matrix[0][2] = 0;      Matrix[0][3] = 0;
  Matrix[1][0] =0;   Matrix[1][1] = 1;  Matrix[1][2] = 0;      Matrix[1][3] = 0;
  Matrix[2][0] =0;   Matrix[2][1] = 0;  Matrix[2][2] = 1;      Matrix[2][3] = 0;
  Matrix[3][0] =0;   Matrix[3][1] = 0;  Matrix[3][2] = 0;      Matrix[3][3] = 1;
  
  
  }
  
  ///////////////////////////////////////////////////////////////////////////////////
  
  
  
  
  
  
  ///////////////////////// Set Translation Matrix //////////////////////////////////
  
  Matrix4X4 Matrix4X4::setTranslation(float x,float y,float z)
  {
  
  
  Matrix[0][0] =1;   Matrix[0][1] = 0;  Matrix[0][2] = 0;      Matrix[0][3] = x;
  Matrix[1][0] =0;   Matrix[1][1] = 1;  Matrix[1][2] = 0;      Matrix[1][3] = y;
  Matrix[2][0] =0;   Matrix[2][1] = 0;  Matrix[2][2] = 1;      Matrix[2][3] = z;
  Matrix[3][0] =0;   Matrix[3][1] = 0;  Matrix[3][2] = 0;      Matrix[3][3] = 1;
  
  return  *this;
  
  }
  /////////////////////////////////////////////////////////////////////////////////
  
  
  
  
  
  ////////////////////////////////////// Set Rotation Matrix     ///////////////////////////////////////////
  
  Matrix4X4 Matrix4X4::setRotation(float x,float y,float z)
  {
  Matrix4X4 xRot;
  Matrix4X4 yRot;
  Matrix4X4 zRot;
  
  x = (float)x * 3.14/ 180.0;
  y = (float)y * 3.14/ 180.0;
  z = (float)z * 3.14/ 180.0;
  
  
  
  xRot.Matrix[0][0] =1;         xRot.Matrix[0][1] = 0;        xRot.Matrix[0][2] = 0;            xRot.Matrix[0][3] = 0;
  xRot.Matrix[1][0] =0;         xRot.Matrix[1][1] = cosf(x);  xRot.Matrix[1][2] = -sinf(x);   xRot.Matrix[1][3] = 0;
  xRot.Matrix[2][0] =0;         xRot.Matrix[2][1] = sinf(x);  xRot.Matrix[2][2] = cosf(x);    xRot.Matrix[2][3] = 0;
  xRot.Matrix[3][0] =0;         xRot.Matrix[3][1] = 0;        xRot.Matrix[3][2] = 0;          xRot.Matrix[3][3] = 1;
  
  yRot.Matrix[0][0] = cosf(y);  yRot.Matrix[0][1] = 0;        yRot.Matrix[0][2] = -sinf(y);   yRot.Matrix[0][3] = 0;
  yRot.Matrix[1][0] =0;         yRot.Matrix[1][1] = 1;        yRot.Matrix[1][2] = 0;          yRot.Matrix[1][3] = 0;
  yRot.Matrix[2][0] = sinf(y);  yRot.Matrix[2][1] = 0;        yRot.Matrix[2][2] = cosf(y);    yRot.Matrix[2][3] = 0;
  yRot.Matrix[3][0] =0;         yRot.Matrix[3][1] = 0;        yRot.Matrix[3][2] = 0;          yRot.Matrix[3][3] = 1;
  
  zRot.Matrix[0][0] = cosf(z);  zRot.Matrix[0][1] = -sinf(z); zRot.Matrix[0][2] = 0;          zRot.Matrix[0][3] = 0;
  zRot.Matrix[1][0] = sinf(z);  zRot.Matrix[1][1] = cosf(z);  zRot.Matrix[1][2] = 0;          zRot.Matrix[1][3] = 0;
  zRot.Matrix[2][0] =0;         zRot.Matrix[2][1] = 0;        zRot.Matrix[2][2] = 1;          zRot.Matrix[2][3] = 0;
  zRot.Matrix[3][0] =0;         zRot.Matrix[3][1] = 0;        zRot.Matrix[3][2] = 0;          zRot.Matrix[3][3] = 1;
  
  
  return (zRot * yRot * xRot) ;
  
  }
  
  ////////////////////////////////////////////////////////////////////////////////////////////////////
  
  
  
  
  
  
  //////////////////////////////////////// Set Scale Matrix //////////////////////////////////////////
  
  Matrix4X4 Matrix4X4::setScale(float x,float y,float z)
  {
  
  
  Matrix[0][0] =x;   Matrix[0][1] = 0;  Matrix[0][2] = 0;      Matrix[0][3] = 0;
  Matrix[1][0] =0;   Matrix[1][1] = y;  Matrix[1][2] = 0;      Matrix[1][3] = 0;
  Matrix[2][0] =0;   Matrix[2][1] = 0;  Matrix[2][2] = z;      Matrix[2][3] = 0;
  Matrix[3][0] =0;   Matrix[3][1] = 0;  Matrix[3][2] = 0;      Matrix[3][3] = 1;
  
  return *this;
  }
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////
  
  
  
  
  
  ///////////////////////////////// Set Perspective Projection ///////////////////////////////////////
  
  void Matrix4X4::setPerspective(float fov,float aRatio,float zNear,float zFar)
  {
  
  
  fov = (fov/2) * 3.14 / 180.0;
  float tanHalfFOV = tanf(fov);
  float zRange = zNear - zFar;
  
  
   Matrix[0][0] =1.0f / (tanHalfFOV * aRatio);   Matrix[0][1] = 0;                  Matrix[0][2] = 0;                         Matrix[0][3] = 0;
   Matrix[1][0] =0;                              Matrix[1][1] = 1.0f / tanHalfFOV;  Matrix[1][2] = 0;                         Matrix[1][3] = 0;
   Matrix[2][0] =0;                              Matrix[2][1] = 0;                  Matrix[2][2] = (-zNear - zFar)/ zRange;   Matrix[2][3] = 2* zFar * zNear / zRange;
   Matrix[3][0] =0;                              Matrix[3][1] = 0;                  Matrix[3][2] = 1;                         Matrix[3][3] = 0;
  
  
  
  }
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  
  
  
  
  ////////////////////////////////////// Getters &amp; Setters ////////////////////////////////////////////
  
  float * Matrix4X4::getMat()
  {
  return (float *) Matrix;
  }
  
  
  float Matrix4X4::getMember(int x, int y) const
  {
  return Matrix[x][y];
  }
  
  
  void Matrix4X4::setMat(int row,int col,float value)
  {
  Matrix[row][col] = value;
  }
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////
  
  
  
  
  
  
  /////////////////////////////////////// (*) Operator Overload //////////////////////////////////////
  
  Matrix4X4 operator * (const Matrix4X4 &amp; lhs,const Matrix4X4 &amp; rhs)
  {
  
  Matrix4X4 result;
  
      for(int i = 0 ; i &lt; 4; i++)
          for ( int j = 0; j &lt; 4; j++)
              result.setMat(i, j,  lhs.getMember(i,0) * rhs.getMember(0, j) +
                              lhs.getMember(i,1) * rhs.getMember(1, j) +
                              lhs.getMember(i,2) * rhs.getMember(2, j) +
                              lhs.getMember(i,3) * rhs.getMember(3, j));
  
  
          return result;
  }
  //////////////////////////////////////////////////////////////////////////////////////////////////
  </code></pre>
  
  <p>the Transformation code i use in my main block:</p>
  
  <pre><code>        SDL_PumpEvents();
  
          for (int x = 0; x&lt; 256; x++)
          {
              if (state[x] == 1 )
              {
                  if(x  == 26)
                      tranForward -= 0.001;
                  if (x == 22)
                      tranForward += 0.001;
                  if (x == 4)
                      tranRight += 0.0009;
                  if (x == 7)
                      tranRight -= 0.0009;
  
                  if (x == 82)
                      lookUp += 0.02;
                  if (x == 81)
                      lookUp -= 0.02;
                  if (x == 80)
                      lookRight -= 0.02;
                  if (x == 79)
                      lookRight += 0.02;
              }
          }
  
  
  
  
  
          modelTrans =  Translation.setTranslation(0, 0, 5) * Scale.setScale(0.5, 0.5, 0.5);
          camTrans   =  Rotation.setRotation(lookUp, lookRight, 0) * Translation.setTranslation(tranRight, 0, tranForward);
          Projection.setPerspective(70, win.getWidth()/win.getHeight(), 0.1, 1000);
  
  
          result =  Projection * camTrans * modelTrans;
  
  
  
  
         glUniformMatrix4fv(uniformloc, 1, GL_TRUE, result.getMat());
  </code></pre>