22. OpenGL Camera

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

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
    #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;
}

  • March 25, 2010
  • 26