Hello Guest

[BUG] Incorrect viewport when switching to fullscreen (OS X, 2.9.x)

  • 2 Replies
  • 4578 Views
In OS X, switching to fullscreen sometimes results in a viewport in the lower-left corner of the screen with the same dimensions as the previous non-fullscreen window. I'm testing this in OS X 10.6.8, using both 2.9.0 and the latest nightly build (2.9.1).

Here's the test program (escape quits, space switches to fullscreen):

Code: [Select]
package fullscreentest;

import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import static org.lwjgl.opengl.GL11.*;

public class FullscreenTest
{
    public static void main(String[] args) throws Exception
    {
        Display.create();
        Display.setDisplayMode(new DisplayMode(640, 480));
        glViewport(0, 0, 640, 480);

        while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
            while (Keyboard.next()) {
                if (Keyboard.getEventKeyState() && Keyboard.getEventKey() == Keyboard.KEY_SPACE) {
                    DisplayMode displayMode = Display.getDesktopDisplayMode();
                    Display.setDisplayModeAndFullscreen(displayMode);
                    glViewport(0, 0, displayMode.getWidth(), displayMode.getHeight());
                }
            }

            glBegin(GL_QUADS);
            glColor3f(1f, 0f, 0f);
            glVertex2i(-1, -1);
            glVertex2i(1, -1);
            glColor3f(0f, 1f, 0f);
            glVertex2i(1, 1);
            glVertex2i(-1, 1);
            glEnd();
           
            Display.update();
        }
       
        Display.destroy();
    }
}

Here's what I noticed in the LWJGL code. In MacOSXDisplay.createWindow() is this bit of code:

Code: [Select]
if (fullscreen) {
    // when going to fullscreen viewport is set to screen size by Cocoa, ignore this value
    skipViewportValue = true;
    // if starting in fullscreen then set initial viewport to displaymode size
    if (current_viewport.get(2) == 0 && current_viewport.get(3) == 0) {
        current_viewport.put(2, mode.getWidth());
        current_viewport.put(3, mode.getHeight());
    }
}

I don't know for sure what the values in current_viewport would be prior to this code running, but if the width and height were that of the previous non-fullscreen window, it seems that current_viewport would remain unchanged after this code runs.

Then, in update() is:

Code: [Select]
if (skipViewportValue) skipViewportValue = false;
else glGetInteger(GL_VIEWPORT, current_viewport);
glViewport(current_viewport.get(0), current_viewport.get(1), current_viewport.get(2), current_viewport.get(3));

Which suggests that on the first call to update(), the viewport may be being set to that of the previous non-fullscreen window, which would explain the behavior in question.

This is easy enough to work around (e.g. by setting the viewport every frame prior to rendering), but it seemed like it might be worth mentioning.

I think that is normal OpenGL behavior. Until you change the viewport, it will stay the same no matter what happens to the window. You just need to reset the viewport whenever the size changes (see Display.wasResized()).
« Last Edit: July 16, 2013, 12:36:05 by Fool Running »
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Thanks for the reply.

I think that is normal OpenGL behavior. Until you change the viewport, it will stay the same no matter what happens to the window. You just need to reset the viewport whenever the size changes (see Display.wasResized()).

I don't know if you read the whole post - the example program does in fact reset the viewport, as you describe. The problem seems to be that LWJGL itself is setting the viewport in MacOSXDisplay.update(), but with the wrong values, which overrides the viewport set earlier. The example program demonstrates this behavior. (It's self-contained, so should be easy to test.)

Again, it's easy to work around, but it does appear to be a bug (unless I've overlooked something).