Why use glm::LookAt in OpenGL? - opengl

After reading on the coordinate systems in OpenGL, I figured to move the camera around the world I just need to translate the view coordinates. If I say use view = glm::translate(view, glm::vec3(0, 0, -50));, I'm translating the camera 50 units back (by translating the world 50 units forward). After thinking I had it figured out, I encounter LookAt function. I can't understand why I would need to use this function, if I just can move around my camera by translating and rotating the view. The whole thing is a bit hard to wrap the head around, so I'm sorry if this doesn't make much sense!

glm::LookAt or mat4x4_look_at of linmath.h or gluLookAt, and so on, are all just there for your (= the programmer's) convenience. That's all.
If you want to setup the view portion of the modelview transform with a different method, because it suits you better, then by all means you should to that then.

Related

How would I go about moving in a 3D environment, openGL c++

I'm not quite sure on how I should be making things move using openGL.
Am I supposed to be moving the camera's position around the 3D world, or moving/translating the objects around the camera?
I read online that the camera should stay at the origin and everything else should move around the camera, but wouldn't that be an intensive operation? Like if I have 1000 objects and I'm moving, we'd have to move all of these objects. Would it not be easier to move the camera and keep the world objects where they are?
The way OpenGL works is, conceptually, the camera is always in the center, Y axis up and Z axis forward. If you want to move or rotate the camera, you actually move everything else the opposite way.
This is opposed to Direct3D for example, where you have a separate camera matrix.
It's a minor detail though because mathematically speaking they're exactly the same. Whether you move everything forward or the camera back, it's exactly the same end result. You could even argue that having only one matrix as opposed to lugging around two and multiplying them is a performance gain, but it's extremely minor and usually you'll separate your camera matrix from your world building matrix anyway.
In Opengl, the camera is always located at the eye space coordinate (0., 0., 0.). To give the appearance of moving the camera, your OpenGL application must move the scene with the inverse of the camera transformation.
You don't need to worry about moving/translating objects in your scene. gluLookAt() function does it for you. This function computes the inverse camera transform according to its parameters and multiplies it onto the current matrix stack.

Rotating a 3d world in LuaGL or OpenGL

I was just wondering how one would rotate a 3d world in either LuaGL or OpenGL. The problem I have is that when I rotate, at somepoint when I am near a wall in my program, I end up either in the wall or outside of the room I built. Not exactly sure why this is, and it's even harder because a lot of programming code I look at is either C or C++ oriented. I have checked out NEHE already and again it is C or C++ oriented, not Lua oriented.
the problem is that you are rotating everything about their world space coordinates, to fix this, you would need to make the origin of your object equal to the point around which you wish to rotate, then rotate and then translate it to where it should be.
So for example if you just want to rotate your world, you would need to make sure that the world matrix of each object you are drawing is equal to the identity matrix.
In graphics we go by the principle of scaleMatrix * rotationMatrix * translationMatrix.
Here is an example of what your draw method for an object might look like.
You should consider looking at glm for handling your matrices though, I've found it to work much better.
glPushMatrix();
glLoadIdentity();
glScale();
glRotate();
glTranslate();
glPopMatrix)();

FPS camera in c++ maybe using glm:lookat

I have a rather simple setup, a model at 0,0,0, with:
projection = glm::perspective(fov, aspectRatio, near, far);
model = glm::mat4(1.0);
I want a flexible camera, which is, from what I read the best described as FPS camera.
Now I am having:
glm::mat4 CameraMatrix = glm::lookAt(
glm::vec3(cameraPosition.X,cameraPosition.Y,cameraPosition.Z), // camera, in world space
glm::vec3(cameraTarget.X,cameraTarget.Y,cameraTarget.Z), // direction vector eye + Dir
glm::vec3(upVector.X,upVector.Y,upVector.Z)
);
very much as described here: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-6-keyboard-and-mouse/
This is working out fine except one thing, mouse up and down does as intended, but left-right rotation the mouse makes the model rotating around cameraposition and not camera rotating around the model? Did I make something wrong?
My impression is that this requires at least some additional rotation and maybe translation to make it work correctly. If so, I am wondering why this seems to be mentioned nowhere. There are plenty of tutorials using lookat also if referring to "FPS camera" when I google for it. This confuses me a bit.
Now the examples around glm::lookat are rather poor and I read some stuff for gluLookAt in which I heard some voices that at least gluLookAt is no solution for such a task, does the same apply to glm::lookat? And if so, what's the right way to go? I am really not bound to glm:lookat in any way, it's just when I stumbled across it, I was like "HEY! Just what I was looking for" and it seems to be a clean and easy solution.
Maybe someone can shed some light on this and point me into the right direction or tutorial.
it appeared to be that one of my matrices was upside down, causing this problem.
The tutorial mentioned above was very helpful to find out. So if anyone stumbles across such an issue, it can be a simple math problem and indeed glm::lookAt does all I need.

