配置和查詢
libGDX有一個精心設計的API,可讓您查詢監視器和顯示模式,并切換垂直同步(vsync)。 這可以在配置應用程序或運行時完成。
注意:Android和iOS不支持顯示模式更改
查詢和設置顯示器和顯示模式(運行時)
在配置時查詢監視器和顯示模式是平臺相關的.以下小節說明了在每個平臺上可以對顯示器和顯示模式做些什么。
LWJGL平臺
使用默認的LWJGL 2后端,您可以獲得主監視器的可用顯示模式,如下所示:
DisplayMode[] modes = LwjglApplicationConfiguration.getDisplayModes();
您可以獲得主監視器(也稱為桌面模式)的當前顯示模式,如下所示:
DisplayMode desktopMode = LwjglApplicationConfiguration.getDesktopDisplayMode();
一旦你有一個DisplayMode,你可以在LwjglApplicationConfiguration上設置它:
DisplayMode displayMode = LwjglApplicationConfiguration.getDesktopDisplayMode();
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.setFromDisplayMode(displayMode);
new LwjglApplication(new MyAppListener(), config);
您的應用程序將以全屏模式啟動(使用DisplayMode對象中的分辨率)。
要在窗口模式下啟動應用程序,只需指定窗口的寬度和高度:
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.width = 800;
config.height = 600;
new LwjglApplication(new MyAppListener(), config);
您還可以通過指定相對于監視器當前顯示模式的左上角坐標,將窗口放在主監視器特定位置上:
config.x = 100;
config.y = 100;
要使窗口居中,請使用-1作為坐標(默認值)。
最后,您還可以指定應用程序是否應啟用vsync(垂直同步):
config.vSyncEnabled = true;
LWJGL 3平臺
當涉及顯示器和顯示模式時,LWJGL 3后端更加精細。 與LWJGL 2后端不同,它支持多顯示器設置。
在配置時查詢所有可用的顯示器的代碼如下:
Monitor[] monitors = Lwjgl3ApplicationConfiguration.getMonitors();
要獲得主顯示器:
Monitor primary = Lwjgl3ApplicationConfiguration.getPrimaryMonitor();
要獲取顯示器的所有支持的顯示模式,請調用:
DisplayMode[] displayModes = Lwjgl3ApplicationConfiguration.getDisplayModes(monitor);
要獲取顯示器的當前顯示模式,請撥打:
DisplayMode desktopMode = Lwjgl3ApplicationConfiguration.getDisplayMode(monitor);
獲取主顯示器的顯示模式也有一些困難:
DisplayMode[] primaryDisplayModes = Lwjgl3ApplicationConfiguration.getDisplayModes();
DisplayMode primaryDesktopMode = Lwjgl3ApplicationConfiguration.getDisplayMode();
當你得到了DisplayMode ,您可以將其設置到Lwjgl3ApplicationConfiguration上:
DisplayMode primaryMode = LWjgl3ApplicationConfiguration.getDisplayMode();
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setFullscreenMode(primaryMode);
new Lwjgl3ApplicationConfiguration(new MyAppListener(), config);
如此,將使得主顯示器以設置好的顯示模式以全屏的模式啟動,如果你使用其他顯示器的顯示模式啟動當前顯示器,它也會以當前的顯示模式全屏啟動,但是可能會失敗(因為可能不存在該顯示模式).
注意:建議始終使用顯示器的當前顯示模式,其他顯示模式可能會失敗。
要在窗口模式下啟動應用程序,請在配置中調用此方法:
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setWindowedMode(800, 600);
這將在主顯示器上以窗口模式啟動您的應用程序。 如果你要設置窗口的精確位置:
config.setWindowPosition(100, 100);
您還可以指定您的窗口是否應該調整大小,以及是否有裝飾(窗口標題欄,邊框):
config.setResizable(false);
config.setDecorated(false);
The LWJGL 3 backend also allows you to specify how to deal with HDPI monitors. The operating system may report logical sizes and coordinates instead of pixel-based coordinates to you for drawing surface sizes or mouse events. E.g. on a Macbook Pro with a retina display running Mac OS X, the OS reports only half the width/height of the underlying pixel surface. The LWJGL 3 backend can report drawing surface sizes as returned by Gdx.graphics.getWidth()/getHeight() and mouse coordinates either in those logical coordinates, or in pixel coordinates. To configure this behaviour, set a HDPI mode:
LWJGL 3后端還允許您指定如何處理HDPI監視器,要配置此行為,請設置HDPI模式:
config.setHdpiMode(HdpiMode.Logical);
This will report mouse coordinates and drawing surface sizes in logical coordinates. It is also the default for this backend. If you want to work in raw pixels, use HdpiMode.Pixels. Note that when using logical coordinates, you will have to convert these to pixel coordinates for OpenGL functions like glScissor, glViewport or glReadPixels. All libGDX classes calling these functions will take into account the HdpiMode you set. If you call these functions yourself, use HdpiUtils.
運行時查詢和設置顯示器和顯示模式
LibGDX通過Graphics 接口提供API,可以在運行時查詢監視器,顯示模式和其他相關方面。 一旦知道可能的配置,你可以設置它們,例如 切換到全屏模式,或切換垂直同步。
檢查是否支持顯示模式更改
只有一部分平臺支持顯示模式更改。 值得注意的是,Android和iOS不支持切換到任意全屏顯示模式。 更改顯示模式之前檢查您的應用程序當前正在運行的平臺是否支持顯示模式更改是一個不錯的習慣:
if(Gdx.graphics.supportsDisplayModeChange()) {
// change display mode if necessary
}
請注意,圖形中所有與顯示模式有關的功能將不會在不支持顯示模式更改的平臺上執行任何操作。
查詢監視器
要查詢所有連接的顯示器,請使用以下方法:
Monitor[] monitors = Gdx.graphics.getMonitors();
在Android,iOS,GWT和LWJGL 2后端,只有主顯示器才會被返回, LWJGL 3后端返回所有連接的顯示器。
如果僅僅查詢主監視器,請使用:
Monitor primary = Gdx.graphics.getPrimaryMonitor();
要查詢當前窗口所在的顯示器,可以調用如下代碼:
Monitor currMonitor = Gdx.graphics.getMonitor();
It is good practice to toggle full-screen on the monitor the window is on, instead of say the primary monitor. This allows users to move the application window to another monitor, and then enable full-screen mode there.
查詢顯示模式
一旦你有了Monitor 實例后,您可以查詢其支持的顯示模式:
DisplayMode[] modes = Gdx.graphics.getDisplayModes(monitor);
要獲取當前顯示模式,請使用以下方法:
DisplayMode currMode = Gdx.graphics.getDisplayMode(monitor);
切換到全屏模式
使用來自特定顯示器的DisplayMode,您可以切換到全屏,如下所示:
Monitor currMonitor = Gdx.graphics.getMonitor();
DisplayMode displayMode = Gdx.graphics.getDisplayMode(monitor);
if(!Gdx.graphics.setFullscreenMode(displayMode)) {
// switching to full-screen mode failed
}
如果切換到全屏模式失敗,后端將恢復最后一個窗口模式配置。
切換到窗口模式
要更改窗口的大小,或從全屏模式切換到窗口模式,請使用以下方法:
Gdx.graphics.setWindowedMode(800, 600);
將窗口設置為窗口模式,并將其定位在調用此方法之前的顯示器上。
多窗口API(LWJGL 3后端)
一些應用程序(如編輯器或其他僅限桌面的工具)可從多窗口設置中受益。 LWJGL 3后端提供了一個額外的非跨平臺API來創建多個窗口。
每一個程序都是配置窗口屬性開始:
Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
config.setWindowedMode(800, 600);
new Lwjgl3ApplicationConfiguration(new MyMainWindowListener(), config);
在這個例子中,窗口由MyMainWindowListener(一個標準的ApplicationListener)驅動。 libGDX不直接報告圖標化或焦點丟失等事件。 為此,LWJGL 3后端引入了一個名為Lwjgl3WindowListener的桌面專用接口。 您可以提供此接口的實現來接收和響應這些事件:
config.setWindowListener(new Lwjgl3WindowListener() {
@Override
public void iconified() {
// the window is not visible anymore, potentially stop background
// work, mute audio, etc.
}
@Override
public void deiconified() {
// the window is visible again, start-up background work, unmute
// audio, etc.
}
@Override
public void focusLost() {
// the window lost focus, pause the game
}
@Override
public void focusGained() {
// the window received input focus, unpause the game
}
@Override
public boolean windowIsClosing() {
// if there's unsaved stuff, we may not want to close
// the window, but ask the user to save her work
if(isStuffUnsaved) {
// tell our app listener to show a save dialog
return false;
} else {
// OK, the window may close
return true;
}
});
如果窗口失去焦點,LWJGL 3后端不會報告暫停和恢復事件。 只有在應用程序被 iconfified/deiconified 時才會報告暫停和恢復事件,或者應用程序關閉。
為了產生其他窗口,您的代碼需要將Gdx.app轉換為Lwjgl3Application。 這只有在您的項目直接依賴于LWJGL 3后端時才可能。 您將無法與其他平臺共享此類代碼。 一旦你有一個Lwjgl3Application,你可以創建一個這樣的新窗口:
Lwjgl3Application lwjgl3App = (Lwjgl3Application)Gdx.app;
Lwjgl3WindowConfiguration windowConfig = new Lwjgl3WindowConfiguration();
windowConfig.setWindowListener(new MyWindowListener());
windowConfig.setTitle("My other window");
Lwjgl3Window window = Lwjgl3App.newWindow(new MyOtherWindowAppListener(), windowConfig);
建議讓每個窗口都有自己的ApplicationListener。 一個應用程序的所有窗口在同一個線程上更新,一個接一個。 LWJGL 3后端將確保為當前正在更新的窗口設置靜態Gdx.graphics和Gdx.input。 這意味著您的ApplicationListener本質上可以忽略其他窗口,并且假裝它是城里唯一的監聽器。
這有一個例外。 當使用Gdx.app.postRunnable()時,LWJGL 3后端無法決定Runnable已經發布了哪個窗口。 例如。 該方法可能已經從工作線程被調用,并且在Runnable被發布的時候,當前可以更新不同的窗口。 要解決這個問題,建議將窗口特定的Runnable實例直接發送到窗口:
····java
// e.g. in a worker thread
window.postRunnable(new MyRunnable());
····
這樣可以確保在執行Runnable時為特定窗口設置靜態Gdx.graphics和Gdx.input。
Lwjgl3Window類有其他方法可以修改Windows屬性。 您可以在ApplicationListener中獲取當前窗口,然后繼續修改它:
// in ApplicationListener#render()
Lwjgl3Window window = ((Lwjgl3Graphics)Gdx.graphics).getWindow();
window.setVisible(false); // hide the window
window.iconifyWindow(); // iconify the window
window.deiconifyWindow(); // deiconify window
window.closeWindow(); // close the window, also disposes the ApplicationListener
//TODO 待續