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?
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.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:
The whole process is discussed in better detail here, under 4.1 Coordinates Transformation.