How do I implement basic camera operations in OpenGL?

I'm trying to implement an application using OpenGL and I need to implement the basic camera movements: orbit, pan and zoom.
To make it a little clearer, I need Maya-like camera control. Due to the nature of the application, I can't use the good ol' "transform the scene to make it look like the camera moves". So I'm stuck using transform matrices, gluLookAt, and such.
Zoom I know is dead easy, I just have to hook to the depth component of the eye vector (gluLookAt), but I'm not quite sure how to implement the other two, pan and orbit. Has anyone ever done this?
I can't use the good ol' "transform the scene to make it look like the camera moves"
OpenGL has no camera. So you'll end up doing exactly this.
Zoom I know is dead easy, I just have to hook to the depth component of the eye vector (gluLookAt),
This is not a Zoom, this is a Dolly. Zooming means varying the limits of the projection volume, i.e. the extents of a ortho projection, or the field of view of a perspective.
gluLookAt, which you've already run into, is your solution. First three arguments are the camera's position (x,y,z), next three are the camera's center (the point it's looking at), and the final three are the up vector (usually (0,1,0)), which defines the camera's y-z plane.*
It's pretty simple: you just glLoadIdentity();, call gluLookAt(...), and then draw your scene as normally. Personally, I always do all the calculations in the CPU myself. I find that orbiting a point is an extremely common task. My template C/C++ code uses spherical coordinates and looks like:
double camera_center[3] = {0.0,0.0,0.0};
double camera_radius = 4.0;
double camera_rot[2] = {0.0,0.0};
double camera_pos[3] = {
camera_center[0] + camera_radius*cos(radians(camera_rot[0]))*cos(radians(camera_rot[1])),
camera_center[1] + camera_radius* sin(radians(camera_rot[1])),
camera_center[2] + camera_radius*sin(radians(camera_rot[0]))*cos(radians(camera_rot[1]))
};
gluLookAt(
camera_pos[0], camera_pos[1], camera_pos[2],
camera_center[0],camera_center[1],camera_center[2],
0,1,0
);
Clearly you can adjust camera_radius, which will change the "zoom" of the camera, camera_rot, which will change the rotation of the camera about its axes, or camera_center, which will change the point about which the camera orbits.
*The only other tricky bit is learning exactly what all that means. To clarify, because the internet is lacking:
The position is the (x,y,z) position of the camera. Pretty straightforward.
The center is the (x,y,z) point the camera is focusing at. You're basically looking along an imaginary ray from the position to the center.
Now, your camera could still be looking any direction around this vector (e.g., it could be upsidedown, but still looking along the same direction). The up vector is a vector, not a position. It, along with that imaginary vector from the position to the center, form a plane. This is the camera's y-z plane.

Best way to make a camera both move and rotate

I'm learning some OpenGL game programing, and I'm stuck in how to implement so the camera follows the mousepointer. Like in a fps game you want to look where your mouse is pointing, but I can't find a nice solution to this while I'm moving. I was thinking of saving one matrix for the move, like walkking and strafing, while using quaternions to handle the rotation. Then make the quaternion to a rotationmatrix, load the identity for the modelview matrix and time this matrix with both matrixes.
There is ofcourse some problems with this, like which matrix we should use in the multiplication first, and the code will be ugly.
So I'm wondering if anyone have a good solution to solving this, so I don't have to find out which matrix to use first, and which gives cleaner code.
Store the camera's view details as a position vector, a view-vector and an up-vector (think of pointing with your thumb stuck out: your finger is the view-vector, and your thumb is the up-vector). Keep these vectors normalized and at 90 degrees to each other. You should be able to see that these three vectors are sufficient to represent any camera position and orientation.
You can use these vectors to transform world-coordinates to camera-coordinates:
Translate by -position;
Rotate around (up-vector 'cross' y-axis) by -(angle between up-vector and y-axis);
Rotate around up-vector by -(angle between view-vector and z-axis).
(I might have got some of my signs the wrong way around there).
You can transform these vectors as the user moves the mouse:
As the mouse moves sideways, rotate the view-vector around the up-vector (or rotate both view-vector and up-vector around y-axis, if you prefer).
As the mouse moves back/forwards, rotate both the view-vector and up-vector around (view-vector 'cross' up-vector).
I don't really have a solution for your problem, but i know the open-source 3d engine Irrlicht has a FPS camera that does exactly what you're looking for and, usually, it has a well-documented source.
You could try looking at how the FPS camera is implemented in Irrlicht or you could even use Irrlicht itself for your project; i used it for a couple of mine when i was in college and it always worked like a charm :)