Creating a basic camera for use in OpenGL
Back to OpenGL Tutorial Index
In this tutorial I will be teaching you how to make a 'camera' system using simple trigonometry. In our camera creation I will be using only keyboard input with the glut keyboard controls. Now camera rotation is where maths can first start coming into play when it comes to game programming. Math unfortunately for many, is crucial to graphics, physics and even sound, so math must be understood relatively well if you want to get anywhere.
now here we are setting positions for the camera with the variables:
xpos, ypos, zpos
we are then setting the angle at which the camera is rotated with:
xrot, yrot, xrot is the rotation on the x-axis(up and down), while
yrot is the rotation on the y-axis(left and right). And yes it is a little
confusing.
now because we are rotating and moving in circular directions, we need
to use PI, you might remember this as 3.14 but here we have to be alot more
accurate, so we use 3.141592654. We don't use the symbol for PI as each time the
computer calculates it, it will round off to a different number, and also takes
longer to calculate.
here is where you also have to use trigonometry to calculate your position
we are using:
yrotrad = (yrot / 180 * 3.141592654f);
xrotrad = (xrot / 180 * 3.141592654f);
xpos -= float(sin(yrotrad));
zpos += float(cos(yrotrad)) ;
ypos += float(sin(xrotrad));
now the yrotrad is angle at which you have rotated.
to calculate your position on the x,y and z axis you have to use 2 of the trigonomic
forumulas, sin(sine), cos(cosine). If you have done these in maths, you will
understand more of what is going on. If not, I suggest you take a crash course
in trigonometry. Rather simple concept when you know what it is.
now to set the angle of which you have rotated, we use the simple:
yrot -= 1;
if (yrot < -360) yrot += 360;
this says to take 1 of the angle of rotation on the y-axis
then says that if the angle is less then -360, to set it back to 360
so we can start subtracting the angle again. We have to use 360,
because there are 360 degrees in a circle.
now because I have described these lines up here, I will not comment them below.
you should get the jist of what they do if you have read what I just said.
I hope that you understood some of that, I am not sure I do :S
If you have any queries about this feel free to contact me at swiftless@gmail.com
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
//angle of rotation
float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0;
//positions of the cubes
float positionz[10];
float positionx[10];
void cubepositions (void) { //set the positions of the cubes
for (int i=0;i<10;i++)
{
positionz[i] = rand()%5 + 5;
positionx[i] = rand()%5 + 5;
}
}
//draw the cube
void cube (void) {
for (int i=0;i<10;i++)
{
glPushMatrix();
glTranslated(-positionx[i + 1] * 10, 0, -positionz[i + 1] * 10); //translate the cube
glutSolidCube(2); //draw the cube
glPopMatrix();
}
}
void init (void) {
cubepositions();
}
void enable (void) {
glEnable (GL_DEPTH_TEST); //enable the depth testing
glEnable (GL_LIGHTING); //enable the lighting
glEnable (GL_LIGHT0); //enable LIGHT0, our Diffuse Light
glShadeModel (GL_SMOOTH); //set the shader to smooth shader
}
void camera (void) {
glRotatef(xrot,1.0,0.0,0.0); //rotate our camera on teh x-axis (left and right)
glRotatef(yrot,0.0,1.0,0.0); //rotate our camera on the y-axis (up and down)
glTranslated(-xpos,-ypos,-zpos); //translate the screen to the position of our camera
}
void display (void) {
glClearColor (0.0,0.0,0.0,1.0); //clear the screen to black
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the color buffer and the depth buffer
glLoadIdentity();
camera();
enable();
cube(); //call the cube drawing function
glutSwapBuffers(); //swap the buffers
angle++; //increase the angle
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h); //set the viewport to the current window specifications
glMatrixMode (GL_PROJECTION); //set the matrix to projection
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 1000.0); //set the perspective (angle of sight, width, height, , depth)
glMatrixMode (GL_MODELVIEW); //set the matrix back to model
}
void keyboard (unsigned char key, int x, int y) {
if (key=='q')
{
xrot += 1;
if (xrot >360) xrot -= 360;
}
if (key=='z')
{
xrot -= 1;
if (xrot < -360) xrot += 360;
}
if (key=='w')
{
float xrotrad, yrotrad;
yrotrad = (yrot / 180 * 3.141592654f);
xrotrad = (xrot / 180 * 3.141592654f);
xpos += float(sin(yrotrad)) ;
zpos -= float(cos(yrotrad)) ;
ypos -= float(sin(xrotrad)) ;
}
if (key=='s')
{
float xrotrad, yrotrad;
yrotrad = (yrot / 180 * 3.141592654f);
xrotrad = (xrot / 180 * 3.141592654f);
xpos -= float(sin(yrotrad));
zpos += float(cos(yrotrad)) ;
ypos += float(sin(xrotrad));
}
if (key=='d')
{
yrot += 1;
if (yrot >360) yrot -= 360;
}
if (key=='a')
{
yrot -= 1;
if (yrot < -360)yrot += 360;
}
if (key==27)
{
exit(0);
}
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH); //set the display to Double buffer, with depth
glutInitWindowSize (500, 500); //set the window size
glutInitWindowPosition (100, 100); //set the position of the window
glutCreateWindow ("A basic OpenGL Window"); //the caption of the window
init (); //call the init function
glutDisplayFunc (display); //use the display function to draw everything
glutIdleFunc (display); //update any variables in display, display can be changed to anyhing, as long as you move the variables to be updated, in this case, angle++;
glutReshapeFunc (reshape); //reshape the window accordingly
glutKeyboardFunc (keyboard); //check the keyboard
glutMainLoop (); //call the main loop
return 0;
}
Download C++ Source Code for this Tutorial
Download Visual Basic Source Code for this Tutorial |