Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Letterboxed rendering for full screen windows on Retina MBP #4

Closed
jaredjones opened this issue Apr 23, 2013 · 29 comments
Closed

Letterboxed rendering for full screen windows on Retina MBP #4

jaredjones opened this issue Apr 23, 2013 · 29 comments
Assignees
Labels
bug Bug reports and bugfix pull requests High DPI High resolution display specific macOS
Milestone

Comments

@jaredjones
Copy link

Mac OS: 10.8.4
Mac: Macbook Pro w/ Retina 15" (MC950LL) (2880x1800) ran at 1440*900
RAM: 16GB
Video Card: Switchable Intel HD 4000 / nVidia 650 GT

Commit: "7423cfa5bf3324c0526a92d9d7a5aa36bf0c7604"

Whenever I choose to put GLFW into Full Screen on my Retina using glfwGetPrimaryMonitor() it is not matching my appropriate resolution, at least it appears that way.

What happens is everything inside of the OpenGL View is fuzzy, it almost looks like when it went full screen that it didn't go to my computers resolution. I can assure you that this is not due to the fact that I'm seeing it pixely because I'm on a retina... Its actually fuzzy, like the aspect ratio is off. Also on the top and bottom of my screen there is a black bar. Both black bars are about 100 Pixels in height and the width of the black bar is the width of my monitor. I set the glColor to blue so thats how I see the black bar.
Its also not an issue with GLFWvidmode because its reporting the proper resolution for my display.

CODE IM USING TO GO INTO FULL SCREEN:

GLFWvidmode mainMonVidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
GLFWwindow* window = glfwCreateWindow(mainMonVidMode.width, mainMonVidMode.height, "Welcome to My Game", glfwGetPrimaryMonitor(), NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);

I also cannot figure out why this is happening in the source code of GLFW 3.0 either. In cocoa_window.m the following code is the proper code to enter full screen. However once it goes into full screen like I said everything is blurry like it didn't go into fullscreen at the proper resolution.

if (wndconfig->monitor)
{
if (!_glfwSetVideoMode(window->monitor, &window->videoMode))
return GL_FALSE;
_glfwPlatformShowWindow(window);
[[window->ns.object contentView] enterFullScreenMode:wndconfig->monitor->ns.screen
withOptions:nil];
}

@jaredjones
Copy link
Author

Also its important to note that Full Screen worked perfectly in 2.7.4.

Another thing I've found out is that if I change the X and the Y to something weird like 5x5 pixels the program will actually fully fill my screen. The program will still look blurry but the black bars go away. This confuses me, if I change it to something like 5x5 shouldn't that make black bars appear and wouldn't that also make whatever I have in my view VERY bad quality?
GLFWwindow* window = glfwCreateWindow(5,5, "Welcome to My Game", glfwGetPrimaryMonitor(), NULL);

@ghost ghost assigned elmindreda Apr 23, 2013
@elmindreda
Copy link
Member

This sounds very odd. I don't (yet) have any idea why this problem occurs.

@elmindreda
Copy link
Member

Does it work in 2.7.8?

@jaredjones
Copy link
Author

Yes in 2.7.8 if I enter the resolution of my screen aka half of the real resolution 1440x900 it will work but its pixely, however this is only due to the fact that there isn't retina support in 2.7.8. Anyhow to answer your question, 2.7.8 works correctly.

Full Retina Res: (2880x1800)

@elmindreda
Copy link
Member

Does current master work for you?

@jaredjones
Copy link
Author

Sorry I am unable to test the latest master...
OS X Mavericks is Apple's next OS and is not officially supported nor is it the final product. As you may know, OS X Mavericks provided support for OpenGL 4.1.

However upon building GLFW Master commit: 22e1aa6

Xcode is getting a build error and the build error does not lie within GLFW code but within The Khronos Group file GLEXT.H. I am getting an error on line number 6165 saying "typedef unsigned int GLhandleARB" is a redefinition with different types ('unsigned int' vs 'void *')
No idea what is going on but if I comment out the line which is a BAD idea the build will succeed however nothing is outputted and non of the static libraries are found on my system. Upon compiling I also get deprecation warnings that CGDisplayIOServicePort is deprecated and so is SetFrontProcess.

So unfortunately looks like I won't be able to test out GLFW on OS X 10.9.

@elmindreda
Copy link
Member

Thank you for having a go, though.

@elmindreda
Copy link
Member

Is this still reproducible with 3.0.3? I haven't had anyone else report this issue.

@AndriPalsson
Copy link
Contributor

