5
votes

I'm starting to work a little on OpenGL stuff, and I'm seeing a lot of examples that make calls to the glMatrixMode function.

From what I've gathered, setting this to either GL_MODELVIEW or GL_PROJECTION (etc) will activate that specific transformation matrix and all subsequent calls to matrix transformation functions (glTranslatef, glPushMatrix, glLoadIdentity, glLoadMatrix etc) will affect the active matrix only.

What I don't get is why are there 3 (4 in some cases) different matrices? Which one should I use? (I'm probably going to get a lot of "Use Shaders", but I can't. Limited by school...) When should I switch and activate a different matrix? What is the benefit of utilizing all of them as opposed to only using one?

Thanks for any help :)

4

4 Answers

8
votes

glMatrixMode doesn't "activate" matrices. The OpenGL fixed pipeline uses 3 matrices (sometimes 4): Two are responsible for transforming the geometry, one for transforming texture space (and some implementations one for color adjustments). Those matrices are used all the time.

The modelview matrix is used to move geoemtry around. Since OpenGL doesn't have a "camera" the viewer is positioned by moving all the geometry in the opposite (=inverse) of the movements of the "camera".

The projection matrix is used to transform the geometry from modelview space into clip space, i.e. it projects the transformed geometry into the viewport.

The texture matrix transforms the texture coordinates. In case (s,t,r,q) are directly given the benefit of this matrix isn't clear at first. But OpenGL also allows to generate texture coordinates from the vertex positions. This together with the texture matrix allows to implement projection textures.

The color matrix is seldomly used and not even available in all implementations (it's part of an extension). If available it transforms the incoming vertex colours. Since there are not implicit color generators what use is then? Well, it can be used to transform between linear colourspaces, e.g. RGB->XYZ or any other colour space conversion that can be expressed as a matrix of scalars. Nobody used the color matrix these days, shaders do the job much better.

glMatrixMode is there so that there's no bloat of functions. Otherwise you'd need:

glModelviewLoadIdentity
glModelviewLoadMatrix
glModelviewMultMatrix
glModelviewRotate
glModelviewTranslate
glModelviewScale
glModelviewPushMatrix
glModelviewPopMatrix

glProjectionLoadIdentity
glProjectionLoadMatrix
glProjectonMultMatrix
glProjectionRotate
glProjectionTranslate
glProjectionScale
glProjectionPushMatrix
glProjectionPopMatrix

and so on. Also you couldn't use functions like glFrutum in both projection and texture matrices. You'd need two of those, too.

And last but not least one important hint. Setting the viewport and the projection matrix belongs in the rendering function. Most tutorials you'll see out there place them in the window resizing handler, which is the totally wrong place for that. Don't immitate this bad habit.

5
votes

You will be using all of these if you use the fixed function pipeline (i.e. "no shaders"). In fact, you'll use them with shaders too, but you'll implement them yourself in that case.

This part of OpenGL can be hard to grasp at first, although it is actually quite simple. When you select a particular matrix, then this does not turn on or off anything. All it does is that it makes functions like glTranslatef work with the one specific matrix that you've selected.

OpenGL works like this everywhere (except for direct state access), for example with textures and buffers, in the same way.

EDIT: As for why there are several matrices, they all do different things. Your models are usually in their "own space", which means they need to be somehow transferred to the "world", by scaling them appropriately and translating them to the right location. Then everything (the whole "world") needs to be transformed in a way according to your "eye position", and it must be transformed into a "normalized" clip space, because that is how the hardware can be implemented in the most efficient manner, etc, etc, etc.

All those matrices are usually multiplied together (without you knowing that this happens).
If you google for opengl transform pipeline, you will get a lot of good resources that explain what happens when in detail, for example this.

Or, read the specification (freely available at opengl.org), it contains very explicit (and in my opinion easy) information on how all the seemingly complicated matrix stuff is intended.

1
votes

You will probably just use glMatrixMode(GL_PROJECTION) once, followed by gluPerspective() (or maybe glOrtho()), so that you will set how the projection will be done. It is not that very common to change the perspective once set.

Then you change to GL_MODELVIEW and just use it to rotate/translate/scale stuff around. Both matrix are used on redering, being final position on screen = GL_PROJECTION * GL_MODELVIEW * your vertex. But since GL_MODELVIEW should change much more often than GL_PROJECTION, they are separated by the specification.

0
votes

It's because matrix multiplies are not commutative. If you only had one matrix mode, the new transformation would always occur after all existing ones, and that's not always desirable.

By keeping several matrices which effectively get multiplied together for each piece of geometry, it's possible to e.g. have both translation to render the different bits of an object and also a point-of-view transformation, and be able to adjust these independently of each other.