Help me to understand matrices

After scanning thru the attached article / link I am still not sure if I am on right track to solve this problem.
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#cumulating-transformations

I have solved part of the problem by executing parts of the OpenGL_Stencil_Cascade in push / pop fashion of each major part.
I can add to the OpenGL_Stencil_Cascade using same push / pop scheme.

My objective is to create OpenGL (original) object and be able to resize it using window maximize / minimize etc.
The (original ) object is part of system state machine and all works fine in
case / state “idle” .
I use (left button ) mouse callback to create next case / state “mouse down”
to add / render another object to the original. I can add without an issue and the added object displays on the screen as expected.

Here is basic "case mouse " code

	if (State_Mouse.state == 0) { // button down 
		glPushMatrix();
		glLineWidth(2.0);	// removed from OpenGL_NDC_coordinates
		glTranslatef(.25, .25, .25);
		glScalef(.1, .1, .1);
		OpenGL_NDC_coordinates(0);				//  TOK with text
		glPopMatrix();
		glFlush();
	} else {
		//system_state = SYSTEM_STATE_MOUSE_EXIT;
	}
	break;

The “case mouse” code does not include call to the original object - and I like to keep it that way for more additions.

Here is an abbreviated case / idle which does include the original object call and is successfully doing / resizing similar addition.

Bloc

	OpenGL_Stencil_Cascade(1);        // initially clear buffers
	glPushMatrix();
	glLineWidth(2.0);	// removed from OpenGL_NDC_coordinates
	glTranslatef(.5, .5, 0);
	glScalef(.1, .1, .1);
	OpenGL_NDC_coordinates(0);				//  TOK with text
	glPopMatrix();
	glFlush();

	break;

What I no not understand is - how can I have a object rendered on screen / viewport and cannot “resize” it without reloading the original object?

Does not “reshape” works on current viewport?

I’d say the short answer is: you cannot. Virtually every OpenGL (or DirectX, Metal, Vulkan, etc) application redraws everything on screen constantly - ideally at least 60 times per second. That is done because in general it is much more complicated/time consuming to figure out which pixels are still valid than to just re-render everything.

The longer answer is that if you know in advance that some opaque (!) parts of your scene are not going to change you could render those to a color and a depth texture (to preserve color and depth information). Then the first thing on the next re-render would be write the values back to the color/depth buffer respectively.

However, this would not help if the window is resized. You simply have no pixel data for the new pixels if the window was enlarged, so you need to re-render everything to the newly sized buffers (and textures). If the new window size is smaller you could downsample the textures, but that would likely introduce visible artefacts, especially when applied to the depth texture.

BTW, I cannot be sure, but from the snippets you posted it sounds to me like you might be rendering from GLUT callbacks other than the one registered with glutDisplayFunc - do not do this! All other callbacks should only record information into your application’s data structures and then (if desired) request a redraw with glutPostRedisplay. That will cause the display callback to be run again redrawing everything. Any other design is extremely error prone because the order of the callbacks (and therefore the order you set OpenGL state and render) depends on what the user is doing and is thus fairly unpredictable.

Yes, but as far as OpenGL is concerned the viewport is merely a transformation that describes how to get from NDC coordinates to window coordinates. What is displayed in the window is the content of the front buffer, but the specification of glViewport does not say that it resizes the content of the front buffer and so, well, it doesn’t do that :wink:

Well , I cannot win.
Even if I post code there is always something "missing " in my post.

My “state machine” runs in “display” callback, it is being updated using standard callbacks - the one mentioned in original most is from glutMouseFunc via
glutPostRedisplay().

I am NOT interested in any “automatic re-display” mentioned.

My objective is event driven application and ONLY by event of mine choosing.
I need to be able to fully control displays of objects / code in each state.

In other words
I am using standard OpenGL"display" callback is a wrapper for state machine.
The contents of “display” is a simple C switch statement.
All I want is to “send” current , standard OpenGL processing / rendering pipe to viewport.

Why OpenGL cannot handle that ?
I must be missing something here . And I do not understand what.

Hmm, I believe the part you may be missing is related to this:

I don’t think that is a good match for how this works in practice. If you want an object to be visible you have to draw it every time your display callback runs - if for no other reason than that a typical display callback starts with clearing depth and color buffers, i.e. it wipes away any rendering from a previous invocation of the display callback.
Even if you did not start your display callback with clearing buffers, window resizing causes the contents of the buffers to effectively become undefined - to be honest I don’t know off the top of my head what the OpenGL specification promises about that, if anything - and you have to redraw everything anyway.

You say your display callback implements a state machine, but it sounds like you want to render more than just the “objects” that correspond to the current state. Instead to me it sounds like you want to draw all the objects that correspond to the “path” (sequence of states) through your state machine that you took. If that is the case your application could record that path so that you can draw all objects that correspond to the states you visited. It also would mean separating your state machine proper (the thing that evaluates the current state and transitions to the next) from rendering. Rendering would only receive a sequence of states (the path the application took through the state machine) and render whatever object corresponds to that state.

OK, if I have to keep track of current object(s) to be displayed in each state I do not see any issues.
The idea or suggestion of "going thru each state " to reach current one is NOT how switch command works.

This is not a dynamic application and if there is going to be “flickering” between each state it is no big deal. BUT ultimately I have to have clean window resizing and that is so far not happening. Makes no sense to continue coding states if I cannot get that working reliably on first one after “idle”.

One more thought before I take a snooze.
Standard reshape callback - executed by window maximize menu call does not call “display” , it manipulates current viewport.

Now my mouse callbacks includes glutPostRedisplay(); which physically runs “display”. That for some yet unknown reason let me maximize the window by clicking on it!

What I am getting form the discussion - I need to gain control of the viewport.