Yes I also see the letterbox effect in fullscreen on my MBP 15" retina with 3.0.3. However I don't see the fuzzy effect @TheOatman is reporting

@vbo
Copy link

vbo commented Nov 28, 2013

I don't see any of this effects no my 13'' retina MBP (OS X 10.8.5). Don't have access to 15'' right now to check.

@jaredjones
Copy link
Author

I haven't had much time recently, however this issue seems to have been resolved with none of my own code changes just from using the latest commit. This issue was probably fixed over 4 months ago. Thanks Elmindreda for keeping this open until I was able to verify that the issue was resolved!

Issue Works As of Testing: d937b74
OS: 10.9.1

Issue Is Closing

@elmindreda
Copy link
Member

Thank you for following up! Very relieved to see it's been resolved.

@sarnesjo
Copy link

I'm sorry to say that it seems that this bug (or one with the same symptoms) is still around in GLFW 3.0.4. When I try to create a 1440x900 fullscreen window, I instead get a letterboxed 1280x720 window. Here is a fairly minimal test case:

#include <GLFW/glfw3.h>
#include <stdio.h>

int main()
{
  glfwInit();

  GLFWwindow *window = glfwCreateWindow(1440, 900, "", glfwGetPrimaryMonitor(), NULL);
  glfwMakeContextCurrent(window);

  int window_width, window_height, framebuffer_width, framebuffer_height;
  glfwGetWindowSize(window, &window_width, &window_height);
  glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
  printf("window: %d,%d\n", window_width, window_height);
  printf("framebuffer: %d,%d\n", framebuffer_width, framebuffer_height);

  glfwDestroyWindow(window);
  glfwTerminate();
  return 0;
}

And here is its output:

window: 1280,720
framebuffer: 2560,1440

I have a 15" Retina MBP (MacBookPro10,1) with dual graphics cards (Intel HD Graphics 4000 and Nvidia GeForce GT 650M) and a physical display resolution of 2880x1800 pixels. It is running Mac OS X 10.9.2 and Windows 7 (using Boot Camp).

Two interesting things:

  1. This bug only manifests on Mac OS X. If I compile and run the same code on the same machine, but on Windows, it works as expected. (I have not tested on Linux.)
  2. I actually had the same problem when using SDL. With a bit of help, I was able to work around it by creating the window hidden, then creating the OpenGL context, and then showing the window. I don't know if that translates to GLFW, but here are my findings anyway:

@dmitshur
Copy link
Collaborator

@sarnesjo What's your output of running the ./tests/modes binary?

@sarnesjo
Copy link

@shurcooL Here it is:

Name: Color LCD (primary)
Current mode: 1440 x 900 x 24 (8 8 8) 59 Hz
Virtual position: 0 0
Physical size: 331 x 206 mm (110 dpi)
Modes:
  0: 640 x 480 x 24 (8 8 8) 59 Hz
  1: 800 x 600 x 24 (8 8 8) 59 Hz
  2: 1024 x 768 x 24 (8 8 8) 59 Hz
  3: 1280 x 800 x 24 (8 8 8) 59 Hz
  4: 1440 x 900 x 24 (8 8 8) 59 Hz (current mode)
  5: 1680 x 1050 x 24 (8 8 8) 59 Hz
  6: 2048 x 1280 x 24 (8 8 8) 59 Hz
  7: 2560 x 1600 x 24 (8 8 8) 59 Hz
  8: 2880 x 1800 x 24 (8 8 8) 59 Hz

@dmitshur
Copy link
Collaborator

Interesting. I'll try the above code on a rMBP and report what happens.

@sarnesjo
Copy link

Thanks for looking into this.

Meanwhile, I have one more data point: I connected an external (non-retina) display to my rMBP and tried running the code, and it worked correctly - I got a fullscreen window with the size I requested.

@sarnesjo
Copy link

I tried using using master (aa6f8d4), and that worked a little better. Here's the output of the program above:

window: 1440,900
framebuffer: 2880,1800

So that's good. However, if I edit the program to request other resolutions, results are mixed.

