
Implementing the free camera
Free camera is the first camera type which we will implement in this recipe. A free camera does not have a fixed target. However it does have a fixed position from which it can look in any direction.
Getting ready
The following figure shows a free viewing camera. When we rotate the camera, it rotates at its position. When we move the camera, it keeps looking in the same direction.

The source code for this recipe is in the Chapter2/FreeCamera
directory. The CFreeCamera
class is defined in the Chapter2/src/FreeCamera.[h/cpp]
files. The class interface is as follows:
class CFreeCamera : public CAbstractCamera { public: CFreeCamera(void); ~CFreeCamera(void); void Update(); void Walk(const float dt); void Strafe(const float dt); void Lift(const float dt); void SetTranslation(const glm::vec3& t); glm::vec3 GetTranslation() const; void SetSpeed(const float speed); const float GetSpeed() const; protected: float speed; //move speed of camera in m/s glm::vec3 translation; };
How to do it…
The steps needed to implement the free camera are as follows:
- Define the
CFreeCamera
class and add a vector to store the current translation. - In the
Update
method, calculate the new orientation (rotation) matrix, using the current camera orientations (that is, yaw, pitch, and roll amount):glm::mat4 R = glm::yawPitchRoll(yaw,pitch,roll);
Note
Make sure that the yaw, pitch, and roll angles are in radians.
- Translate the camera position by the translation amount:
position+=translation;
If we need to implement a free camera which gradually comes to a halt, we should gradually decay the translation vector by adding the following code after the key events are handled:
glm::vec3 t = cam.GetTranslation(); if(glm::dot(t,t)>EPSILON2) { cam.SetTranslation(t*0.95f); }
If no decay is needed, then we should clear the translation vector to
0
in theCFreeCamera::Update
function after translating the position:translation = glm::vec3(0);
- Transform the
look
vector by the current rotation matrix, and determine theright
andup
vectors to calculate the orthonormal basis:look = glm::vec3(R*glm::vec4(0,0,1,0)); up = glm::vec3(R*glm::vec4(0,1,0,0)); right = glm::cross(look, up);
- Determine the camera target point:
glm::vec3 tgt = position+look;
- Use the
glm::lookat
function to calculate the new view matrix using the camera position, target, and theup
vector:V = glm::lookAt(position, tgt, up);
There's more…
The Walk
function simply translates the camera in the look direction:
void CFreeCamera::Walk(const float dt) { translation += (look*dt); }
The Strafe
function translates the camera in the right direction:
void CFreeCamera::Strafe(const float dt) { translation += (right*dt); }
The Lift
function translates the camera in the up direction:
void CFreeCamera::Lift(const float dt) { translation += (up*dt); }
Running the demo application renders an infinite checkered plane as shown in the following figure. The free camera can be moved around by pressing the keys W, S, A, D, Q, and Z. Left-clicking the mouse rotates the camera at the current position to change the look direction. Middle-click zooms the camera in the look direction.

See also
- DHPOWare OpenGL camera demo – Part 1 (http://www.dhpoware.com/demos/glCamera1.html)
- DHPOWare OpenGL camera demo – Part 2 (http://www.dhpoware.com/demos/glCamera2.html)
- DHPOWare OpenGL camera demo – Part 3 (http://www.dhpoware.com/demos/glCamera3.html)