Archived

This topic is now archived and is closed to further replies.

cyam95

glPushMatrix and glPopMatrix

Recommended Posts

cyam95    122
I just don''t really understand what this function doin. Can anyone explain to me with an example. I''ve been reading 2 books and still didn''t understand.

Share this post


Link to post
Share on other sites
Shag    122
OK ... erm ...

Here''s a psuedo code snippet:-

Draw a sphere (a planet say) // you''re current modelview matrix is centered on the planet

PushMatrix
Rotate around the Planet
Translate away from the planet
Draw a moon
PopMatrix // back to planet center

PushMatrix
Rotate somewhere else around the planet
Translate away from the planet
Draw a another moon
PopMatrix //back to planet center again

What this means is that each time you did a rotate and translate away from the planet centre, after you popped the matrix you where back there - Otherwise all other rotations/translation would be effected by the first moon etc ...

That was a crap explanation - I''m tired, but I hope you get the idea. Basically put, every manipulation from with a push/pop is reset once you pop.

That still doesn''t make much sense!

Share this post


Link to post
Share on other sites
subnet_rx    158
Me too, thx. I posted about this a few days ago and could never get it. I finally figured out that it wasn''t the matrix stacks I wasn''t getting, it was translation. I thought all translation took place in respect to the origin. Now I know it takes place in relation to the matrix on top of the current matrix stack.

Share this post


Link to post
Share on other sites
subnet_rx    158
One question though.

I''m having a problem understanding what is going on. It is probably due to
me not understanding something else in the library. Anyway, in my mind, you
initialize the matrix at a point, say 0,0,0. Then when you push another
matrix on the stack and translate, it translates in relation to 0,0,0 b/c
that was the previous matrix on top.

But, in OpenGL Game Programming, they are programming a robot. I am having
a hard time understanding why they call pushMatrix and popMatrix in each
part''s function, then they call pushMatrix before calling these functions,
and popMatrix after.

It is sort of like nested push and pop calls, but if they are all just in
relation to one point, why not just call pushMatrix, create and translate
the object, call popMatrix, and move on to the next object? With the torso
always being the relation point.

If anyone can understand what I''m talking about, I''d really appreciate a
response. I''ve been stuck on this for days.

Share this post


Link to post
Share on other sites
ZealousElixir    256
It''s exactly like you said. Nested push-pop calls. The matrix stack is not just two layers deep. You can keep calling glPushMatrix up to 32 times (in the Win implementation, I think). Anyway, after each call to glPushMatrix, your rotations and translations from the last draw are still intact, until you call glLoadIdentity. What we''re saying is,

*Translate and rotate to the main planet.
*glPushMatrix ^^^ THESE TRANSFORMATIONS ARE STILL ACTIVE ^^^
*Translate and rotate to the moon
*NOTE THAT NOW THE TRANSFORMATIONS ARE CHANGED, BUT
STILL RELATIVE TO THE ORIGINAL TRANSLATIONS
*Draw the moon
*glPopMatrix
*WE''VE JUST RELOADED BACK TO STOP TWO, CANCELLING ALL EFFECTS OF THE DRAWING OF THE MOON
*end.

Sorry for the capitals...if an op wants to bold it instead, more power to them, but I think it adds appropriate emphasis.

Hope that helps,
ZE.

Share this post


Link to post
Share on other sites
ZealousElixir    256
quote:
Original post by ZealousElixir
The matrix stack is not just two layers deep. You can keep calling glPushMatrix up to 32 times (in the Win implementation, I think).


I''ll be the first to catch that little error. I would have edited the original post, but this deserves special mention. The view matrix stack can be up to 32 matrices deep. Since the current matrix is on top, you can really only call glPushMatrix() 31 times in Windows OpenGL without causing a GL_STACK_OVERFLOW error.

Sorry for any confusion,
ZE.

Share this post


Link to post
Share on other sites
subnet_rx    158
ok, two questions, and if at any point you think to yourself "This guy is a total idiot and will never get it" I will understand. I myself am wondering why I understand every line in the code with the exception of this. I''ll try to type the code out here in chronological order of calls, not the way it''s typed.