840x525 (that's 1680x1050, divided by 2) works:

window: 840,525
framebuffer: 1680,1050

640x480 does not:

window: 1920,1080
framebuffer: 3840,2160

1280x800 is even weirder, doesn't even do the retina thing:

window: 2880,1800
framebuffer: 2880,1800

@dmitshur
Copy link
Collaborator

I can confirm @sarnesjo's findings on an Early 2013 15" Retina MacBook Pro, with latest OS X 10.9.2.

Using 3.0.4, asking for 1440x900 creates a 1280x720 fullscreen window.

Using master (aa6f8d4), it works correctly, creating a 1440x900 fullscreen window.

# Try to create 1440x900 fullscreen.
$ clang++ win.cpp ./glfw_3.0.4/src/libglfw3.a -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo && ./a.out
window: 1280,720
framebuffer: 2560,1440
$ clang++ win.cpp ./glfw_master/src/libglfw3.a -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo && ./a.out 
window: 1440,900
framebuffer: 2880,1800

However, even master fails for 640x480 and 1280x800 (creating 1920x1080 and 2880x1800 instead, respectively). The good news, 3.0.4 fails the same way for those 2 resolutions, so master is in every way an improvement over 3.0.4.

Since this is a real issue, you should probably make a new issue or find an open issue related to this. This one is closed and hard to find/track.

Edit: I'll try the same on a non-Retina MBP, and I suspect that things will work correctly, so this is likely a Retina-only problem.

Edit 2: Ahh, I should've also tried with commit d937b74, which was reported to have fixed the issue. That way we could learn if this is a regression or not. Edit: Just tried with d937b74, and it gave exacty the same broken results as 3.0.4 for the three resolutions. Edit: Just realized that commit is effectively the same as 3.0.4, they're 1 commit apart, with only a README.md edit.

@dmitshur
Copy link
Collaborator

What do you know, it's not Retina specific. A similar issue is happening on a Late 2011 15" MacBook Pro with latest OS X 10.9.2.

$ ./glfw/tests/modes 
Name: Color LCD (primary)
Current mode: 1680 x 1050 x 24 (8 8 8) 59 Hz
Virtual position: 0 0
Physical size: 330 x 206 mm (129 dpi)
Modes:
  0: 640 x 480 x 24 (8 8 8) 59 Hz
  1: 720 x 480 x 24 (8 8 8) 59 Hz
  2: 800 x 500 x 24 (8 8 8) 59 Hz
  3: 800 x 600 x 24 (8 8 8) 59 Hz
  4: 1024 x 640 x 24 (8 8 8) 59 Hz
  5: 1024 x 768 x 24 (8 8 8) 59 Hz
  6: 1152 x 720 x 24 (8 8 8) 59 Hz
  7: 1280 x 800 x 24 (8 8 8) 59 Hz
  8: 1440 x 852 x 24 (8 8 8) 59 Hz
  9: 1280 x 1024 x 24 (8 8 8) 59 Hz
 10: 1680 x 1050 x 24 (8 8 8) 59 Hz (current mode)

Asking for 1680x1050 fullscreen window gets me that. But,

Requested Got
640x480 1152x720
1024x768 1440x852
1280x800 1280x1024

Not even close.

Edit: I even tried glfw 3.0.2, and it keeps happening. I have a feeling that maybe OS X 10.9.2 changed/broke something. But it still needs to be fixed (and tested on 10.9.2, as well as older versions, if possible).

@sarnesjo
Copy link

I have dug deeper into this, to try to work out if the problem is in GLFW or the underlying Apple APIs, and found that there is definitely something strange going on in the latter.

Here is a test program that gets the current display mode, and then sets that as the display mode. It doesn't use GLFW, but talks directly to Quartz Display Services, the API that GLFW uses to enumerate and set display modes.

CGDirectDisplayID display = CGMainDisplayID();
CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(display);
printf("%ld %ld\n", CGDisplayModeGetWidth(currentMode), CGDisplayModeGetHeight(currentMode));
CGDisplaySetDisplayMode(display, currentMode, NULL);

As one might expect, it is a no-op, and prints (on my machine) 1440 900, which is correct assuming it's meant to use points rather than pixels, which the documentation says it should. So far, so good.

Now look at this program, which gets the current display mode, then finds one just like it, and then sets that as the current mode:

CGDirectDisplayID display = CGMainDisplayID();
CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(display), newMode = NULL;
CFArrayRef modes = CGDisplayCopyAllDisplayModes(display, NULL);

for (CFIndex i = 0; i < CFArrayGetCount(modes); ++i)
{
  CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i);
  printf("%ld %ld %ld\n", i, CGDisplayModeGetWidth(mode), CGDisplayModeGetHeight(mode));

  // not a good enough test in general, but sufficient on my machine (see the output)
  if (CGDisplayModeGetWidth(mode) == CGDisplayModeGetWidth(currentMode) &&
      CGDisplayModeGetHeight(mode) == CGDisplayModeGetHeight(currentMode))
  {
    newMode = mode;
  }
}

