Archived

This topic is now archived and is closed to further replies.

Rickwi22

Moving the camera

Recommended Posts

Ive just started learning OpenGL in C++, I know DX8. Im only learning from NeHe, And Ive gotten to tutorial 17 or something, anyway, Ive made several complex scenes and can move them around but nowhere in the tutorials does it say how to move the camera around, If it does and I missed it tell me, If it doesnt please let me know how, Can you move the camera around with glTranslate(); and glRotate();, or do you have to use matrices or something, Im stumped, please let me know. Thanks

Share this post


Link to post
Share on other sites
glTranslate and glRotate use matrices, but you don''t have to deal with them in the detail that you do with DX8.

It''s important to realise that there is no camera. An OpenGL FAQ page has info about simulating a camera.
http://www.frii.com/~martz/oglfaq/viewing.htm#view0010


Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions

Share this post


Link to post
Share on other sites
quote:
It''s important to realise that there is no camera. An OpenGL FAQ page has info about simulating a camera
Thanks Ill check
it out

Share this post


Link to post
Share on other sites
I tried that and the wierdest thing happened, One of my objects moved, while the other one did not. Here is my camera code
  glMatrixMode(GL_MODELVIEW);		
glLoadIdentity();
gluLookAt(camx,camy,camz,0.0f,0.0f,-6.0f,0.0f,1.0f,0.0f);
glTranslatef(0.0f,-2.0f,-6.0f);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_POLYGON);
glTexCoord2f(0.0f,0.0f);
glVertex3f(-2.0f,0.0f,2.0f);
glTexCoord2f(0.3f,0.0f);
glVertex3f(-2.0f,0.5f,2.0f);
glTexCoord2f(0.7f,0.0f);
glVertex3f(-3.0f,0.7f,3.0f);
glTexCoord2f(0.7f,1.0f);
glVertex3f(-3.0f,0.7f,-3.0f);
glTexCoord2f(0.3f,1.0f);
glVertex3f(-2.0f,0.5f,-2.0f);
glTexCoord2f(0.0f,1.0f);
glVertex3f(-2.0f,0.0f,-2.0f);
glTexCoord2f(1.0f,1.0f);
glVertex3f(2.0f,0.0f,-2.0f);
glTexCoord2f(1.0f,0.0f);
glVertex3f(2.0f,0.0f,2.0f);
glEnd();
glLoadIdentity();
glTranslatef(0.0f,-1.5f,-6.0f);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glEnable(GL_BLEND);
glBegin(GL_POLYGON);
glColor4f(1.0f,1.0f,1.0f,0.5f);
glTexCoord2f(1.0f,0.0f);
glVertex3f(-2.0f,0.0f,2.0f);
glTexCoord2f(1.0f,1.0f);
glVertex3f(-2.0f,0.0f,-2.0f);
glTexCoord2f(0.0f,1.0f);
glVertex3f(2.0f,0.0f,-2.0f);
glTexCoord2f(0.0f,0.0f);
glVertex3f(2.0f,0.0f,2.0f);
glEnd();
glDisable(GL_BLEND);

When i increase the value of camz, the first object, with texture[0], moves back and forth, but the second object with texture[1] does not, what could be happening, If you need to see more of my code let me know.

Share this post


Link to post
Share on other sites
I think i know why. The gllookat is like a rotate and translate function in 1. When you call glLoadidentity it resets back. Either find a way to only call glloadidentity once, or call gllookat everytime you glloadidentity.

Share this post


Link to post
Share on other sites
Yep it worked fine, I wonder if there is a better way to do it though, it seems kind of redundant to do that every time I add an object to my code.

EDIT, NOOOOO, I tried to modify both the camx, and camz values, and my object went out of control in all different directions,definitly not what it was supposed to do, What is going on, Please will some OGL guru help me out.
Ill be going to bed, so Ill reply back later.
[edited by - rickwi22 on May 6, 2002 8:58:47 PM]

[edited by - rickwi22 on May 6, 2002 8:59:56 PM]

Share this post


Link to post
Share on other sites
Theres been some misinformation spread in this thread, so I thought I'd clarify a couple of things.

Here's how camera positioning works:

The camera position is always at the position 0,0,0. Moving the camera is an illusion. Instead, you rotate or translate the modelview matrix to move all the objects in the world, which gives effect of moving the camera. So, you might call glTranslatef(-1,0,0) to move the "camera" (1,0,0).

