Jump to content

  • Log In with Google      Sign In   
  • Create Account


Objects and Cameras in a 3D world, OpenGL


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 Rotti   Members   -  Reputation: 100

Like
0Likes
Like

Posted 06 September 2011 - 01:58 PM

Hi

I'm working with C++. I think I'm slowly but surely understanding the the modelview matrix and how changing it, changes what you see.
I've read a lot about guys talking about there is no camera and all that jazz, It starting to make sence, but its stil a trip. I've read about and looked at the glLookat function,
some guy gave the source code for it somewhere, and I understand what happens there. The parameters are all in terms of the Object frame. I'm planning on using it, so bare with me.

Now, I'm imagining a scene, a 3d world with objects(say cubes) and a camera, I realize that the modelview matrix needs to be set by the glLookat function for each object in the world, depending on where the object is in relation to the camera. Each object is designed in its own frame and has its origin at the middle of the object. So we have the object frames, which are the floating cubes, we have the scene frame(which openGL knows nothing of?), which is the frame that says where all the objects and the camera is, then we have the camera frame.

If I'm on the right track my question should be:

How do I use the info(x,y,z co-ordinates, rotations ,lookat vector) of the objects and the camera in the scene frame, to compute the parameters I need to pass to the glLookat function for each object just before you draw it?

Please point me in the right vector direction. :P

Sponsor:

#2 L. Spiro   Crossbones+   -  Reputation: 13222

Like
0Likes
Like

Posted 06 September 2011 - 03:29 PM

I have never used that function and never will. It is typically more efficient to make your own matrices (using a math library if necessary) and I suggest you start along the right track as soon as possible.

To use glLookat(), you should set the modelview matrix to identity, call glLookat(), and then set the model transform matrix. Then you are prepared to render one object.

If you push the matrix stack before applying the model’s matrix, you can pop it off and push the next model matrix for each following object.
Otherwise you have to repeat the entire process starting with an identity matrix.


Typically, if you plan to do any serious work with OpenGL, you will make up for OpenGL’s lack of a camera by making your own. Your graphics library would keep track of a view matrix and a model matrix and combine them before rendering—if they have changed—to create the modelview matrix.


L. Spiro
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#3 dpadam450   Members   -  Reputation: 884

Like
0Likes
Like

Posted 06 September 2011 - 05:43 PM

If all those boxes are centered at 0,0,0 (on top of you). Then you want to rotate them first, translate them to their world position, and from there apply your camera (gluLookAt). Objects that say are not rotated, would just be translated in the world, but relative to your computer screen/the viewer, they will show up in different positions of the screen. So you first need the object in the right world position before you describe it relative to someone in the world.

I realize that the modelview matrix needs to be set by the glLookat function for each object in the world, depending on where the object is in relation to the camera.

If your boxes never move, then the only portion of the final modelview matrix that is changing is the gluLookAt function.

#4 latent   Members   -  Reputation: 139

Like
0Likes
Like

Posted 06 September 2011 - 06:09 PM

Now, I'm imagining a scene, a 3d world with objects(say cubes) and a camera, I realize that the modelview matrix needs to be set by the glLookat function for each object in the world, depending on where the object is in relation to the camera. Each object is designed in its own frame and has its origin at the middle of the object. So we have the object frames, which are the floating cubes, we have the scene frame(which openGL knows nothing of?), which is the frame that says where all the objects and the camera is, then we have the camera frame.

If I'm on the right track my question should be:

How do I use the info(x,y,z co-ordinates, rotations ,lookat vector) of the objects and the camera in the scene frame, to compute the parameters I need to pass to the glLookat function for each object just before you draw it?


It's pretty straighforward to do this with GL. You simply need to do something like this:
  • Set up your camera matrix (gluLookat)
  • For each object in your world:
  • Push the camera matrix onto the stack.
  • Translate, Rotate and Scale your object from Object coordinates to World coordinates.
  • Pop the camera matrix back out
Since you already have code that mostly does this, this will get you working. Later, using your own matrix library will allow you to eliminate the push/pop step and realise a few other optimisations along the way.


A quick and (very) dirty example of the above might be:
//We've previously done GL_PROJECTION
#define VEC(k) (k).x,(k).y,(k).z
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookat(VEC(eye), VEC(dir), VEC(up));
for(int i = 0; i < objects.size(); i++) {
  glPushMatrix();
  glTranslatef(VEC(objects[i].pos));
  glRotatef(VEC(objects[i].rotation));
  Render(objects[i]);	//your rendering code goes here.
  glPopMatrix();
}









#5 _Pickle_   Members   -  Reputation: 102

Like
1Likes
Like

Posted 06 September 2011 - 09:04 PM

If you dont want to make a math library yourself take a look at this:
http://cmldev.net

Ive been using this for all of my vector/matrix operations. I has the Lookat function you refer to and ive use it in my camera code to translate objects into the correct camera positions.

#6 Trienco   Crossbones+   -  Reputation: 2121

Like
0Likes
Like

Posted 06 September 2011 - 11:10 PM

To add to all of this confusion:

-If you call LookAt more than once per frame, you are doing it wrong (you set your camera once and then do the objects transformation between push and pop). Of course there are exceptions, if you want to draw from different angles or just drawing some GUI overlays (it would be plain stupid to set a "camera" and then desperately transform your GUI elements around to appear in a fixed position).

