Skip to main content

What matrix gluLookAt generates? (1)

gluLookAt function

I use OpenGL API to draw a 3D scene. This API is often used in games. If you only use OpenGL world, you usually don't need to know what kind of matrices are created underneath the API. However, if you want to overlay the OpenGL scene, for instance, if you write a own renderer and still want to render the scene with OpenGL and own, it is sometimes useful to know what kind of matrices are computed in the OpenGL API.

Therefore, this blog entry is quite specific. If you are not interested in such story, see you next time.

I would like to talk about a matrix that is computed by gluLookAt function.

gluLookAt puts a camera with a position and camera posture, e.g., which is up direction. Recently, I need to know how to generate this matrix by my own, however, I could not find a good page with a good explanation. At the end, I looked into the source code of Mesa 7.5.1 (Mesa-7.5.1/src/glu/sgi/libutil/project.c), OpenGL software implementation.

The code is quite readable and has useful comments. Here is the Mesa 7.5.1's gluLookAt() source code.


/*
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 */
void GLAPIENTRY
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
          GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
          GLdouble upz)
{
    float forward[3], side[3], up[3];
    GLfloat m[4][4];

    forward[0] = centerx - eyex;
    forward[1] = centery - eyey;
    forward[2] = centerz - eyez;

    up[0] = upx;
    up[1] = upy;
    up[2] = upz;

    normalize(forward);

    /* Side = forward x up */
    cross(forward, up, side);
    normalize(side);

    /* Recompute up as: up = side x forward */
    cross(side, forward, up);

    __gluMakeIdentityf(&m[0][0]);
    m[0][0] = side[0];
    m[1][0] = side[1];
    m[2][0] = side[2];

    m[0][1] = up[0];
    m[1][1] = up[1];
    m[2][1] = up[2];

    m[0][2] = -forward[0];
    m[1][2] = -forward[1];
    m[2][2] = -forward[2];

    glMultMatrixf(&m[0][0]);
    glTranslated(-eyex, -eyey, -eyez);
}


By the way, I am always confused by OpenGL coordinate system and matrix contents. You can even find the folloing in the OpenGL official we pages. http://www.opengl.org/resources/faq/technical/transformations.htm

Column-major notation suggests that matrices are not laid out in memory as a programmer would expect.
It explicitly said you will be probably confused.

I usually first think them with the standard math notation and then interpret to the implementation. Here I would like to use the same strategy. If you would like to implement this with C/C++, then you need to think about the memory layout of your matrices.

Figure 1 shows camera coordinates (up) and the bottom figure shows the camera coordinate has no relationship with the global/world coordinates.

We can assume a camera is a rigid body object, therefore, you can move and rotate the camera. You might be able to extend, shrink, or crash a camera, but, we don't think about such operation on a OpenGL camera.

Figure 1: Camera coordinates. Camera coordinates and other coordinates

Before going to create a matrix, I would like to say one more, about model and view duality. This is:

  • If the scene is static (doesn't move), but your camera goes to forward 1m.
  • If your camera doesn't move, but whole other scene moved 1m backword from the camera.

The camera see exactly the same scene in these two cases. You might experienced when you are at a station on a train, waiting for the departure, sometimes you mistook you are now moving or the other side train is moving. This is an example of the camera movement or the scene movement (the other side train moved). This object movement (model) and camera movement (view) are conbined to the matrix called model-view matrix in OpenGL.

This story is about camera position and posture matrix, therefore it should be 'view matrix,' however, OpenGL says this matrix is model-view matrix since model view duality. In a implementation it is called modelview matrix, though I only talk about a view matrix.

Next time, I would like to talk about the matrices generated by gluLookAt.

Comments

myk said…
Excellent article! Thanks a lot! It would be great if you could please provide a link to this:

http://www.opengl.org/resources/faq/technical/viewing.htm

That article highlights the fact that there is no "camera" as such, in OpenGL. However, it does go on to tell that a camera concept can be implemented.

Popular posts from this blog

Why A^{T}A is invertible? (2) Linear Algebra

Why A^{T}A has the inverse Let me explain why A^{T}A has the inverse, if the columns of A are independent. First, if a matrix is n by n, and all the columns are independent, then this is a square full rank matrix. Therefore, there is the inverse. So, the problem is when A is a m by n, rectangle matrix.  Strang's explanation is based on null space. Null space and column space are the fundamental of the linear algebra. This explanation is simple and clear. However, when I was a University student, I did not recall the explanation of the null space in my linear algebra class. Maybe I was careless. I regret that... Explanation based on null space This explanation is based on Strang's book. Column space and null space are the main characters. Let's start with this explanation. Assume  x  where x is in the null space of A .  The matrices ( A^{T} A ) and A share the null space as the following: This means, if x is in the null space of A , x is also in the n...

Gauss's quote for positive, negative, and imaginary number

Recently I watched the following great videos about imaginary numbers by Welch Labs. https://youtu.be/T647CGsuOVU?list=PLiaHhY2iBX9g6KIvZ_703G3KJXapKkNaF I like this article about naming of math by Kalid Azad. https://betterexplained.com/articles/learning-tip-idea-name/ Both articles mentioned about Gauss, who suggested to use other names of positive, negative, and imaginary numbers. Gauss wrote these names are wrong and that is one of the reason people didn't get why negative times negative is positive, or, pure positive imaginary times pure positive imaginary is negative real number. I made a few videos about explaining why -1 * -1 = +1, too. Explanation: why -1 * -1 = +1 by pattern https://youtu.be/uD7JRdAzKP8 Explanation: why -1 * -1 = +1 by climbing a mountain https://youtu.be/uD7JRdAzKP8 But actually Gauss's insight is much powerful. The original is in the Gauß, Werke, Bd. 2, S. 178 . Hätte man +1, -1, √-1) nicht positiv, negative, imaginäre (oder gar um...

Why parallelogram area is |ad-bc|?

Here is my question. The area of parallelogram is the difference of these two rectangles (red rectangle - blue rectangle). This is not intuitive for me. If you also think it is not so intuitive, you might interested in my slides. I try to explain this for hight school students. Slides:  A bit intuitive (for me) explanation of area of parallelogram  (to my site, external link) .