gluLookat does the glTranslate/glRotate stuff for you, and glLoadIdentity resets the modelview matrix. What you are doing in your code is setting up your camera transform, then you're clearing it with glLoadIdentity before you draw the second object, which is why the second object bears no relation to your camera position.

What you should be doing is this:


      
glLoadIdentity();
glPushMatrix(); //store the identity matrix on the stack

gluLookat(...); //setup camera transform

glPushMatrix(); //store camera transform on the stack

glTranslatef(...); //move drawing position by translating modelview

...draw stuff...
glPopMatrix(); //revert to the saved camera

glPushMatrix(); //save the camera position on the stack

glTranslatef(...); //move drawing position by translating modelview

...draw more stuff...
glPopMatrix();//go back to the saved camera position

glPopMatrix();//go back to the identity matrix



____________________________________________________________
www.elf-stone.com

[edited by - benjamin bunny on May 6, 2002 9:49:21 PM]

Share this post


Link to post
Share on other sites
I did what you said and the behaviour was, the same, I realized what I did, I had moved the the x , and z coordinates, but I never moved the look coordinates, so It seemd really wierd. Heres my code now,
    glLoadIdentity();	
glPushMatrix();
gluLookAt(camx,camy,camz,0.0f,0.0f,-6.0f,0.0f,1.0f,0.0f);
glPushMatrix();
glTranslatef(0.0f,-2.0f,-6.0f);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_POLYGON);
glTexCoord2f(0.0f,0.0f);
glVertex3f(-2.0f,0.0f,2.0f);
glTexCoord2f(0.3f,0.0f);
glVertex3f(-2.0f,0.5f,2.0f);
glTexCoord2f(0.7f,0.0f);
glVertex3f(-3.0f,0.7f,3.0f);
glTexCoord2f(0.7f,1.0f);
glVertex3f(-3.0f,0.7f,-3.0f);
glTexCoord2f(0.3f,1.0f);
glVertex3f(-2.0f,0.5f,-2.0f);
glTexCoord2f(0.0f,1.0f);
glVertex3f(-2.0f,0.0f,-2.0f);
glTexCoord2f(1.0f,1.0f);
glVertex3f(2.0f,0.0f,-2.0f);
glTexCoord2f(1.0f,0.0f);
glVertex3f(2.0f,0.0f,2.0f);
glEnd();
//glLoadIdentity();

glTranslatef(0.0f,-1.5f,-6.0f);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glEnable(GL_BLEND);
glBegin(GL_POLYGON);
glColor4f(1.0f,1.0f,1.0f,0.5f);
glTexCoord2f(1.0f,0.0f);
glVertex3f(-2.0f,0.0f,2.0f);
glTexCoord2f(1.0f,1.0f);
glVertex3f(-2.0f,0.0f,-2.0f);
glTexCoord2f(0.0f,1.0f);
glVertex3f(2.0f,0.0f,-2.0f);
glTexCoord2f(0.0f,0.0f);
glVertex3f(2.0f,0.0f,2.0f);
glEnd();
glDisable(GL_BLEND);
glPopMatrix();
glPopMatrix();

But Now How the heck am i supposed to move it on its axis rather than the worlds axis, so if I move it on its z-axis, which it is facing on, when it is facing up on the world y-axis

[edited by - rickwi22 on May 7, 2002 8:38:57 PM]

Share this post


Link to post
Share on other sites
2 things:

Firstly, your code isn't exactly the same as mine. You're pushing the camera's view matrix, then translating, drawing and translating again. If you call gltranslate twice without popping back to the camera matrix in between, the second translate will be affected by the first translate. Is this your intent?

quote:

But Now How the heck am i supposed to move it on its axis rather than the worlds axis, so if I move it on its z-axis, which it is facing on, when it is facing up on the world y-axis


I'm not really sure what you're talking about. Can you be a bit more specific?

____________________________________________________________
www.elf-stone.com

[edited by - benjamin bunny on May 7, 2002 10:24:31 PM]

Share this post


Link to post
Share on other sites
Use an object heirarchy. This lets you handle sub objects more easily. Each object has similiar position systems with vectors. So in the hierarchy, the camera sits at the root and each object is transformed by it''s predecessor.



