How to Translate Camera after Rotating the Scene?

Started by aieong19, April 03, 2012, 01:29:36 AM

Previous topic - Next topic

aieong19

Hello all,

I am new here and new to OpenGL. For a school project, I am trying to use OpenGL and GLUT to render a city scene with multiple buildings in it. Then, I have to do a camera "fly through" around the city and capture the whole process.

I have the city properly rendered. But I have ran into a issue with coding proper control for my camera.

I will try to explain my approach here as clear as possible without going on forever:

What I am trying to do is to control my camera, or more accurately the movement of the scene, in ways similar to a first person video game.

Here is what I mean:

'w' - Move Forward
's' - Move Backward
'a' - Turn Left
'd' - Turn Right
'q' - Strafe Left
'e' - Strafe Right

I implemented this by changing the parameters inside gluLookAt()and by rotating the scene as needed.

Here is how I set up my gluLookAt():
gluLookAt(xPos,yPos,zPos, xLookAt,yLookAt,zLookAt, 0,1,0);

So, for example, every time I press, say 'w'(Forward), zPos and zLookAt are decremented for a certain amount. Likewise, if I press 'q'(Strafe Right), xPos and xLookAt are decremented for a set amount, so on and so forth.

To turn and face a different direction, I rotate the scene instead of rotating the camera (Mainly because I don't know how to rotate the camera). So, when 'a' is pressed,I decrements a valuable call angle_x and perform the rotation like so: glRotatef(Transformations::angle_x, 0.0, 1.0, 0.0);

To make the rotation seems like it is rotating about the camera, I do the following:

glTranslatef(xPos,yPos,zPos);
glRotatef(Transformations::angle_x, 0.0, 1.0, 0.0);
glTranslatef(-xPos,-yPos,-zPos);
drawBuildings();

Everything works perfect except for one thing. I cannot change the orientation of the camera after the rotation. So imagine forward is pointing North initially and I make a 90 degree rotation and I am now appeared to be looking toward East. If I press forward on my keyboard now my camera still moves toward north, which now would appears to be moving to the left and not what I want.

I have tried many ways of messing with the order of translation and rotation and I still couldn't figure out a solution. I looked through the internet and found people talking about updating the direction vector of the camera or something like that but I couldn't understand their approach posted.

I am hoping someone here would be able to give me some idea as to what I can do. Any comment would be greatly appreciated!

Thank you very much for reading so much!

Farabi

It is very difficult to understand at first, but after you get the logic behind it, it very simple.




fCam struct
Position VERTEX <0.0>
Rotation VERTEX <0.0>
fCam ends

fCameraMove proc uses esi edi lpcamera:dword,fp4distance:dword
LOCAL x[16]:real4
LOCAL buff[256]:dword
LOCAL q:qword
LOCAL py,px:dword
LOCAL m[16]:dword
mov esi,lpcamera

invoke glPushMatrix
invoke glMatrixMode,GL_MODELVIEW
invoke glLoadIdentity
invoke fMat4fRotate,addr m,RROTATE_X,[esi].fCam.Rotation.x
invoke fMat4fRotate,addr m,RROTATE_Y,[esi].fCam.Rotation.y
invoke fMat4fRotate,addr m,RROTATE_Z,[esi].fCam.Rotation.z
invoke glGetFloatv,GL_MODELVIEW_MATRIX,addr x
lea edi,x
invoke glPopMatrix

fld dword ptr[edi+2*4]
fmul fp4distance
fstp dword ptr[edi+2*4]
fld dword ptr[edi+6*4]
fmul fp4distance
fstp dword ptr[edi+6*4]
fld dword ptr[edi+10*4]
fmul fp4distance
fstp dword ptr[edi+10*4]

fld  [esi].fCam.Position.x
fadd dword ptr[edi+2*4]
fstp [esi].fCam.Position.x

fld [esi].fCam.Position.y
fadd dword ptr[edi+6*4]
fstp [esi].fCam.Position.y

fld [esi].fCam.Position.z
fadd dword ptr[edi+10*4]
fstp [esi].fCam.Position.z
ret
fCameraMove endp

fCameraLook proc uses esi lpcamera:dword
LOCAL cpos:real4
LOCAL m[16]:real4

invoke glMatrixMode,GL_MODELVIEW;
invoke glLoadIdentity
invoke gluPerspective,FP8(45.0),FP8(1.0),FP8(1.0),FP8(10000.0)

mov esi,lpcamera
invoke fMat4fRotate,addr m,RROTATE_X,[esi].fCam.Rotation.x
invoke fMat4fRotate,addr m,RROTATE_Y,[esi].fCam.Rotation.y
invoke fMat4fRotate,addr m,RROTATE_Z,[esi].fCam.Rotation.z

invoke glTranslatef,[esi].fCam.Position.x,[esi].fCam.Position.y,[esi].fCam.Position.z

ret
fCameraLook endp



How to use it
Quote
.data

.if WM_INIT
Fld FP4(0.0)
      fstp CurrCam.Position.x
      Fld FP4(0.0)
      fstp CurrCam.Position.y
      Fld FP4(0.0)
      fstp CurrCam.Position.z
      
      Fld FP4(0.0)
      fstp CurrCam.Rotation.x
      Fld FP4(0.0)
      fstp CurrCam.Rotation.y
      Fld FP4(0.0)
      fstp CurrCam.Rotation.z
      invoke fCameraLook,addr CurrCam
invoke fCameraMove,addr CurrCam,FP4(0.0)

.if OnRender
   invoke IsPressed,"A"
   .if eax==1
      fld1
      fchs
      fadd CurrCam.Rotation.z
      fstp CurrCam.Rotation.z   
   .endif
   
   invoke IsPressed,"D"
   .if eax==1
      fld1
      fadd CurrCam.Rotation.z
      fstp CurrCam.Rotation.z
   .endif
   
   invoke IsPressed,"W"
   .if eax==1
      invoke fCameraMove,addr CurrCam,FP4(1.1)
   .endif
   
   invoke IsPressed,"S"
   .if eax==1
      invoke fCameraMove,addr CurrCam,FP4(-1.1)
   .endif
invoke fCameraLook,addr CurrCam   
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"