Kamera object

Top  Previous  Next

Creating a camera can be done in a few ways.


Camera Cam; //Position will be set to (0,0,0)

Camera Cam(x,y,z); //Position will be set to (x,y,z) To place the camera somewhere else you can:



Cam.Position[2]=newZ; In your render function before drawing anything you have to call Cam.setView(); To rotate around the (global) y-axis you call Cam.rotateGlob(degree, 0,1,0); while to look up/down you would call Cam.rotateLoc(degree, 1,0,0); Moving forward would be Cam.moveLoc(0,0,distance); while being shoved in a fixed direction would be Cam.moveGlob(deltaX, deltaY, deltaZ); of if you have a direction vector and a distance you call Cam.moveGlobal(dirX, dirY,dirZ, distance); A more complete version is available if you like, which also handles the perspective matrix and has functions to cull spheres, points and boxes.


Currently browsing [openglcamera.zip] (2,929 bytes) - [camera.cpp] - (3,215 bytes)


#include "camera.h"



The constructor will set the matrix to identity, except the inverted z-axis.

I cant get used to "forward" being negative, but if this bothers you feel free

to change the marked parts.


Also, if you dont like to access the vectors like float-arrays you can always

use vector-pointers, as long as they only contain three floats like this:

struct vector{float x,y,z;};

and replace the float* with vector* in the header file.


Camera::Camera(float x, float y, float z) {

       memset(Transform, 0, 16*sizeof(float));

       Transform[0] = 1.0f;

       Transform[5] = 1.0f;

       Transform[10] = -1.0f;

       Transform[15] = 1.0f;

       Transform[12] = x; Transform[13] = y; Transform[14] = z;








Camera::~Camera() {}



This one does pretty much the same as gluLookAt, just that it doesnt require

to extract the vectors for gluLookAt and have it rebuild the matrix we already



void Camera::setView() {



       float viewmatrix[16]={//Remove the three - for non-inverted z-axis

                                                Transform[0], Transform[4], -Transform[8], 0,

                                                Transform[1], Transform[5], -Transform[9], 0,

                                                Transform[2], Transform[6], -Transform[10], 0,


                                                -(Transform[0]*Transform[12] +

                                                Transform[1]*Transform[13] +



                                                -(Transform[4]*Transform[12] +

                                                Transform[5]*Transform[13] +



                                                //add a - like above for non-inverted z-axis

                                                (Transform[8]*Transform[12] +

                                                Transform[9]*Transform[13] +

                                                Transform[10]*Transform[14]), 1};




void Camera::moveLoc(float x, float y, float z, float distance) {

       float dx=x*Transform[0] + y*Transform[4] + z*Transform[8];

       float dy=x*Transform[1] + y*Transform[5] + z*Transform[9];

       float dz=x*Transform[2] + y*Transform[6] + z*Transform[10];

       Transform[12] += dx * distance;

       Transform[13] += dy * distance;

       Transform[14] += dz * distance;



void Camera::moveGlob(float x, float y, float z, float distance) {

       Transform[12] += x * distance;

       Transform[13] += y * distance;

       Transform[14] += z * distance;




Here we let OpenGls (most likely quite optimized) functions do the work.

Note that its transformations already are in local coords.


void Camera::rotateLoc(float deg, float x, float y, float z) {




       glRotatef(deg, x,y,z);

       glGetFloatv(GL_MODELVIEW_MATRIX, Transform);





We have to invert the rotations to get the global axes in local coords.

Luckily thats just the transposed in this case.


void Camera::rotateGlob(float deg, float x, float y, float z) {

       float dx=x*Transform[0] + y*Transform[1] + z*Transform[2];

       float dy=x*Transform[4] + y*Transform[5] + z*Transform[6];

       float dz=x*Transform[8] + y*Transform[9] + z*Transform[10];




       glRotatef(deg, dx,dy,dz);

       glGetFloatv(GL_MODELVIEW_MATRIX, Transform);







Currently browsing [openglcamera.zip] (2,929 bytes) - [camera.h] - (1,814 bytes)


#ifndef CAMERA_H

#define CAMERA_H



All the Win/OpenGL stuff..

if youre not using Windows you most likely know what goes here


#ifdef _WIN32

#define  WIN32_LEAN_AND_MEAN

#include <windows.h>

#include <GL/gl.h>

#pragma comment (lib, "opengl32.lib")

#pragma comment (lib, "glu32.lib")





You can access the Right/Up/Forward vectors like a float[3] array,

but cannot write to them, because that would screw up the matrix.

Same goes for Position, except its safe to write to it.


setView() has to be called before you draw anything.

Just call it instead of gluLookAt (which most are using)


move and rotate come in two versions. Loc means the transformation

is in local coords, so rotating around (1,0,0) means youre rotating

around your current Right-vector while Glob would rotate around the

global x-axis.


Most likely you will use Loc for controlling the camera, though Glob

can be usefull if you need to apply physics. Also walking characters

will usually rotate around the global rather than around their local Up,

while flying objects will always use local axes.


If talking about objects when this is a camera confuses you: if you drop

the setView() method you can use this for objects in your world too. Just

rename the class to Object3D or something and derive a camera class from it.


class Camera {


       float const *Right, *Up, *Forward;

       float *Position;


       float Transform[16];



       Camera(float x=0.0f, float y=0.0f, float z=0.0f);



       void setView();

       void moveLoc(float x, float y, float z, float distance=1);

       void moveGlob(float x, float y, float z, float distance=1);

       void rotateLoc(float deg, float x, float y, float z);

       void rotateGlob(float deg, float x, float y, float z);