# Understanding the z-axis vector from OpenGL modelview matrix

I would like to shoot spheres in the current view direction in a simple scene. I use an FPS camera, so no z-rotation. The vector pointing in the correct direction should be (m[8], m[9], m[10]) where m is the modelview matrix as returned by glGetDoublev(...).

In my understanding that vector is normalized, so when I scale it by some scalar its length will equal that scalar. If I draw an object every frame and translate it by the scaled z-axis vector (plus camera position), the object should be directly in front of me, all the time, right?

However, when I run my program, the object is not in front of me all the time. It is in front of me, as long as no rotation around the y-axis is done. Here is the relevant (I think) source code:

/* camera */
glMatrixMode(GL_MODELVIEW);
glRotatef(g_cam.rx, 1, 0, 0);
glRotatef(g_cam.ry, 0, 1, 0);
glTranslatef(-g_cam.tx, -g_cam.ty, -g_cam.tz);

/* get z-axis vector */
double mm[16];
glGetDoublev(GL_MODELVIEW_MATRIX, mm);

/* should be in front of me, all the time */
glPushMatrix();
glTranslatef(g_cam.tx + 10 * mm[8], g_cam.ty + 10 * mm[9], g_cam.tz - 10 * mm[10]);
glColor3f(0, 0, 1);
glCullFace(GL_FRONT);
glutSolidTeapot(2);
glCullFace(GL_BACK);
glPopMatrix();


Note that this is not about how to place an object in front of me all the time, but rather what is wrong with my understanding, that using the z-axis vector does not work here.

I know that this is a frequent question, because I found lots of material on the internet. However, I seem to be missing something yet. It would be great if you could help me with it :)

If the problem is not as obvious as I think it is, I can prepare a small example demonstrating the issue.

• I see you are kinda using OpenGL as a math library(glGetDoublev) and that is considered a bad practice. You should consider using a proper math library instead.(the one I use is GLM which is specifically for OpenGL, but its c++ so it might not fit your needs) – akaltar Jul 25 '13 at 23:37
• @akaltar I will have a look at GLM. The language does not matter so much. – Matthias Jul 26 '13 at 8:24

You would need to use the inverse view matrix for this. The view matrix transforms from world space to camera space, so the third column (elements 8, 9, 10) of this matrix is the world Z-axis expressed in camera coordinates. You want to invert it so you get the matrix that goes from camera space to world space; then its third column will be the camera Z-axis expressed in world coordinates, which is what you want.

Since the upper 3x3 part of the view matrix is rotation only, its inverse is its transpose. So you can extract the vector you want by using components 2, 6, 10 instead of 8, 9, 10.

• Also note that in OpenGL (by default, unless you manually build your own projection matrices to do things differently), the camera looks along the negative z axis. If you move the an object forward by the camera's z axis each frame, you'll actually be moving the ball further and further behind the camera, rather than in front of it. – Trevor Powell Jul 26 '13 at 0:50
• Thank you very much! Now it works like a charm :) @TrevorPowell I figured that z-axis thing out already, but thank you for the complement. – Matthias Jul 26 '13 at 8:21