if (newMode)
{
  CGDisplaySetDisplayMode(display, newMode, NULL);
}

And its output:

0 2880 1800
1 1440 900
2 2560 1600
3 2048 1280
4 1024 768
5 800 600
6 640 480
7 1680 1050
8 1280 800

You'd imagine that this would also be a no-op, but it's not. What it does, is to set the display mode to 1440 by 900 pixels, effectively "de-retinizing" the display.

So that's a problem. Guess I'll file a bug with Apple.

@sarnesjo
Copy link

Alright, I've reported the above to Apple. However, since @shurcooL was able to reproduce a similar problem on a non-retina MBP, I guess there's more to it.

@dmitshur
Copy link
Collaborator

OS X 10.9.3 (Build 13D65) has been released today. I've updated from 10.9.2 and re-ran the above tests on my non-Retina MBP, using latest master (aa6f8d4) as well as 3.0.4.

This time, everything seems to work correctly for both versions.

Requested Result (10.9.3, aa6f8d4) Result (10.9.3, 3.0.4)
640x480 Success Success
800x600 Success Success
1024x768 Success Success
1280x800 Success Success

@sarnesjo Can you confirm that 10.9.3 fixes the issue on your Retina MBP?

@sarnesjo
Copy link

Sadly, no. These are my results with GLFW 3.0.4:

Requested Result (window) Result (framebuffer)
640x480 840x525 1680x1050
800x600 840x525 1680x1050
1024x768 960x540 1920x1080
1280x800 1440x900 1440x900
1440x900 1280x720 2560x1440

And with master (aa6f8d4):

Requested Result (window) Result (framebuffer)
640x480 840x525 1680x1050
800x600 840x525 1680x1050
1024x768 960x540 1920x1080
1280x800 1440x900 1440x900
1440x900 1440x900 2880x1800

./tests/modes gives the same output as before.

Further, my test that uses Quartz Display Services directly (above) continues to fail in the same way.

@maxscott
Copy link

Similar issue here. Glfw3, late 2013 macbook pro, native resolution 2560x1440.

GLFWmonitor* mon = glfwGetPrimaryMonitor ();
const GLFWvidmode* vmode = glfwGetVideoMode (mon);
g_gl_width = vmode->width;
g_gl_height = vmode->height;

gives me 1440 and 900 respectively. If I set the glViewport to these sizes, however, I end up with a fullscreen window (at 2560x1440) with a viewport of 1440x900.

It's like glfw makes a full screen window, and thinks it's smaller in pixels than it is? Love to help out more if I can. Thanks!

@elmindreda elmindreda modified the milestones: 3.2, 3.0.4 Jul 26, 2014
@elmindreda elmindreda reopened this Jul 26, 2014
@jaredjones
Copy link
Author

I personally would leave the bug in 3.0.4. As far as I know the issue is resolved in the master branch.

@maxscott
Copy link

Will try--I'm on osx and haven't been using cmake, just the brew glfw3,
I'll give it a shot when I can. Thanks.

On Sat, Jul 26, 2014 at 7:11 PM, Jared Jones notifications@github.com
wrote:

Guys make sure you are using master. I believe this issue is resolved.


Reply to this email directly or view it on GitHub
#4 (comment).

@ghost
Copy link

ghost commented Aug 26, 2014

fwiw, this is key:

http://slicer-devel.65872.n3.nabble.com/Support-for-quot-Retina-quot-displays-td4030716.html

have been trying to figure out how to patch cmake to include this in the glfw/examples/CMakeLists.txt. probably just need to make a custom:

http://www.cmake.org/cmake/help/git-master/prop_tgt/MACOSX_BUNDLE_INFO_PLIST.html?highlight=macosx_bundle_info_plist

but anyway, when i manually updated the Info.plist to include that NSPrincipalClass key, and GLFWApplication as the value.. the examples suddenly started working on retina..

also, will need to move the application to another folder to prevent the caching issues with accessing the plist.. just thought i'd share though if others run into this issue. may be related to other retina issues too.

@elmindreda elmindreda modified the milestones: 3.1, 3.2 Sep 11, 2014
@elmindreda
Copy link
Member

@maxwerr Video mode dimensions are in screen coordinates, not pixels, as are window sizes and positions. To set the viewport you need to use the framebuffer size, which is in pixels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug reports and bugfix pull requests High DPI High resolution display specific macOS
Projects
None yet
Development

No branches or pull requests

7 participants