It sure looks that “window maximize” does not only resizes viewport - running “reshape” , but “display” gets also called.
It is unclear how "display " gets called , but running “display” invokes state machine function.
And that is where the actual display gets rendered.
Works perfect in “idle” state.

I do not see how and why it does not work in other states.

Here is an actual trace AFTER the window is maximized and “un-maximized” , all in state “idle”.

CALLBACK void OpenGL_reshape @function OpenGL_reshape @line 9176
CALLBACK void OpenGL_display(void) @function OpenGL_display @line 11334
@function OpenGL_Stencil_Cascade @line 550
clear buffers ENTRY @function OpenGL_Stencil_Cascade @line 629
clear buffers EXIT - DONE @function OpenGL_Stencil_Cascade @line 638
CALLBACK void OpenGL_display(void) @function OpenGL_display @line 11334
@function OpenGL_Stencil_Cascade @line 550
clear buffers ENTRY @function OpenGL_Stencil_Cascade @line 629
clear buffers EXIT - DONE @function OpenGL_Stencil_Cascade @line 638
CALLBACK void OpenGL_reshape @function OpenGL_reshape @line 9176
CALLBACK void OpenGL_reshape @function OpenGL_reshape @line 9176
CALLBACK void OpenGL_display(void) @function OpenGL_display @line 11334
@function OpenGL_Stencil_Cascade @line 550
clear buffers ENTRY @function OpenGL_Stencil_Cascade @line 629
clear buffers EXIT - DONE @function OpenGL_Stencil_Cascade @line 638
CALLBACK void OpenGL_display(void) @function OpenGL_display @line 11334
@function OpenGL_Stencil_Cascade @line 550
clear buffers ENTRY @function OpenGL_Stencil_Cascade @line 629
clear buffers EXIT - DONE @function OpenGL_Stencil_Cascade @line 638
CALLBACK void OpenGL_reshape @function OpenGL_reshape @line 9176
CALLBACK void OpenGL_display(void) @function OpenGL_display @line 11334
@function OpenGL_Stencil_Cascade @line 550
clear buffers ENTRY @function OpenGL_Stencil_Cascade @line 629

Does that surprise you?

If a window gets maximized, then odds are good that there are now pixels that are part of the window which were not part of the window before it was maximized. What values are in those pixels? Well, they’re undefined. They could be black, white, whatever used to be in windows adjacent to the now maximized one, or just random garbage.

But what matters is that those pixels aren’t values that you put there. So if the window has been resized, does it not make since that this would be a good time to redraw its contents? And is that not what the display callback is for?

So what’s the problem?

Well, we can’t know either, because we don’t know what this “state machine” is, how it works, what is responsible for what, or anything of that nature. How can you reasonably expect someone to help you find a bug in code that they don’t know anything about? You haven’t even explained why you need a “state machine” in your display logic to begin with.

Your “trace” is meaningless, as we have no idea what any of those functions are actually doing. I mean, I can see a bunch of clear calls and calls to whatever “OpenGL_Stencil_Cascade” is, but that doesn’t mean anything.

And before you dump a big blob of code on us, don’t. You need to learn the virtues of a minimal, complete, verifiable example, and then give that to us. That means removing everything that isn’t absolutely necessary in showing the problem. It may take some time to break your application down that far.

You may not recall that I asked if “reshape” uses / calls “display”.
So I did not bother to trace the “display” calls.
The real issue is - when there was nothing to render in switch case - the window maximize and subsequent “reshape and display” functions where not called. But the window itself was redraw with unusable garbage and froze.
It is hard to debug a tool which does “behind the scenes “automation””.

I shall limit my future requests to simple - yes / no answers to make it easier to reply to.
It has been a bumpy ride so far, but I am getting there.

It doesn’t. Your “reshape” callback can do whatever it likes.

However, the various circumstances that cause your reshape callback to be invoked typically also cause the display callback to be called afterwards. One is not calling the other, but they’re both being caused by the same thing: resizing the window.

Nobody’s making you use that tool. As has been suggested several times, GLUT is typically for demo-like applications. If you want more direct and obvious control over what’s going on, you can employ GLFW or other tools.

This is also why it’s important for you to recognize the difference between “OpenGL” and “GLUT”. Because they’re not the same thing, and using the former does not require the latter.

Hi JulyJim,
I ought to stay quiet due to my low knowledge of GLUT.
Maybe the opengl ‘state-mashine’ thingie makes better sense if you think about it along with the invisible loop(). In normal opengl you get to controle the loop() yourself. If I don’t controle this loop properly, it’s likely that it will do the draw-call and all the calls it spawns 60 times a second. If you just ‘watch’ the screen without giving input this can put a heavy and unnecessary burden on the GPU since one call between screen-manipulations is enough. The loop() is not controlable in GLUT (as I understand it), but you can glean it through the order and frequence some of your code is called.
My general ‘bon mot’ is “the draw-call is the last” … you’r done with sucess or failure as it is. If this holds true, it should put sense into the order of other calls/callbacks you should use to complete a certain task.
In ‘normal’ opengl you make a lot of initiation once. In GLUT you use initiation for every pass of the loop. That may make the use of matrixes somewhat different between the two.
Just ignore if I’m missing the point.
bwt, it’s not clear if you make a distinction between the ‘window’ & window-size and the size of what’s drawn within the ‘window’.

Nothing missed here. You got it.
This "discussion " went down hill first time I posted / asked about basic parts of “main OpenGL (event) loop”. There is nothing special about it - combination of callbacks in “event” loop is main part of common OS.
There are ways to track the OpenGL callbacks / events which I was trying to demonstrate and…
Philosophical differences aside , I do not see why any software app would “bother” to update the actual physical display at any rate - “just because”.
And I am talking about software, not hardware display stuff.
Thanks for your contributions.
Cheers