Using High DPI Mode

From LWJGL
Jump to: navigation, search

Note this guide require LWJGL 2.9.1 or greater and currently only implemented on OS X

High DPI resolution monitors have started to become more popular for desktop computers (even though mobile devices have had such screens as standard for a while now). Apple have introduced them to OS X with their retina displays and Windows 8 also introduced supported for such screens. In order for applications to use such high DPI resolutions they need to specifically opt in, probably to allow older applications built for non high DPI resolutions to continue to work without becoming really tiny.


In order to enable high DPI mode in LWJGL you'll have to toggle the org.lwjgl.opengl.Display.enableHighDPI switch:

This can be done as a VM parameter using:

-Dorg.lwjgl.opengl.Display.enableHighDPI=true

or in java code before creating the Display:

System.setProperty("org.lwjgl.opengl.Display.enableHighDPI", "true");


In such modes Operating Systems will scale the Display window to avoid the window shrinking due to high resolutions. The OpenGL frame buffer will however use the higher resolution and not be scaled to match the Display window size. This causes the coordinates/values of the Display and Mouse classes to differ from that of the actual frame buffer size.


In order to address this you will need to use the following LWJGL method:

Display.getPixelScaleFactor()

This will return a float value of how much the Display has been scaled by the Operating System. Thus you can calculate coordinates/values from the Display and Mouse classes that can be used with the OpenGL frame buffer.


To convert the scaled Display and Mouse coordinates to the high resolution value you simply multiply them by the pixel scale factor. Thus can be used by pixel dependent OpenGL methods such as glViewport, glTexImage2D, glReadPixels, glScissor, glLineWidth, glRenderbufferStorage, etc.

e.g.

Display.getWidth() * Display.getPixelScaleFactor()

This will return the high DPI width of the OpenGL frame buffer. Whereas Display.getWidth() will be the same as the OpenGL frame buffer in non high DPI mode.


Where high DPI mode is not available this method will just return 1.0f therefore not have any effect on values that are multiplied by it.


example usage:

GL11.glViewport(0, 0,
             Display.getWidth() * Display.getPixelScaleFactor(), 
             Display.getHeight() * Display.getPixelScaleFactor());