问题
I'm working on a libGDX (library on top of LWJGL) game project, and use the Intellij IDEA IDE from several different workstations:
- Windows 7 x64 laptop with two displays (1920x1080 and 1600x1200), nVidia GT540M.
- Ubuntu 12.04 LTS on a laptop with a single display (1366x768), Intel integrated graphics.
- Ubuntu 12.04 LTS on a desktop with two displays (1920x1080 and 1280x1024), nVidia GTS 450.
I'm using the OpenJDK for Java 6 on the Ubuntu boxes, and Sun/Oracle Java 6 on the Windows box (I heard Java 6 was the one to use for Android compatibility).
When running on full-screen:
- Windows 7 laptop: works fine.
- Ubuntu laptop: works fine.
- Ubuntu desktop: background image is shown enlarged, and only part of it fits on the screen. +
Looking into this further, I see that the calls to Gdx.graphics.getHeight() and Gdx.graphics.getWidth() return the size of the rectangle needed to cover both displays, in my case 3200x1080, but when I tell my game to run full-screen, it only uses one of the displays, so the cameras get set to 1920x1080, but my camera movement and Tiled map panning think they've got 3200x1080 to work with, making things distorted and unusable (since character can walk off of the screen to the right).
I'm guessing my problem actually comes from the sizes returned by the awt.Toolkit's getScreenSize() call, but I don't know how to interrogate it more deeply to get the size of the screen it will actually use when I go fullscreen.
My DesktopStarter gets the screen size and sets fullscreen as follows:
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
cfg.width = screenDimension.width;
cfg.height = screenDimension.height;
cfg.fullscreen = true;
new LwjglApplication(new Game1(), cfg);
Is there a work-around to get the height/width of just the display that "full screen" will actually launch into?
So the trouble I'm seeing, is that executing the game.jar file, exiting the game, then executing again, repeatedly, results in different display modes showing up in the list of modes returned by Gdx.graphics.getDisplayModes() -- as P.T. pointed out below, this is a thin wrapper around LWJGL's Display.getAvailableDisplayModes()
. Why is this happening? Why would it be a different set of modes presented on subsequent runs on Ubuntu?
edit: per P.T.'s suggestion, put LWJGL references in question, since it seems to be LWJGL that's providing the list of display modes.
Thanks!
回答1:
I would refrain from using Toolkit.getDefaultToolkit()
and use solely lwjgl.util.Display.getAvailableDisplayModes() or the method described by libgdx.
Once you have set up a fullscreen window, fetch its size (if your set-up method doesn't already know that) and only use this information from thereon.
If Display.getAvailableDisplayModes() changes its sort order on different executions, simply re-sort them and use the biggest one available or use a standard one and provide in-game settings to change them.
回答2:
GraphicsDevice monitors[]=GraphicsEnvironment.getScreenDevices();
Dimension screen_resolution[monitors.length];
for (int monitorID = 0; monitorID < monitors.length; monitorID++)
{
screen_resolution[monitorID] = new Dimension(monitors[monitorID].getDisplyMode().getWidth(),monitors[monitorID].getDisplyMode().getHeight());
}
回答3:
You could use javafx.stage.screen
to work around this issue, but you'd either have to add JavaFX if you stick with Java 6, or upgrade to Java 7 (It's included with the Java 7 SDK.)
From the documentation:
"Describes the characteristics of a graphics destination such as monitor. In a virtual device multi-screen environment in which the desktop area could span multiple physical screen devices, the bounds of the Screen objects are relative to the Screen.primary.
For example:
Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
//set Stage boundaries to visible bounds of the main screen stage.setX(primaryScreenBounds.getMinX()); stage.setY(primaryScreenBounds.getMinY()); stage.setWidth(primaryScreenBounds.getWidth()); stage.setHeight(primaryScreenBounds.getHeight());
stage.show();"
There are a variety of other methods (getBounds(), getDpi(), getScreens()
, etc.) that would also likely be very useful for you.
回答4:
Maybe get the dimensions of the monitor your currently using, so on the different sized monitors, just get the dimensions. You may have to do things differently for different sized monitors.
Maybe the background image is enlarged due to it thinking it's still working on the other screens.
Hope this helps, if not gl
回答5:
I would refrain from using lwjgl completely. It may seem simple enough on the surface, but as you try to add in more advanced features, you'll realize that a wrapper over OpenGL won't give you that functionality, or it'll make the program 3x slower. I suggest moving into c++ and OpenGL (if this is an option). You will be surprised at its simplicity. Otherwise, cross-platform libraries generally do have these sorts of glitches. To solve your problem, you need to stop relying on the library to determine your viewport resolutions. Instead, enumerate through all the possible display modes and pick the best one according to you. This will result in much more defined behavior and will be easier to debug than utilizing a default config which appears as if by magic. In general, you want to always be sure you know what data you are using. Even worse, I just noticed that you are using a wrapper over a wrapper. This over-complicates and will slow down rendering much more that you can imagine (20x on average).
回答6:
Here
http://www.lwjgl.org/wiki/index.php?title=LWJGL_Basics_5_%28Fullscreen%29
you will find a convenience method for lwjgl to chose a suitable full screen display mode for your desktop. You can use the same method to determine the resolution as well and use it for your gl ops later.
回答7:
I am not sure but it worked for me. Just set the size after "start" the game, like in the following code:
public static void main(String[] args) {
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
cfg.title = "Palmeiras!!";
cfg.vSyncEnabled = false;
cfg.forceExit = true;
cfg.allowSoftwareMode = true;
new LwjglApplication(new Palmeiras(null), cfg);
Gdx.graphics.setDisplayMode(Gdx.graphics.getDesktopDisplayMode().width,
Gdx.graphics.getDesktopDisplayMode().height, true);
}
Let me know if it worked for you.
回答8:
I would refrain from using Toolkit.getDefaultToolkit() and use solely lwjgl.util.Display.getAvailableDisplayModes() or the method described by libgdx.
Once you have set up a fullscreen window, fetch its size (if your set-up method doesn't already know that) and only use this information from thereon.
If Display.getAvailableDisplayModes() changes its sort order on different executions, simply re-sort them and use the biggest one available or use a standard one and provide in-game settings to change them.
来源:https://stackoverflow.com/questions/16452784/java-and-libgdx-lwjgl-game-fullscreen-wrong-size-for-multiple-monitors-on-ubun