void RenderObj(Obj* obj) {

glPushMatrix();

glRotatef(obj->angle.x,1.0f,0.0f,0.0f);
glRotatef(obj->angle.y,0.0f,1.0f,0.0f);
glRotatef(obj->angle.z,0.0f,0.0f,1.0f);
glTranslatef(obj->pos.x,obj->pos.y,obj->pos.z);

// draw all your polygons for that object

for(int i=0; inum_children; i++) {
RenderObj(&obj->child);
}

glPopMatrix();
}

void RenderWorld() {

glLoadIdentity();

RenderObj(&CamObject);
}



Something like that but more complex.

Share this post


Link to post
Share on other sites
I mean does anyone know how I can move it forward in the direction it is facing, regardless of where it is facing in the world.
You are right, I just realized my code was not the same. My bad.

quote:
Yes, you just take the camera's forward vector (normalized hopefully) multiplied by the the speed, and there's your velocity vector. Translate the camera position by that.



What I mean is how do I do the things like compute the forward vector, normalize it, and then tranlsate the camera by that.
[edited by - rickwi22 on May 8, 2002 5:57:12 PM]

[edited by - rickwi22 on May 8, 2002 6:47:30 PM]

Share this post


Link to post
Share on other sites
Yes, you just take the camera''s forward vector (normalized hopefully) multiplied by the the speed, and there''s your velocity vector. Translate the camera position by that.

____________________________________________________________
www.elf-stone.com

Share this post


Link to post
Share on other sites
quote:

What I mean is how do I do the things like compute the forward vector, normalize it, and then tranlsate the camera by that.

That depends on your implementation. If you don''t care about movement up and down (as in Quake et al), your forward vector can be calculated very simply:


B
/|
1/ |
/ | vz
/a |
A--\--
vx

A->B is the facing vector
a is the camera''s angle around the Y axis (which you should already have)

vx is the the x part of the normal
vz is the z part of the normal.
vy is 0

You can calculate vx and vz like this
vx=cos(a)
vz=sin(a)

(bear in mind the math.h header deals with angles in radians, not degrees)


____________________________________________________________
www.elf-stone.com

Share this post


Link to post
Share on other sites
How I implement a camera in OpenGL:

I use the technique of moving the world in an inverse manner to the camera, i.e. all operations performed in reverse w/ negated values.

My camera class has several vectors (actually the camera has a motion-controller object within, which has these, but that''s another story):

pos // camera location in x/y/z
orient // camera rotation about x/y/z

and a scaler:

fov // camera field of view in degrees


Then I do this:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(camera.fov, viewport.aspectRatio, nearz, farz);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

My code supports multiple viewports, but the aspect ratio can be simply:
aspectRatio = (float) screen.width / screen.height


Then:
gluLookAt(0,0,0, 0,0,-1, 0,1,0); // set base eye view
glRotatef(-orient.x),1,0,0); // orient camera
glRotatef(-orient.y),0,1,0);
glTranslatef(-pos.x,-pos.y,-pos.z); // position camera
get_matrix() // extracts camera vectors for move/strafe operations

// ready to render...


The reason I do not use glulookat to do the camera positioning, is that for my needs when doing several types of billboards (some z-rotatable) I need to maintain a distinct camera orientation vector so I can easily unrotate, using gluLookat would leave you without such a vector.
And I also have a handy eye-relative in/out, up/down & left/right control via sliders, which is difficult to incorporate into glulookat. My actual gluLookat:

gluLookAt(eyex,eyey,eyez, eyex,eyey,eyez-1, 0.,1.,0.);

---------------------------------------------------

Now I can simply set the camera''s pos and orient vectors to whatever/wherever I need, by keys or program-control (my motion-controller class has 5 modes of programmable movement/orientation: MANUAL, ORBIT, LOOKAT, LOOKFROM, and HOLD, soon to have several more).

The more you treat things like cameras and lights like regular 3d objects, the easier it is.

zin


zintel.com - 3d graphics & more or less

Share this post


Link to post
Share on other sites
quote:
Original post by zin
The reason I do not use glulookat to do the camera positioning, is that for my needs when doing several types of billboards (some z-rotatable) I need to maintain a distinct camera orientation vector so I can easily unrotate, using gluLookat would leave you without such a vector.



Just multiply your modelview matrix by the inverse of the rotation matrix.

____________________________________________________________
www.elf-stone.com

[edited by - benjamin bunny on May 8, 2002 9:01:25 PM]

Share this post


Link to post
Share on other sites