As you probably know, one 1x3 portion of the 4x4 transform contains the XYZ translation vector (aka position).
Likewise, one 3x3 portion of the matrix contains the rotation (and scale or shear at the same time, but I’ll ignore that here).
And the great thing about transformation matrices, is that this 3x3 rotation sub-matrix itself consists of three normalized vectors.
Turns out, the first column is the vector pointing to the right (positive X axis). The column to the right of that is the ‘up vector’ (positive Y). The column next to that, is the vector pointing rearward or forward depending on your camera orientation convention (positive Z axis).
// OpenGL matrix convention for typical GL software
// with positive Y=up and positive Z=rearward direction
RT = right
UP = up
BK = back
POS = position/translation
US = uniform scale
float transform[16];
[0] [4] [8 ] [12]
[1] [5] [9 ] [13]
[2] [6] [10] [14]
[3] [7] [11] [15]
[RT.x] [UP.x] [BK.x] [POS.x]
[RT.y] [UP.y] [BK.y] [POS.y]
[RT.z] [UP.z] [BK.z] [POS.Z]
[ ] [ ] [ ] [US ]
So in other words, you can fish your camera direction vector (and up vector, you may need it too) out of the transformation matrix, and plug it straight into gluLookAt (or whatever you use to setup the projection).
If I understood you right, you are constructing the transformation matrix from quaternions? You can then also simply rotate the ‘up’ and ‘back’ vector of the untransformed camera by the quaternion rotation. It should be computationally cheaper, although, as I noted above, once constructed, a 4x4 transformation matrix can hold lots of readily available useful information for many purposes. So depending on your needs, a matrix may be more handy.
I tried as you have explained. Here I have small question.
In my case it seems to be has problems in the matrix.
Here I have tried to move my camera to the direction which it face as following
RT = right
UP = up
BK = back
POS = position/translation
Vector3 newPosition(
POS.x + BK.x,
POS.y + BK.y,
POS.z + BK.z);
camera->setPosition(newPosition);
But it didn’t worked as expected. So I change it as following.
And it did work.