Opengl View matrix question

Started by
3 comments, last by haegarr 10 years, 5 months ago

I am shifting from directX to Opengl and wondered why the

fourth row of the view matrix of opengl is negated?

by fourth row i meant the look vector since in opengl it is arranged in column major order.

my confusion is that when i checked some of opengl tutorials, some of them DOES NOT negate the look vector.

but i checked the LookAt function of GLM, it did negate the look/target vector.

the value is different from that of DirectX, where only the eye position is negated to subtract the camera position to the vertices of the objects.

Is this because in OpenGL the coordinates is facing -Z instread of +Z?

Advertisement
I don't know, why the fourth row should be negated (or why it should have anything to do with the view direction). In fact I'm pretty sure you can just use the same matrix (depending on the VS you might need to transpose it).

Since the deprecation of the fixed function pipeline and the introduction of the vertex program/shader, all the transformation math is the responsibility of the programmer.

The only remaining difference between DirectX and OpenGL in that respect is the clip space. In OpenGL it ranges from -1 to 1 along the z-axis, whereas in DirectX it only ranges from 0 to 1. But this only changes the way the projection matrix has to be set up. The view matrix can stay the same.

In opengl, +Z is coming out of your screen at you.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

In opengl, +Z is coming out of your screen at you.


I believe this is not entirely correct. In clip space, -z is coming at you (unless you reverse the depth test) and in modern OpenGL this is about the only thing that is "fixed".

Older versions of OpenGL used to have conveniance functions for setting up projection matrices. These live on in libraries like glm.
All that these function did/do is set up a projection matrix like so:

    // First index is row, second index is column. Position vectors are column vectors.
    Matrix<4,4,float> m;
    m[0][0] = 1.0f / tanFovXHalf;
    m[1][1] = 1.0f / tanFovYHalf;
    m[2][2] = -(zFar + zNear) / farMinusNear;
    m[2][3] = -2.0f*(zFar*zNear) / farMinusNear;
    m[3][2] = -1.0f;
    m[3][3] = 0;
If such a projection matrix is used, than the view space +z axis is comming at you. However, you could just as well set up your projection matrix like this:

    Matrix<4,4,float> m;
    m[0][0] = 1.0f / tanFovXHalf;
    m[1][1] = 1.0f / tanFovYHalf;
    m[2][2] = (zFar + zNear) / farMinusNear;
    m[2][3] = -2.0f*(zFar*zNear) / farMinusNear;
    m[3][2] = 1.0f;
    m[3][3] = 0;
Then the view space -z axis would be comming right at you, and your view space coordinate system would be left handed. This is entirely up to the programmer.

I prefer the first method, but for a cross plattform or ported project I would not outright discard the idea of using a projection matrix, where all the other matrices can stay the way they are. This can save a lot of pain.

There are several misunderstandings in front of the problem:

I am shifting from directX to Opengl and wondered why the
fourth row of the view matrix of opengl is negated?

The view matrix defines the space transformation from global space to camera/view space. OpenGL uses by convention column vectors with the homogenous co-ordinate at last, and hence the 4th row of its view matrix always is [ 0 0 0 1 ] (in a matrix the term "row" means a horizontal span). You probably mean something different.

by fourth row i meant the look vector ...

The "look vector" is a direction vector. Because of OpenGL's convention to place the homogeneous co-ordinate at the 4-th position, the 3 possible direction vectors are at the 1st, 2nd, and 3rd columns (not row, see below). The 4-th column contains the eye position. Usually the 3rd column ("z axis") is named the look vector.

... since in opengl it is arranged in column major order.

The "column major order" describes a way to arrange the 2D structure of a matrix in linear memory. This has no relation to mathematics but is an implementation detail. What you probably mean is that OpenGL uses "column vectors". The latter aspect means that a matrix vector product reads M*v opposed to the order v*M you are familiar with from D3D (the both v's and M's are not exactly the same here but written as such for simplicity).

Whether your camera looks along the negative (RHS) or positive (LHS) z axis can be regulated by mirroring using a scaling matrix set-up as S(1,1,-1). This scaling is to be done behind the view transformation but before the projection, hence

P * S * V

so it can be integrated with the projection matrix or else with the view matrix, if wanted, because of:

P * S * V = ( P * S ) * V = P * ( S * V )

So you need to look at several things: What does OpenGL expect? Which handedness (LHS or RHS) does the camera system use? Where, if used at all, does the math library considering the handedness swapping? Only all this together gives you the real picture.

This topic is closed to new replies.

Advertisement