Jump to content
  • Advertisement
Sign in to follow this  
Toolmaker

OpenGL Understanding camera basics...

This topic is 3905 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently learning OpenGL using the NeHe tutorials. I'm currently up to lesson 10, but I'm having some trouble understand the whole deal around the camera. It says: 1. Rotate and translate the camera position according to user commands 2. Rotate the world around the origin in the opposite direction of the camera rotation (giving the illusion that the camera has been rotated) 3. Translate the world in the opposite manner that the camera has been translated (again, giving the illusion that the camera has moved). I don't completely understand 2 and 3. 1 is updating the camera according to user input, ie. move 1 unit forward, rotate to 90 degrees. But what about 2 and 3? And why is it done like that? I want to understand WHY I have to do it. I also want to move away from doing translations/rotations by doing it the hard way, and therefor I want to switch to the use of matrices. What would be good material to dive into for that? Thank you. Toolmaker

Share this post


Link to post
Share on other sites
Advertisement
I also dislike that method of doing cameras.
My cameras work via matrices, and are API agnostic. Put simply, my camera system is a position and a direction. To move the camera forwards, I add the direction * distance to the position. To rotate the camera, I use euler rotation.

To apply the camera to my renderer, I pass it in via a set method, and the renderer then uses it with gluLookAt(___), and gluPerspective(___). There are no graphics API calls inside the camera class. the result of thsi is that I can give cameras to entities such as characters, and even physics objects, with some pretty sick results.

I trust you are familiar with euler rotation? It makes life a whole lot easier where cameras are concerned.

Would you like more details?

[update] While I recommend you start by writing your own and then upgrade to a better one later, I currently use vmath.

[Edited by - shotgunnutter on January 14, 2008 11:22:49 AM]

Share this post


Link to post
Share on other sites
You should definitely look here at some point, but the explanations there are not as beginner friendly as they could be, so I'll try to explain this as best as I can.

Obviously there is no actual camera in the world, but we want to achieve the effect of a camera that we can move and orient. How can we do this?

Suppose we have a scene with just one object, and the camera is looking directly at it. Moving the camera 1 unit forward (suppose forward means the negative Z-axis) will give the same result as moving the object 1 unit backward, the result being that the object is 1 unit closer to the camera. Similarly, rotating the camera 30 degrees to the left is the same as rotating the object 30 degrees to the right around the camera (so in this case 'orbiting' might be a better term than 'rotation').

After we understand this, we see that we can achieve the effect of a camera by properly translating and rotating the objects, but by negated distances and angles, and in reverse order so that the objects rotate around the camera's position and not around themselves. This last point requires understanding how applying transformations in a different order can affect the result. The section titled "Thinking About Transformations" in the link above covers this very well.

Of course, we might have more than one object in the scene, and we have to do this for all of them. Therefore, in your code, you specify the camera position and orientation before you specify any of the transformations for the objects. That way, any transformation you specify for the object will be combined with the camera-related transformations to simulate the effect of a movable camera (this point also requires that you understand how OpenGL transformations work and the material in the section I mentioned earlier).

Well, after reading my explanation, it's not as clear as I would have wanted it to be, but if you have any specific questions I'll try to explain further.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
You should definitely look here at some point, but the explanations there are not as beginner friendly as they could be, so I'll try to explain this as best as I can.

Obviously there is no actual camera in the world, but we want to achieve the effect of a camera that we can move and orient. How can we do this?

Suppose we have a scene with just one object, and the camera is looking directly at it. Moving the camera 1 unit forward (suppose forward means the negative Z-axis) will give the same result as moving the object 1 unit backward, the result being that the object is 1 unit closer to the camera. Similarly, rotating the camera 30 degrees to the left is the same as rotating the object 30 degrees to the right around the camera (so in this case 'orbiting' might be a better term than 'rotation').

After we understand this, we see that we can achieve the effect of a camera by properly translating and rotating the objects, but by negated distances and angles, and in reverse order so that the objects rotate around the camera's position and not around themselves. This last point requires understanding how applying transformations in a different order can affect the result. The section titled "Thinking About Transformations" in the link above covers this very well.

Of course, we might have more than one object in the scene, and we have to do this for all of them. Therefore, in your code, you specify the camera position and orientation before you specify any of the transformations for the objects. That way, any transformation you specify for the object will be combined with the camera-related transformations to simulate the effect of a movable camera (this point also requires that you understand how OpenGL transformations work and the material in the section I mentioned earlier).

Well, after reading my explanation, it's not as clear as I would have wanted it to be, but if you have any specific questions I'll try to explain further.


That explains it pretty well, but its a problematic way of handling OpenGL cameras, IMHO. I find that doing it via matrices is easier. YMMV.

