Push / Pop question - please just confirm

Push / pop has been around since abacus computer.
Here my function pseudo code

initialize matrixview
push matrix
set parameters
call function
implement " for loop"
render object
modify parameters
call function
implement " for loop"
render object

So I leave matrix stack in currently “pushed” matrix.

It fails when I try to reuse the function in same “pipe”, just modifying parameters.
“Fixed” be enclosing each function call in "push / pop " .

Is this “normal” behavior of OpenGL?

Push / pop has been around since abacus computer.

That’s a great analogy. So let’s take it to its conclusion.

If you push a bead on the abacus without eventually popping it, and you keep doing that, pretty soon you won’t have any beads left to push, right?

The same goes with OpenGL’s matrix stack. If you keep pushing without a corresponding pop, you eventually run out of space.

The purpose of pushing a matrix onto the matrix stack is to be able to preserve the value of that matrix so that you can change that value, then restore it to the preserved value.

Consider a hierarchy of objects. You have the world, then a box, then a sphere on top of that box, and a cone sitting somewhere else. The sphere should move when the box moves, but the cone should not.

The way to render this is:

  • Setup camera matrix for world
  • push (preserves camera matrix)
    • set up box matrix.
    • render box
    • push (preserves box matrix)
      • Set up sphere matrix relative to the box
      • render sphere
    • pop (restores original box matrix)
  • pop (restores original camera matrix)
  • push (preserve camera matrix)
    • set up cone matrix
    • render cone
  • pop (restores original camera matrix)

Nice, but in my case I am darn sure that I did not run out of beads.
That is way I think OpenGL function call does something to the matrix stack.
(Time to figure out how to read current and select matrix…)
I have now 6 calls to same function with PROPERLY pushing and popping OUTSIDE the function and all is well ( on western front) .
Cheers

Transformation functions (glRotate, glTranslate, etc) modify the top-most element of the stack in-place. The only functions which change the depth of the stack are glPushMatrix and glPopMatrix (note that there is no function to “reset” the matrix stack; if you need to do this and don’t know how many matrices are on the stack, you just have to keep popping until you get a GL_STACK_UNDERFLOW error).

You only need to use push/pop if you’re implementing a hierarchy, where children are positioned relative to their parent.

Yes, that is what I am doing - that is where OpenGL is very useful, at least in my case.
But I am finding that keeping track of rotation and translation is not that intuitive, even in 2D.

That’s how people who don’t read the documentation do it. The rest of us know about GL_MODELVIEW_STACK_DEPTH.

Fortunately majority of “rest of us” communicate their wisdom without putting people who do not RTFM down as you did.
Have a nice day .

@JulyJim, I think you might be reading too much into that. It’s about the method. The point is that in OpenGL, if you’re doing something repeatedly until the driver throws a GL error, then you’re almost certainly doing it wrong (or “suboptimally”, if you prefer).

I like to ask a follow-up question, if I may.
I have implemented a call to
glGetDoublev(GL_MODELVIEW_MATRIX , mvmatrix);
before and after glPopMatrix. Here are the results

before

index 0  mvmatrix[index] 0.031250  
index 1  mvmatrix[index] 0.000000  
index 2  mvmatrix[index] 0.000000  
index 3  mvmatrix[index] 0.000000  
index 4  mvmatrix[index] 0.000000  
index 5  mvmatrix[index] 0.031250  
index 6  mvmatrix[index] 0.000000  
index 7  mvmatrix[index] 0.000000  
index 8  mvmatrix[index] 0.000000  
index 9  mvmatrix[index] 0.000000  
index 10  mvmatrix[index] 0.031250  
index 11  mvmatrix[index] 0.000000  
index 12  mvmatrix[index] 0.968750  
index 13  mvmatrix[index] 0.000000  
index 14  mvmatrix[index] 0.000000  
index 15  mvmatrix[index] 1.000000  
index 16  mvmatrix[index] 0.000000  
index 17  mvmatrix[index] 0.000000  
index 18  mvmatrix[index] 0.000000  
index 19  mvmatrix[index] 0.000000  
index 20  mvmatrix[index] 0.000000  
index 21  mvmatrix[index] 0.000000  
index 22  mvmatrix[index] 0.000000  
index 23  mvmatrix[index] 0.000000  
index 24  mvmatrix[index] 0.000000  
index 25  mvmatrix[index] 0.000000  
index 26  mvmatrix[index] 0.059211  
index 27  mvmatrix[index] 0.000000  
index 28  mvmatrix[index] 0.000000  
index 29  mvmatrix[index] 0.000000  
index 30  mvmatrix[index] 0.000000  
index 31  mvmatrix[index] 0.000000  
index 32  mvmatrix[index] 0.000000  

