red book example dont understand - clip.c

Hello everyone,

I am trying to understand OpenGL but am having some trouble with matricies. I will paste the part of the code that I have trouble with in clip.c:

void display(void)
{
GLdouble eqn[4] = {0.0, 1.0, 0.0, 0.0};
GLdouble eqn2[4] = {1.0, 0.0, 0.0, 0.0};

glClear(GL_COLOR_BUFFER_BIT);

glColor3f (1.0, 1.0, 1.0);
glPushMatrix();
glTranslatef (0.0, 0.0, -5.0);

/* clip lower half – y < 0 /
glClipPlane (GL_CLIP_PLANE0, eqn);
glEnable (GL_CLIP_PLANE0);
/
clip left half – x < 0 */
glClipPlane (GL_CLIP_PLANE1, eqn2);
glEnable (GL_CLIP_PLANE1);

glRotatef (90.0, 1.0, 0.0, 0.0);
glutWireSphere(1.0, 20, 16);
glPopMatrix();

glFlush ();
}

Basically, I understand everything except for the glPushMatrix and glPopMatrix. What exactly is it doing and how is it doing it?

I thought the first call to translate and rotate just rotates and moves the sphere. but then I see that you need the push/pop to be able to SEE it. Why is that? Thanks for the help!

Jenny

In legacy OpenGL, transformation matrices are stored in a stack in order to alleviate hierarchical transformations without need to save/restore those matrices with your code. Potentially, it is much faster, because stacks can be stored on the server side.

So, all transformation you are performing are the effects of the matrix on the top of the stack. For example, you are drawing a body. You have to place it somewhere in the world-space (translate, rotate, scale, etc.), and you are applying model-view transformation matrix. Then you want to draw an arm. The arm is rotated in the shoulder. You have to multiply current model-view matrix with the new transformation. If you want to draw another arm, you have to create matrix that will do exacly the same transformation as the matrix that positions the body, and then modify it with transformation for the other arm. Why don’t you use already created matrix?

glPushmatrix() pushes current (at the top of the stack) matrix down the stack and copies it on the top, so you can combine it with the new transformation. When you are done with the arm, just glPopMatrix(), and you can get rid of the current transformation as well as restore previous one. For the another hand just multiply current matrix with the new (relative) transformation.

This is really well explained in the Red book. Read it more carefully. :wink:

In this example, the combination glPushMatrix/glPopMatrix is used to isolate transformation in the function and prevent changing state of the model-view matrix (transformation).

i am still a bit confused. is it possible to tell me what it would look like without the glPushMatrix/PopMatrix code? so what code would replace it if it wasnt there? that way i can see the equivalence and try to understand it. thanks heaps and sorry for the trouble!

It’s quite simple really. glPushMatrix is saving the OpenGL modelview matrix which you initially setup with gluLookat. Think of this internal matrix as the “camera”.
Now every time you render and use glTranslatef OpenGL builds a new matrix and multiplies this against the camera - thus moving or translating your model into the cameras view. If you need to draw another object you need to undo the last matrix multiplication which is not that easy or convenient. Instead you wrap your draw calls up with glPushMatrix and glPopMatrix to preserve the camera between draw calls.

for this part of the above code, this is my understanding:

glPushMatrix();
glTranslatef (0.0, 0.0, -5.0);

glRotatef (90.0, 1.0, 0.0, 0.0);
glutWireSphere(1.0, 20, 16);
glPopMatrix();

glTranslatef is at a point 5 units from the z-axis/centre. Then we rotate that point 90deg about the x-axis. Then we draw the sphere.

Ignoring the Push/Pop for now, is that what is happening? So the sphere is drawn at the location where we are AFTER gltranslatef was applied? so if we were at center initially (0,0,0), then we did the translate above, that means we are at 0,0,-5 on the coordinate space…then we draw the sphere there…but its rotated at 90degrees about the x-axis.

Is that correct? (ignoring the push/pop calls)?

You said that you have a copy of Red book, but it seems that you haven’t read what is written there. :frowning:

You can “think” in local or in global coordinate system. If you “think” in local, then local coordinate system is translated down the negative Z-axis, and then rotated around local X-axis.

If you “think” in global (world) coordinate system, then your object is first rotated around global X-axis and then the object is translated along global Z-axis.

If you don’t have glPushMatrix()/glPopMatrix() these transformation will affect all subsequent objects. Translation for -5 units means pushing away from you, not above. You are at the coordinate center and you are looking toward negative Z-axis.

Okay i do have it with me and i just read through alot of it. makes more sense but im still confused:

glPushMatrix();
glTranslatef (0.0, 0.0, -5.0);
glRotatef (90.0, 1.0, 0.0, 0.0);
glutWireSphere(1.0, 20, 16);
glPopMatrix();

I dont see how Push/Pop is required. I mean initially we load the idenitiy matrix using glLoadIdentity. then we do all this. Ive see code where we just loadidentitiy, do a translate/rotate then thats it…we can see the image. with this one, you cant see the image without using the push/pop. Why is that? Example shown here:

http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=04

where we do a loadidentity, translate, rotate then draw triangle. then we loadidentitiy, translate, rotate and draw another triangle.

the use of push/pop was not required here. yet it is required for the above example that i initially posted?

The local coordinate system is attached to the object. When you draw your object, you define position of its vertices in its local coordinate system. When you transform the object, you transform local coordinate system as well.

Fig 3.2 - Coordinate systems

Sorry i edited my above post because i undersatnd what locak coordinate system is. I now have another question above. I hope thats okay!

What i dont get is what the Popmatrix is doing. I mean, whatever the matrix was before the translate call, I am guessing Popmatrix simply restores the current matrix to that?

so in:

glPushMatrix();
glTranslatef (0.0, 0.0, -5.0);
glRotatef (90.0, 1.0, 0.0, 0.0);
glutWireSphere(1.0, 20, 16);
glPopMatrix();

PopMatrix restores the current matrix to the matrix it was BEFORE the glTranslatef call? thats my understanding of this (accroding to another example in the redbook)

Use glLoadIdentity() in the first example and get rid of glPushMatrix()/glPopMatrix() and see what’s happening.

yep tried it and its the same. also i did this:

glTranslatef (0.0, 0.0, -5.0);
glutWireSphere(1.0, 20, 16);
glLoadIdentity();

Then i did this:
glLoadIdentity();
glTranslatef (0.0, 0.0, -5.0);
glutWireSphere(1.0, 20, 16);
glLoadIdentity();

For some reason the second one showed the image closer and the first one showed the image more far away. which didnt make sense. but then after trying both again, they are both close. is there a reason for why this happened? some error from visual c++ maybe?

Also when I tried this while back the image was not visible unless i moved the window around. when i stopped moving the window it was not visible. Then when i tried again it was there but when i clicked it with my mouse it got smaller each time i clicked, eventually disappearing. this is really weird, because I never set the mouse to do anything!

now its all working like its suppose to. The above faults is why I thought pop/push was doing something else thats not equivalent to me using identitiymatrix. anyidea why the above weird errors occurred?

yes, exactly.