[Edited by - shotgunnutter on January 14, 2008 11:51:17 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by shotgunnutter
its a problematic way of handling OpenGL cameras, IMHO. I find that doing it via matrices is easier.


The only way you could do it is with matrices (note that gluLookAt() also generates a matrix). How you create that matrix is up to you - you can use Euler angles and trigonometry, quaternions, etc., but at the end you have to create a matrix because that's all OpenGL understands. So even if you hide it behind a more convenient interface, my description above is the only way to achieve the effect of a camera.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
You should definitely look here at some point, but the explanations there are not as beginner friendly as they could be, so I'll try to explain this as best as I can.

Obviously there is no actual camera in the world, but we want to achieve the effect of a camera that we can move and orient. How can we do this?

Suppose we have a scene with just one object, and the camera is looking directly at it. Moving the camera 1 unit forward (suppose forward means the negative Z-axis) will give the same result as moving the object 1 unit backward, the result being that the object is 1 unit closer to the camera. Similarly, rotating the camera 30 degrees to the left is the same as rotating the object 30 degrees to the right around the camera (so in this case 'orbiting' might be a better term than 'rotation').

After we understand this, we see that we can achieve the effect of a camera by properly translating and rotating the objects, but by negated distances and angles, and in reverse order so that the objects rotate around the camera's position and not around themselves. This last point requires understanding how applying transformations in a different order can affect the result. The section titled "Thinking About Transformations" in the link above covers this very well.

Of course, we might have more than one object in the scene, and we have to do this for all of them. Therefore, in your code, you specify the camera position and orientation before you specify any of the transformations for the objects. That way, any transformation you specify for the object will be combined with the camera-related transformations to simulate the effect of a movable camera (this point also requires that you understand how OpenGL transformations work and the material in the section I mentioned earlier).

Well, after reading my explanation, it's not as clear as I would have wanted it to be, but if you have any specific questions I'll try to explain further.


Excellent explanation! That's pretty much what I wanted to know :). Now to brush up my matrix maths(I've had it, but I kinda forgot how to do it, so I'll have to look it up) and from there on, work further on my vector maths.

I'll give you a rate++ for the excellent explanation :). 1 question tho, all object movements should be relative to the camera in order to achieve a camera-like 'experience'. How does this affect other translations(I'll leave out rotations for now).

If I move my 'camera' to (0, 0, -10) and I have an object at (0, 0, -50) and another one at (10, 0, -50), do I need call glLoadIdentity(); -> do camera translation + object translation, or would it be best to calculate the relative position of object a to b and translate with that(ie, glTranslatef(10, 0, 0))?

Toolmaker

Share this post


Link to post
Share on other sites
Quote:
Original post by Toolmaker
Excellent explanation!


Glad you liked it :)

Quote:
Now to brush up my matrix maths(I've had it, but I kinda forgot how to do it, so I'll have to look it up) and from there on, work further on my vector maths.


You might want to look at the two sample chapters I linked to here. The first is a long chapter on vectors. You can probably skip some of it because at first it is important to understand the geometric meaning of vectors and their operations, so focus on that.

The second chapter is an excellent introduction to matrices, probably the best I have ever seen. It does a great job of explaining how to interpret matrices geometrically and not just as tables of numbers. It also emphasizes the important distinction between row vectors and column vectors. After reading this chapter, you'll want to look at the section titled "Thinking About Transformations" in the link in my first post to understand why this is especially when using OpenGL.

Quote:
If I move my 'camera' to (0, 0, -10) and I have an object at (0, 0, -50) and another one at (10, 0, -50), do I need call glLoadIdentity(); -> do camera translation + object translation, or would it be best to calculate the relative position of object a to b and translate with that(ie, glTranslatef(10, 0, 0))?


I'm not entirely sure I understand your question, but in general you don't have to think about the camera when moving your objects. You just know that it will work correctly. How do you know? Look at the following code:


void display() {
glLoadIdentity();

// Position camera at (0, 0, -10) so we translate by the negative units
glTranslatef(0, 0, 10);

// Position first object
glPushMatrix();
glTranslatef(0, 0, -50);
drawObjectA();
glPopMatrix();

// Position second object
glPushMatrix();
glTranslatef(10, 0, -50);
drawObjectA();
glPopMatrix();
}




The calls to glPush/glPop are needed when manipulating multiple objects (unless you want their transformations to be combined, but we'll forget about that for now). If you are not familiar with these calls, just pretend there's one object and you can ignore them (they are explained with nice examples in the link in my first post).

I don't want to go into too much detail (because you need to understand matrices to understand those details), but calls Like glTranslatef() combine their transformations with any transformations that were previously applied (EDIT - this is exactly why you call glLoadIdentity() at the start of each frame). In the code above, the camera related transformation was applied first, so any further transformations will be combined with it. So, we can just move our objects and be sure that they will move properly with relation to the camera, because the camera transform will be applied to them "automatically".

Again this turned out to be more confusing than I intended. I recommend that you first get comfortable with matrices, then with how transformations work in OpenGL (including the glPush/glPop functions). The sample chapter on matrices covers the former (to an extent), and the link in my first post covers the latter. Once you are comfortable with writing code that can move several objects independently with a fixed camera, come back to this post and see if what I said is somewhat clearer.

Hope this helps and sorry for the long post (again!).

[Edited by - Gage64 on January 15, 2008 1:54:57 AM]

Share this post


Link to post
Share on other sites
Thanks for the answers :). You're great at explaining it understandly. A skill which is extremely useful in our field.

I'm currently doing 2D vector math in my computer graphics class at college, so I do understand how most of the stuff works, except it has another added direction to it. And, I need to start brushing up my skills when it comes to matrices, because I need them at the exam.

For example, let's take this as our environment:


Ok, so now I want to move my camera 10 units towards the boxes. This would mean I have to translate the camera 10 units negatively on the z-axis(-10). Unless I want move all the objects, then I translate all the objects along the z-axis in +10 units.

In other words, the translation/rotation of the camera is always the inverse of the translation I would do the world. Perhaps I should stop trying to understand this all, without actually having seen all the maths and stuff.

Again, thanks a lot!

Toolmaker

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!