-No, you do not have to use LookAt. In fact, I'd strongly suggest looking at what it does and understanding the point of it. The parameters are supposed to describe your imaginary camera object (and it's LOCAL up vector.. blindly always passing (0,1,0) is wrong.. imagine a pencil stuck in the top of your head.. "up" is where the pencil is pointing, but since LookAt only needs a very rough direction (0,1,0) happens to work in 50% of all cases)

-LookAt essentially creates a transformation matrix for your imaginary camera like it was just any other object... then inverts it to "move the world the opposite way"
f@dzhttp://festini.device-zero.de

#7 Rotti   Members   -  Reputation: 100

Like
0Likes
Like

Posted 07 September 2011 - 03:53 PM

Hi

Thanks everyone, I enjoyed your comments.

@latent
thanks for that bit of code, I made this just to test the waters:

glLoadIdentity();
gluLookAt(10,20,20, 0,0,0, 0,1,0);
int i,j,k;
for (i =0; i<10 ; i++)
{
for (j =0; j<10 ; j++)
{
for (k =0; k<10 ; k++)
{
glPushMatrix();
glTranslatef(-i, -j, -k);
glScalef(0.3,0.3,0.3);
tetrahedron(n);
glPopMatrix();
}
}
}

It draws the tetrahedrons, 10 by 10 by 10, and the gluLookAt makes the camera sit at a nice birds I eye point of view at (10,20,20) to view the big cube of objects.
This is great, makes a lot of sence the setting of the models and the the setting of the view.

@Trienco
It seems that this is one of those times the (0,1,0) vector does work. I do understand that this is not write though, it should be like the pencil. So how do I go about calculating it before I set the view matrix by gluLookAt(); ? I've got the lookat vector... ok, something happend to that vetcor to change it from (0,0,-1) down the negative z axes to the bird's eye vector (-10,-20,-20) ? and that same thing needs to happen to the pencil vector while its stil pointing at (0,1,0)? Do you think this problem can be avoided by not using the gluLookAt and by making the view matrix myself?

If so?

Making and implementing a small math library sounds tough. Were do I start?

I want to fly around in this world!

#8 _Pickle_   Members   -  Reputation: 102

Like
0Likes
Like

Posted 07 September 2011 - 05:34 PM

Rolli I think you only have to change the up vector if you intend to let the camera flip. For example I have setup a camera that acts like a first person shooter using lookat. I limit my pitch to +/- 89 degrees, otherwise if I let pass over the the 90 degree point the camera will flip since the up vector is still pointing up.
I might be able allow 360 degrees if I inverted the up vector when i hit the 90 degree point.

Edit: also the link to the cml library provides any math related operation you would ever need. Using it you can get rid of glu, not use the gl library matrix api( other than glMatrixMode and glLoadMatrix). Im glad I took this approach as it helped adding opengl 2.0 support. > 2.0 does not support matrix api like 1.X does.

#9 Trienco   Crossbones+   -  Reputation: 2121

Like
0Likes
Like

Posted 07 September 2011 - 11:05 PM

The answer depends on how you keep track of your orientation. The naive approach everybody falls for is to say "I'll just store three angles around x,y,z and maybe call them yaw, pitch, roll... then I'll realize it starts acting funny when I accumulate my rotations.. and then somebody claims that quaternions are the only salvation, because when someone struggles with matrix math or trigonometry, suggesting a method based on multidimensional imaginary numbers is always a hoot".

The only time this works painlessly is for first person shooter like cameras (where rotations are very limited). If that's what you want anyway, then just flip your "up" when pitch is beyond -90;90 degree (and avoid exactly +-90 degree).

Bottom line, don't use Euler angles. And once you start keeping track of at least two vectors (up and forward) and a position, you're just one step away from storing the actual matrix (which in addition has "right" in it's first column).

I want to fly around in this world!


If that includes flying loopings, then you should probably just forget about those LookAt helper functions, since eventually they just make things more messy and require more manual tracking of stuff that should be kept in a transformation matrix.

Get any matrix library of your choice (or write one yourself, but why would you do that?). Treat the camera like any other object by multiplying rotations and translations to it (in the right order).

camTransform = rotationMatrix * camTransform;

For the rare situation where you want to rotate or move around/along global axes you need to invert the order

camTransform = translateForwardMatrix * camTransform; //Translate by (0,0,1) is forward
camTransform = camTransform * translateNorthMatrix; //Translate by (0,0,1) is "north" (given that world z axis actually is north/south)

Before each frame you ditch look at and use

viewMatrix = camTransform.inverse();
glLoadMatrix(viewMatrix);

You skip the whole "when is up no longer up anymore" nonsense and instead of piecing together that matrix from scratch and invert it by calling lookat, you just update and invert it yourself.
f@dzhttp://festini.device-zero.de

#10 dpadam450   Members   -  Reputation: 884

Like
0Likes
Like

Posted 07 September 2011 - 11:13 PM

Making and implementing a small math library sounds tough. Were do I start?

You don't really need one. My math library is just vectors (vec3, vec4).

To fly, do you know trigonometry (sine/cosine)? You can use the z-axis vector and can compute the direction to move the camera (target - eye position).

#11 Rotti   Members   -  Reputation: 100

Like
0Likes
Like

Posted 12 September 2011 - 02:57 AM

Thanks guys

Please take a look at what I made over the weekend:

I'm stil using gluLookAt, but I'm doing quite a lot of trig, evertime the mouse moves, is this very expensive? this very basic app, doesn't seem to have any problems with it at the moment.

http://www.userotti.com/opengl/planets.zip

I'm using the "glut32.dll"

so I think its windows only...




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS