1
\$\begingroup\$

I am trying to learn OpenGL and am doing some beginners learning exercises. One of the exercises is to translate and then to rotate the camera along its own local coordinates and not the world coordinate system.

I am at a loss at how to do one vs the other. I'm aware how to perform translations and rotations using glTranslatef() and glRotatef() functions. Through research I'm also aware of using the 4x4 transformation matrix to multiply our vector/s with to create the desired transformations, although I've not yet messed around with it personally so I'm not too familiar with the transformation matrix.

This being said, I still have questions regarding the local vs world coordinates. I understand that we can put into effect translations and rotations via these functions or the transformation matrix, but I'm concerned with understanding how we do one vs the other. I haven't found any explicit code/examples of transforming a camera (or a model, but I'm more concerned with the camera in this instance) with respect to the world coordinates, and likewise for transforming it with respect to its local coordinates. I feel like at this point I need something rather explicit, because I've felt confused for several days now.

Furthermore, there may be some conceptual things I am confused about. This is to my understanding: If we strictly move objects and the camera (which to my understanding functions like any other object in the world) by the local coordinate system, does that mean that all the local coordinate systems share the same position of their origin with each other and the origin of the world coordinate system? Then, on the other hand, if we strictly move objects/camera with respect to the world coordinate system, then all objects will always be on their own local coordinate system's origin, right? And assuming no object is positioned on the same spot, then no local coordinate systems origin will be positioned on the same spot, right?

\$\endgroup\$
1
\$\begingroup\$

The glTranslatef() and glRotatef() calls are fixed function old-style OpenGL. It's best to forget about them.

Modern OpenGL uses vertex and fragment shaders, and it is up to your shader to project your geometry onto the screen.

To do this, vertices of your model have to be multiplied with what is called the "Model View Projection Matrix." Please bear with me for now before I address your question.

The Model-View-Projection matrix is just as the name implies: the multiplication of three matrices:

  • Model Transformation Matrix
  • View Transformation Matrix
  • Projection Matrix

The Model Transformation Matrix represents how your model is positioned, oriented and scaled into the world. If you place your model at pos (4,5,6) for instance, this matrix would be:

1 0 0 0 // row0: the x-axis (1,0,0)
0 1 0 0 // row1: the y-axis (0,0,1)
0 0 1 0 // row2: the z-axis (0,0,1)
4 5 6 1 // row3: the position

The first three rows determine how the object is oriented (and scaled.) These axes need to be perpendicular to each other of course. The last row determines where the object is placed.

Here's the kicker: the View Transformation Matrix is nothing more than the inverse of the Camera Transformation Matrix.

So your program will place the camera in the world, using a transformation matrix just as it places objects in your world as described above.

When it is time to render your world, you take your Camera Transformation Matrix and invert it.

Mᵥᵢₑ ≔ Mcₐₘ ⁻¹

Generating a Projection Matrix is typically done only if the window is resized, and your window aspect ratio changes.

For how to create a projection matrix, for instance a perspective projection, you can read up here.

Multiply the model matrix with the view matrix, and multiply the result with the project matrix to get the fully concatenated Model-View-Projection Matrix.†

You typically pass this Model-View-Projection Matrix as a uniform to your vertex shader, which will multiply the vertices and normals with it. gl_Position = modelviewprojmat * pos;

Now to finally get back to your original question, how to move the camera in its local space.

So remember how we now keep track of a camera transformation matrix. It places the camera in your scene. To move or rotate your camera in its own reference frame, you can simply manipulate this matrix using information from that very same matrix.

An example: To make the camera step 0.2 units to the left, just get the Y-axis from the camera matrix by doing:

axis = cam_mat.getRow(1)      // get camera's Y axis, which points to the left
campos = cam.getRow(3)        // get camera's current position
campos = campos + axis * 0.2  // move it 0.2 units to the left
cam.setRow(3, campos)         // set the camera's new position

Another example: To make the camera yaw left and right, you rotate transformation matrix over its own z-axis. So you get the 3rd row of the camera matrix, and use that with an angle to create a rotation matrix. Apply that rotation to your camera transform, and the result will be the camera rotated using its own frame of reference.

Once you have updated the camera transform to your liking, you invert it to get the view transform, and combine it with projection and model transforms, and pass the result to your shader.

(†) Note that depending on convention, the matrix multiplication order is often proj * view * model, as the vertex is typically post-multiplied.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.