Full-screen mode in libGDX

Recently I switched from LWJGL2 to LWJGL3 backend for my desktop app and had to adopt full-screen switching code since LWJGL3 handles things a bit differently.

The problem is with full-screen mode in case we DO NOT choose to use primary monitor’s current display mode but some custom mode (e.g. custom width & height pair). In case we want to switch to custom full-screen mode, we can’t just provide LWJGL3 with our custom width or height but instead choose between display modes that selected monitor supports (here we deal with primary monitor only, it’s easy to adopt for any other monitor).

In order to use our custom width & height, we need to find the closest mode that the monitor supports. Here’s a little code that does just that:

 

	/**
	 * Finds the best fitting display mode on primary monitor that is closest to given dimensions.
	 * Should be used for full-screen modes only.
	 *
	 * @param width desired full-screen width
	 * @param height desired full-screen height
	 * @return best matching mode display mode (according to width/height) or null if no mode has been found (which should never happen). Prefers highest refresh rate and "bits-per-pixel".
	 */
	private static Graphics.DisplayMode findClosestDisplayMode(int width, int height) {
		Graphics.DisplayMode[] modes = Lwjgl3ApplicationConfiguration.getDisplayModes();
		int bestDiff = Integer.MAX_VALUE;
		Graphics.DisplayMode bestMode = null;
		
		for (Graphics.DisplayMode mode : modes) {
			int diff = Math.abs(mode.width - width) + Math.abs(mode.height - height);
			if ((diff < bestDiff) || ((diff == bestDiff) && (mode.refreshRate > bestMode.refreshRate)) || ((diff == bestDiff) && (mode.refreshRate == bestMode.refreshRate) && (mode.bitsPerPixel > bestMode.bitsPerPixel))) {
				bestDiff = diff;
				bestMode = mode;
			}
		}
		
		return bestMode;
	}

The above code will find best-matching display mode that our primary monitor supports. Such mode is determined by its size (whichever mode is closest to desired one). If several such modes exist, then the one with highest refresh rate is selected (and highest “bits-per-pixel”).

Actual use case from my app:

Graphics.DisplayMode mode = findClosestDisplayMode(game.settings.getScreenWidth(), game.settings.getScreenHeight());
if (mode == null) mode = Lwjgl3ApplicationConfiguration.getDisplayMode(); // this should never happen though. Fall back to current display mode for full screen.
config.setFullscreenMode(mode);