and after

index 0  mvmatrix[index] 1.000000  
index 1  mvmatrix[index] 0.000000  
index 2  mvmatrix[index] 0.000000  
index 3  mvmatrix[index] 0.000000  
index 4  mvmatrix[index] 0.000000  
index 5  mvmatrix[index] 1.000000  
index 6  mvmatrix[index] 0.000000  
index 7  mvmatrix[index] 0.000000  
index 8  mvmatrix[index] 0.000000  
index 9  mvmatrix[index] 0.000000  
index 10  mvmatrix[index] 1.000000  
index 11  mvmatrix[index] 0.000000  
index 12  mvmatrix[index] 0.000000  
index 13  mvmatrix[index] 0.000000  
index 14  mvmatrix[index] 0.000000  
index 15  mvmatrix[index] 1.000000  
index 16  mvmatrix[index] 0.000000  
index 17  mvmatrix[index] 0.000000  
index 18  mvmatrix[index] 0.000000  
index 19  mvmatrix[index] 0.000000  
index 20  mvmatrix[index] 0.000000  
index 21  mvmatrix[index] 0.000000  
index 22  mvmatrix[index] 0.000000  
index 23  mvmatrix[index] -152417243827761841678289670059210226360711242757086154864984064.000000  
index 24  mvmatrix[index] 0.000000  
index 25  mvmatrix[index] 0.000000  
index 26  mvmatrix[index] 0.000000  
index 27  mvmatrix[index] 0.000000  
index 28  mvmatrix[index] 0.000000  
index 29  mvmatrix[index] 0.000000  
index 30  mvmatrix[index] 0.000000  
index 31  mvmatrix[index] 0.000000  
index 32  mvmatrix[index] 0.000000  

I am assuming the “before” values are some kind of final values of each stack and seems to look OK.

What I do not get how single pop put most of the stack back to 1 and of course have no idea from where did the 23 stack value came from.

So if I am using the modleview matrix correctly I would assume to see consecutive usage reflected by reasonable < 1 values.

I am not trying to over-analyze this , but…I do have an issue with unexpected behavior after several push / pop are used in sequence.

How would it not?

A matrix is a single value; it may be composed of multiple individual components, but conceptually, a matrix is a single value. Much like when we do vector math, we treat a vector value as a single value upon when we can perform various vector operations.

So poping a stack of matrices works exactly like poping a stack of integers. The value of a matrix may be bigger than the value of an integer, but the overall operation is the same.

Well that’s easy; a 4x4 matrix has sixteen floats, not 32. So OpenGL only filled in the first 16 values; the other 16 are likely uninitialized and therefore can contain arbitrary garbage.

It’s hard to say what should be expected or unexpected when we are only reading a vague description of your code instead of the actual code which produces the output.

OK, so what EXACTLY am I reading / seeing as a return value from glGetIntegerv ?
The doc is not that clear about the "return value " ( of what ?)
Am I seeing ONE stack of 4 rows and 4 columns?

