When you do a PushMatrix, it never changes the value at the head of the matrix stack, so conceptually a PushMatrix doesn’t do anything to modify the active transform.

How do I move an object only in object space? This should however move it in world space as well. Don’t I always move objects in object space?

Recall:

```
MODELING TRANSFORM * (OBJECT SPACE) = (WORLD SPACE)
VIEWING TRANSFORM * (WORLD SPACE) = (EYE SPACE)
or if we plug the 1st into the 2nd, we get:
VIEWING * MODELING TRANSFORMS * (OBJECT SPACE) = (EYE SPACE)
i.e.
MODELVIEW * (OBJECT SPACE) = (EYE SPACE)
```

Now let’s take your questions. If you fix your MODELING and VIEWING transforms (i.e. the MODELVIEW matrix) and you tweak your OBJECT SPACE positions, then you can see that the WORLD SPACE positions will change too – basic math, right? So will the eye-space positions. Right? So given a constant MODELVIEW, if we tweak object space positions, world space positions change too.

However, what if we didn’t hold MODELVIEW constant, but instead augmented it to counteract the change we just made to the OBJECT SPACE positions? Then our OBJECT SPACE positions could have changed but our WORLD SPACE positions could be the same as before. Make sense? For instance, translate the OBJECT SPACE positions +5 units in X, but then put a -5 units in X translation in MODELVIEW. Net result? World space is the same (to floating point precision of course).

Now to your last question, suppose we held our OBJECT SPACE positions constant, and we only tweaked the MODELVIEW matrix. Then our OBJECT SPACE positions would remain the same, while our WORLD SPACE positions would have changed. Right?

Essentially I’m asking how to e.g. know if a call to glRotatef() rotates an object, or a coordinate system and which one (object or world coordinate system).

That’s just a conceptual math trick you can use to understand what’s going on. If you read the transforms one direction you’re transforming the objects. If you read the transforms in the other direction, you’re transforming the coordinate systems. If you want to think about OpenGL transforms in terms of transforming objects, you typically have to read them in the reverse order that you multiply them with the current MODELVIEW matrix. In other words, start closest to your triangle draw calls and read “backwards”

For a description of how applying a single OpenGL transform actually works, see the red book, or read this post.

Also there is a somewhat strange explanation floating around the web, that while in object coordinate space, I have to read glPushMatrix()/popMatrix() block in reverse.

I can’t make heads or tails of that one.