配置和查询
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 待续
网友评论