When to call gluPerspective?

I’ve got a program that needs to display some triangles with a correct aspect ratio even when the window is resized. Normally when I do what people say, the triangles are stretched when I resize the window.

In example after example online, people say to use this sequence of calls in the reshape callback:

glViewport (0, 0, win_width, win_height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
double r = (double) win_width / (double) win_height;
gluPerspective (45.0f, r, .01, 100);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();

And after that, you simply need to draw things normally in draw_scene, with no need for calling gluPerspective.
However I find this does not correct the aspect ratio at all. It’s like the gluPerspective call is ignored.
Can anyone explain this?

I find that it is only when I call gluPerspective and second time after the above code that the aspect ratio is corrected and my triangles are not stretched.

What is the real difference under the hood between GL_PROJECTION and GL_MODELVIEW?

Load projection transforms like Perspective on the PROJECTION matrix stack.

One of the main reasons for the separation is that certain fixed-function shading operations like lighting and fog calculation need to transform coordinates and normals to EYE-SPACE. That’s what the MODELVIEW matrix does. It’s a stop-off point before PROJECTION is applied to take positions all the way to clip-space for clipping, perspective divide, and rasterization.

Can you hazard a guess as to why using gluPerspective to adapt to the new aspect ratio doesn’t work for me on the projection matrix stack but does work on the model view matrix stack?

I’m puzzled. Didn’t you say it does work, but only seems to work the second (and subsequent) times?

You might check that you are populating the PROJECTION and MODELVIEW matrix stacks with the same matrix both times through. If there’s a difference, that’d explain it.

Could be that you’re getting a couple calls to the reshape function with different values.

It could also be that after you’re getting a reshape event (and thus changing the frustum definition including projection matrix) that you’re not posting a redisplay, causing your redraw event to be called again to update with the new size/aspect ratio. That’s a common problem.

For debugging purposes, you can tell your reshape and redisplay callbacks to post a redisplay event, so they’ll be called continually. Then once you debug this issue, drop back to only posting a redisplay event when something has actually changed that should affect the resulting image displayed.

Ah thanks it seems I wasn’t calling glutPostRedisplay at all. Adding that to the end of my redraw routine fixed it.

Ok. That’ll get your redraw display called again (and again, repeatedly). However, to save needless redrawing work (+CPU+GPU cost), you may want to step that back to calling glutPostRedisplay() only when some state changes that suggests a redraw will produce different display contents.

You also want to rerun your redraw routine when a window expose event occurs. But IIRC GLUT handles that for you (check me on that though).

Yep. The plan was to call usleep when nothing’s changed.
I found glutVisibilityFunc is what’s called when the window is minimized/maximized.