If so , how do I access SELECTED stack ?
( I’'l ask Mrs Google )

I did verify the max size of GL_MAX_MODELVIEW_STACK_DEPTH as 32.

I’ll be more than happy to provide code, but I do not want to be told that this is not debugging service.

BTW
I tried to limit the debugging output with this code snippet

	printf(" \nindex %i  viewport[index] %i ", index, viewport[index]);
for (int index = 0; index < array_size + 1; index++) {
	if (mvmatrix[index] > 0) // print only "in use"  stack
		printf(" \nindex %i  mvmatrix[index] %f ", index, mvmatrix[index]);
}

and this is what I got

index 0 mvmatrix[index] 1.000000
index 5 mvmatrix[index] 1.000000
index 10 mvmatrix[index] 1.000000
index 15 mvmatrix[index] 1.000000
**index 16 mvmatrix[index] 0.000000 **
**index 17 mvmatrix[index] 0.000000 **
**index 18 mvmatrix[index] 0.000000 **
**index 19 mvmatrix[index] 0.000000 **
**index 21 mvmatrix[index] 0.000000 **
**index 23 mvmatrix[index] 0.000000 **
**index 24 mvmatrix[index] 0.000000 **
**index 25 mvmatrix[index] 0.000000 **
**index 26 mvmatrix[index] 0.000000 **
**index 27 mvmatrix[index] 0.000000 **
**index 29 mvmatrix[index] 0.000000 **
index 31 mvmatrix[index] 0.000000

so even if the index > 16 is invalid , I woudl not expect the tool to pass values == 0

I’ll assume you meant glGetDoublev; calling glGetIntegerv for matrices would result in an OpenGL error.

You asked for GL_MODELVIEW_MATRIX, so that’s what you got: the current modelview matrix. Not every matrix in the modelview matrix stack, just the current one.

No, you are seeing one matrix. A matrix consists of 4 rows and 4 columns, so 16 values.

A matrix stack is a stack data structure, where each value is a matrix. And a stack data structure is:

A stack is a controlled data structure where all operations are applied to the top of the stack. You can remove the top, which makes the stack shorter. You can push a value onto the top of the stack. And you can look at the top of the stack.

But that’s all a stack is. If you could access the matrices beneath the top of the stack (without popping the stack to that level), then it wouldn’t be a stack anymore. So OpenGL doesn’t let you access them.

Broadly speaking, OpenGL state query functions are for querying state that will be used for rendering. Only the current matrix will be used for rendering, so that’s all you can query.

I think you and I are just parting in semantic. Modelview stack is 32 matrices deep. So in theory I can do 32 pushes and no pop.
That way I’ll have each push processed in its own pipe. And that is what I think my problem is - one or more of the matrices is wrong.
I can easily replace each push with push and increment global matrix counter and do same popping , just decrement the counter. I just have a hard time believing that that OpenGL does not have a “command” to identify the current matrix position on stack…

What is a “pipe” in this context?

As previously stated, a “stack” is an abstract data structure with 3 operations, none of which is “get current position”. So there’s no reason for OpenGL to have a function to get the current position; that’s not a normal stack operation.

Indeed, I would go so far as to say that, if your code needs to get the current position of the stack, then your code is doing something wrong. What is your code doing that it needs to know how deep the stack is?

How exactly would identifying “the current matrix position on stack” help you with that? If you think a matrix is wrong, then you need to employ some debugging techniques. When you render, insert code that shows what the current matrix is for that render operation. If you see a matrix that has gone awry, then you have some idea where the problem is. Alternatively, get into a debugger and look at the parameters you give each of OpenGL’s matrix manipulation functions.

But having an index for the current stack depth won’t help you with any of this. If you want to solve the problem, you have to look in the right place, and the current stack depth isn’t it.

Well , I am just trying my best to identify the problem - posted elsewhere.
( I have a working stencil which does not render until accessed second time…)

Each matrix has 4 rows and 4 columns = 16 values. The stack can hold up to 32 matrices. glGetDoublev(GL_MODELVIEW_MATRIX , mvmatrix); stores one matrix (the one at the top of the stack) in mvmatrix.