How to implement an FPS camera without GLU on OSX (Or cross platform) c++
I'm trying to get an FPS style camera working, while following along from the examples in the openGL SuperBible book.
It was all going very well until I ran into the problem where you end up having roll happen, when you really only want pitch and yaw.
Similar question
This question is basically asking the same thing, but I was hoping someone might be able to be a bit more verbose about the implementation, ideally with experience of the SuperBible GLTools framework.
I've already tried implementing GluLookAt code which I've got to compile, but either I made a mistake when duplicating the functions needed, or I'm passing in the wrong parameters when using it.
I guess I'm finding it a bit confusing as the SuperBible code abstracts a bit of how the camera works, and so I'm finding it hard to implement it correctly. When testing my current version, I'm passing in parameters like this
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera); //returns the matrix of the CameraFrame.
M3DVector3f up = { 0.0f, 1.0f, 0.0f };
M3DVector3f look = { xHeading,yHeading,0.0f };
//xHeading & yHeading ranges from -1 to 1 based on mouse movement, is this correct?
How should I be managing and passing in the look variables? It appears currently that the look value is staying in the s开发者_JS百科ame place and so if I move backwards, I end up rotating around the scene.
glhLookAtf2(mCamera, mCamera, look, up);
I feel that I have to be managing my look direction better, and possibly my camera location as well. It seems odd that the look position doesn't seem to change.
Can anyone help, or point me in the direction of a solid tutorial path? I'm trying to avoid doing anything deprecated, but at this point I'd be really happy just to get something working.
It's easy task. You need just 3 vectors to handle camera: position, relative LookAt and relative Up vectors
After you set up those 3, you can supply those to gluLookAt like this:
gluLookAt(camera.eye.x,camera.eye.y,camera.eye.z,
camera.lookAt.x,camera.lookAt.y,camera.lookAt.z,
camera.up.x,camera.up.y,camera.up.z);
don't get confused, camera.lookAt is realtive LookAt added with eye vector:
camera.lookAt = camera.eye + camera.rLookAt;
So that should basically cover setting up a camera. What is next basic task with camera is moving. This is thanks to relative LookAt easy task, as you update just eye vector. You'll probably want to update also absolute LookAt, but that's same piece of code I showed above.
Lastly, you'll want to rotate view. What is tricky about that is that you can use 3 intepretations - matrices, 3 angles or quaterninons. Because angles are easy to understand (on other hand they have worst performance and suffers from gimbal lock) I'll show you how to do this. I won't describe what gimbal lock is, you can google this one, but to avoid it we need to limit rotations. We will use full 360° for horizontal but only 180° for vertical rotation. If you look on openGl coordination system, we can define horizontal rotations about Y axis and vertical arround X axis. For rotating a vector in app we use then these 2 codes:
vector3f vector3f::rotateX(const float &radians)
{
float t_y = y;
y = t_y*cos(radians) + z*sin(radians);
z = t_y*-sin(radians) + z*cos(radians);
return *this;
}
vector3f vector3f::rotateY(const float &radians)
{
float t_x = x;
x = t_x*cos(radians) + z*-sin(radians);
z = t_x*sin(radians) + z*cos(radians);
return *this;
}
You can see that I copy this from my code. vector3f is just a class wraping everything about 3D vectors. x,y and z are public members defining a vector.
So if you want pitch that's basicly rotateX and yaw rotateY. For updating your camera, you need rotate both relative LookAt and Up vectors, compute absolute LookAt and supply those to gluLookAt. That's all..
PS: Not true about few peoples programming opengl on OSX. I never ran OSX, but openGl as crossplatform is definitely still popular.
PSS: I forgot to mention, never add rotations. Better add angles and every time you rotate set vectors to default position and rotate with that absolute angle:
rLookAt.set(0,0,-1);
rLookAt.rotateX(rotations.x);
rLookAt.rotateY(rotations.y);
lookAt = eye + rLookAt;
up.set(0,1,0);
up.rotateX(rotations.x);
up.rotateY(rotations.y);
Thanks for everyones answers but the problem I had was this. In the openGL super bible, I was using their built in frame of reference class, and the problem I had was two functions, one called rotate, and rotateWorld.
I needed to use rotate for up/down movement, and rotateWorld for left right movement. This made the camera behave correctly (fly camera).
It makes sense as regardless of where you are looking up/down, you want the whole world to always spin around the vertical axis. Phew!
精彩评论