Kalevi
Kalevi

Reputation: 591

Order of matrix multiplications in OpenGL

glDisable(GL_DEPTH_TEST);
glViewport(0/*left*/, 0/*botton*/, 200/*width*/, 200/*height*/); //T4   
glMatrixMode(GL_PROJECTION);    
glLoadIdentity();   
gluPerspective(90 /*fov*/, 1/*aspect*/, 1/*fp*/, 1000/*bp*/); //T3
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity();     
gluLookAt(0/*eyex*/,0/*eyey*/,0/*eyez*/, 0/*lax*/,0/*lay*/,-1/*laz*/, 0/*upx*/,1/*upy*/,0/*upz*/); //T2
glTranslatef(-15.0, -10.0, -49.0); //T1
glBegin(GL_POINTS);
glVertex4f(0, 0, -1, 1);
glEnd();

Given this code, in what order does the matrix multiplication happen? What do I have to know to follow and verify the calculations on paper?

I suspect to following order, but haven't figured out a way to verify it: v=[0,0,-1,1]

T4 * T3 * T2 * T1 * v

Is this correct?

Upvotes: 1

Views: 545

Answers (1)

Andon M. Coleman
Andon M. Coleman

Reputation: 43319

This is mostly correct, however glViewport (...) by itself does not define a matrix. It is a simple bias and scale operation. It defines the total width, height and offset in X and Y. There is another component you are missing, which is the depth range.

The multiplication occurs in that order, but since these are column-major matrices and post-multiplied, you conceptually start on the right and then work your way to the left. Cross out T4 because it alone is not a matrix, and the end result of all this is a clip-space vertex coordinate. You still need to divide v.xyz by v.w and then do the viewport transformation to fully replicate what GL does.

You can implement the viewport transform using a matrix, but you also need to factor in glDepthRange (...) which biases and scales the Z coordinate from NDC space to window space.

Here is what such a matrix would look like:

    Row-major viewport matrix

The whole process is discussed in better detail here, under 4.1 Coordinates Transformation.

Upvotes: 3

Related Questions