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 //positions of the cubes void cubepositions (void) { //set the positions of the cubes //draw the cube void init (void) { void enable (void) { void camera (void) { void display (void) { void reshape (int w, int h) { void keyboard (unsigned char key, int x, int y) { if (key==‘z’) if (key==‘w’) if (key==‘s’) if (key==‘d’) if (key==‘a’) int main (int argc, char **argv) { |
The code all seems to be centered instead of left-aligned
Hi.
Thank You for this example, it’s great. I just have one little question. Let’s say I wanted to add the ability to roll the camera around the z axis. How can I do that?
Thank You
Hmm this camera is moving the world itself right?
Hi how do change the sensetivity?
Shouldn’t “-positionx[i+1]” be an error? It would be out of range in the last round.
also when i changed this line zpos -= float(cos(yrotrad)) ; by this one zpos -= 0.9 ; only difference is speed
i don’t know why we need to put trigonometry?
Zilot, his calculation works because it creates a new position vector that is pointing the same direction as the old. If you were to simply add 0.9 then you wouldn’t be traveling in the same direction that the camera is facing. To see what I mean, try adding a larger number like 10 instead… the camera rotates instead of moving forward as intended.
A problem I see is that the speed in which the camera moves varies depending on the values of yrot and xrot to a small extent, it isn’t significant for this program but if the camera’s speed is ever to be scaled up then it may become more noticeable.
An alternative would be to add one unit vector in the direction the camera is facing, ie divide the position vector by it’s magnitude then add that vector to the original position vector. That way it’s easier to program the exact speed you want and avoids using sine and cosine. The drawback is more CPU calculations are required, however.
Thanks for the tutorial, Swiftless, it made much more sense then everything else I’ve found.
hi swifless first thx for this tutorial
i m a bit confused when press w and s button and when i removed this lines from the code
xpos += float(sin(yrotrad)) ;
ypos -= float(sin(xrotrad)) ;
it really gave the same result as when they exist i haven’t understand their role?
i hope you can post some screenshot for each tutorial so that we can understand more clearly what it does…:)
Just wanted to say thanks for this tutorial. I completely overlooked using radians, and everything was acting weird. Thanks!
Thanks so much! Got this running in no time. Thanks for sharing… it’s so refreshing..
wats the difference between and header files!!!???
i like this tutorial. it gives me alot of ideas. thanks
Hi,
Thanks for the great tutorial. However, I don’t really get the math behind scene of camera function and when user press ‘w’.
Thank you
Hi dorekofu_87,
The maths behind the key presses is all about trigonometry and circles. A bit of research on this and you should be able to figure it out.
Cheers,
Swiftless
Hi,
I would still highly suggest storing your value of Pi as a constant that you then refer to in the code. C++ compilers are very good at both handling this constant correctly (not rounding it to different numbers), and more importantly generating fast code.
It’s a simple technique that generally appears even in compilers made by undergraduate students for their university classes and is called constant propagation. Basically what it means is that if there is any value that depends only on constant values will be computed once at compile time. So for example, in the code above when you have lines such as yrotrad = (yrot / 180 * 3.141592654f); the compiler will do the math for 1/180 * 3.141592654f exactly one, and the result will be stored as constant data that the program uses at runtime.
Even if it weren’t the case that the compiler will automatically generate fast code here, the readability and maintainability benefits of using a constant for pi mean that you really should! Just wait till you hardcode the value for pi in your program 100 different places, but do it differently in each place!
Hi Spectre256,
Nice suggestion! There are many different optimization routes you can take, and I suggest people explore them. This tutorial is originally about 5 years old now, and I plan on rewriting it, probably with this suggestion included 🙂
Cheers,
Swiftless
did you ever rewrite this code?
did you ever re-write this code?
float*
What is the int angel there for?, i cant see that u are using it in anything, just increasing it
Hey Per,
That looks like just a left-over variable from the code I built the project on.
Cheers,
Swiftless
Nice and easy, just what I needed after making my own crappy camera movement! 🙂