Avoid distorted appearance when window manager auto-resizes first/toplevel window

Hi all,
When I create a window in OpenGL using GLUT, I have no idea what the maximum allowed window size will be, because GLUT won’t tell me. So I ask for the largest size i.e. full screen, and after the call to glutCreateWindow I check the actual window size using glutGet.
I have found that when GLUT reduces the window size due to the X11 window manager’s rules, a bug is manifested:
Namely, when I draw in the window for the first time, my contents are off-center because OpenGL apparently still thinks the window is the requested size, not the actual size.
Is there any way to get around this bug?
What I am having to do now is, if I didn’t get the size I wanted, I destroy the 1st window and re-create it in the maximum allowed size that glutGet(GLUT_WINDOW_WIDTH) and glutGet(GLUT_WINDOW_HEIGHT) gave me.
Thanks.

You can use glutGet(GLUT_SCREEN_WIDTH) and glutGet(GLUT_SCREEN_HEIGHT) to determine the screen dimensions. A full-screen window should normally have the same dimensions. But you may not be able to create a non-full-screen window with those dimensions because of the borders (which a full-screen window normally lacks). X11 allows windows to be larger than the screen, but a window manager might not allow this.

It isn’t a bug. Or rather, it’s a bug in your code, not in GLUT or OpenGL. You need to use glutResizeFunc() to obtain notification of window size (both the initial size and any subsequent changes) and specify the correct viewport with glViewport(). You can set the viewport either in the resize function or in the display function. You typically need to change the projection matrix as well, otherwise the view will be distorted if the aspect ratio changes.

OpenGL sets the viewport the first time a context is bound to a drawable, but will never automatically change it thereafter. You can’t assume that you’ll actually get the requested window size, or that it will remain constant; the OS (or the window manager in the case of X11) has the final say. So you need to set the viewport yourself.

I’m already doing that, but it doesn’t fix the problem:

   void glutResizeFunc(int w, int h) {
        glViewport (0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        // previously did glOrtho here, it didn't help.
        glutPostRedisplay ();
    }

Remember this bug, where the model is shifted downward, only happens during the 1st redraw; subsequent ones are fine. My drawing code asks GLUT for the window size and correctly draws two triangles that fill the window but these are abnormally shifted downward at first.

[QUOTE=vraime;1293519]I’m already doing that, but it doesn’t fix the problem:


void glutResizeFunc(int w, int h) {
        glViewport (0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        // previously did glOrtho here, it didn't help.
}

[/QUOTE]
Well unless the window is square or you’re otherwise correcting the aspect ratio, you need to call glOrtho() (or similar) somewhere. And if you aren’t calling it in the resize function, then you’ll need to store the width and height for later use (unless you query the size with glutGet() in the display function, which is potentially slow due to needing a round-trip to the X server).

Well, that might be a bug. It may be related to creating a full-screen window first, so try using glutGet(GLUT_SCREEN_WIDTH) (and *_HEIGHT) instead. Also, with FreeGLUT (which most distributions use instead of the original MJK GLUT) you can use glutGet(GLUT_WINDOW_BORDER_WIDTH) (and *_HEIGHT) to query the border dimensions (the difference between the external width/height of the window and the width/height of the drawable area). So you could create a smaller window, query the border dimensions, then subtract those from the screen dimensions to obtain the desired dimensions for a maximised window. It’s possible the issue is caused by the window manager moving and resizing the window after creation, so creating the window such that it doesn’t need resizing may help.

Or you could just create the window at a reduced size and wait for the user to maximise it. Or rely upon the user configuring their window manager to maximise it.

If the issue is related to startup, one option is to have a flag which indicates that initialisation is complete. Until that flag is set, don’t draw anything. Before calling glutMainLoop(), use glutIdleFunc() to install an idle callback. Have the idle callback set the flag, uninstall the idle callback, and call glutPostRedisplay(). This may help to avoid issues related to the initialisation sequence.

[QUOTE=GClements;1293525] Also, with FreeGLUT (which most distributions use instead of the original MJK GLUT) you can use glutGet(GLUT_WINDOW_BORDER_WIDTH) (and *_HEIGHT) to query the border dimensions.

If the issue is related to startup, one option is to have a flag which indicates that initialisation is complete. Until that flag is set, don’t draw anything. Before calling glutMainLoop(), use glutIdleFunc() to install an idle callback. Have the idle callback set the flag, uninstall the idle callback, and call glutPostRedisplay(). This may help to avoid issues related to the initialisation sequence.[/QUOTE]

I checked and both my Linux and MacOS lack GLUT_WINDOW_BORDER_WIDTH.

I tried the delay idea though and it works, but only if in my draw routine when the flag is not yet set, I call glClear followed by glutSwapBuffers. This fills the window with black momentarily and then the first correct model appears.
Whereas if I merely return without doing the clear/swap I still see the shifted model.

Thanks.