glPushMatrix();
glLoadIdentity();
DrawRobot();
glPushMatrix(); //this is inside the DrawRobot function
DrawHead(); //which calls a push, translate, scale, and pop
DrawTorso(); //same as Head
glPushMatrix(); //we''ve called three push''s at this point
glTranslate*();
glRotate*();
DrawArm();


I don''t understand why each object calls a push and pop, and I don''t understand the reason for all the pushes before DrawArm, when the torso is the relation point.

Share this post


Link to post
Share on other sites
Brother Bob    10344
quote:

The view matrix stack can be up to 32 matrices deep



The stack depth is implementation dependent, but must be AT LEAST 32 matrices deep, not up to 32. Any implementation that does not have more than or equal to 32 entries in the modelview matrix stack is not OpenGL compatible.

quote:

I don''t understand why each object calls a push and pop, and I don''t understand the reason for all the pushes before DrawArm, when the torso is the relation point.



You have multiple calls to glPushMatrix (and glPopMatrix of course) so you can draw the hand of the robot independent of where the arm is pointing, and how the torso is turned with respect to the global coordinate system. Once you placed the arm, all you have to do to place the hand is to translate the hand to where it should be relative the arms position. This is always the same, since you probably don''t bend the arm, or have a telescopic arm, or something similar.

If you don''t use multiple calls to glPushMatrix, you must manually calculate the position for the hand each time (instead of using the wonderfull stack), using messy triginometry. And if you want to add fingers to this hand (concider it a palm only), you are in deep trouble.

Share this post


Link to post
Share on other sites
ZealousElixir    256
quote:
by Bob...
The stack depth is implementation dependent, but must be AT LEAST 32 matrices deep, not up to 32. Any implementation that does not have more than or equal to 32 entries in the modelview matrix stack is not OpenGL compatible.



You are correct, sir! What I meant to say was, you can have up to 32 matrices (in Windows OpenGL) on the stack at one time. Notice that I was very careful previously to distinguish this is my first post...it is implementation specific.

Thanks for the correction though,
ZE.

Share this post


Link to post
Share on other sites
Obelix    122
subnet_rx, all translation does _not_ take place in relation to the matrix on top of the current matrix stack. Instead do OpenGL have a separate variable with the current matrix. The explanation Shag wrote is correct. If you follow the links on top of this page , Articles & Resources -> OpenGL, do you find a older versions of the red book. This book has a good explanation of the topic. Here is a some online tutorials:
http://www.dev-gallery.com/programming/

Perhaps did you underestimated the difficulties of this topic?
It is more difficult than just having one global coordinate system. Or more true, thinking of everything in one global system would be harder..

Share this post


Link to post
Share on other sites
WhatEver    125
When you push a matrix the current matrix is being saved. The identity matrix is just a starting point. In the code above it shows the matrix being Pushed right before the Identy matrix is saved...he doesn''t need to do that. Anyway, Pushing and Poping is just a way of saving and restoring matrices.

Take this code for example:

  glPushMatrix();
glRotate3fv(Angle);
//everything at this point will be rotated by Angle

glPopMatrix();
//everything from this point will be at the identity matrices origin


Here, this example might help you understand too. Say you want to draw 4 players each side by side 5 units from each other. Pushing and Popping matrices is expencive, so you can do this:

  glPushMatrix();//save current matrix

DrawPlayer();//0 units from pushed matrix

glTranslate3f(5.0f,0.0f,0.0f);
DrawPlayer();//5 units from pushed matrix

glTranslate3f(5.0f,0.0f,0.0f);
DrawPlayer();//10 units from pushed matrix

glTranslate3f(5.0f,0.0f,0.0f);
DrawPlayer();//15 units from pushed matrix

glPopMatrix();//restore Pushed Matrix

DrawPlayer();//0 units from pushed matrix


Every time you draw something in OpenGL, the vertices are always drawn relative to the last transforming call, such as glTranslate, glRotate and glScale. You use glPop to restore previously Pushed matrices.

Share this post


Link to post
Share on other sites