Skip to content

Commit

Permalink
Added HDPI (retina) support to LWJGL backend. Use the LwjglApplicatio…
Browse files Browse the repository at this point in the history
…nConfiguration.useHDPI switch
  • Loading branch information
badlogic committed Dec 31, 2014
1 parent 6ed55ac commit 744aa85
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 31 deletions.
3 changes: 3 additions & 0 deletions CHANGES
@@ -1,3 +1,6 @@
[1.5.3]
- Added LwjglApplicationConfiguration.useHDPI for Mac OS X with retina displays. Allows you to get "real" pixel coordinates for mouse and display coordinates.

[1.5.2]
- Fixed issue #2433 with color markup and alpha animation.
- Fixed natives loading for LWJGL on Mac OS X
Expand Down
Expand Up @@ -178,13 +178,13 @@ void mainLoop () {
} else {
graphics.config.x = Display.getX();
graphics.config.y = Display.getY();
if (graphics.resize || Display.wasResized() || Display.getWidth() != graphics.config.width
|| Display.getHeight() != graphics.config.height) {
graphics.resize = false;
Gdx.gl.glViewport(0, 0, Display.getWidth(), Display.getHeight());
graphics.config.width = Display.getWidth();
graphics.config.height = Display.getHeight();
if (listener != null) listener.resize(Display.getWidth(), Display.getHeight());
if (graphics.resize || Display.wasResized() || (int)(Display.getWidth() * Display.getPixelScaleFactor()) != graphics.config.width
|| (int)(Display.getHeight() * Display.getPixelScaleFactor()) != graphics.config.height) {
graphics.resize = false;
graphics.config.width = (int)(Display.getWidth() * Display.getPixelScaleFactor());
graphics.config.height = (int)(Display.getHeight() * Display.getPixelScaleFactor());
Gdx.gl.glViewport(0, 0, graphics.config.width, graphics.config.height);
if (listener != null) listener.resize(graphics.config.width, graphics.config.height);
graphics.requestRendering();
}
}
Expand Down
Expand Up @@ -75,6 +75,8 @@ public class LwjglApplicationConfiguration {
public String preferencesDirectory = ".prefs/";
/** Callback used when trying to create a display, can handle failures, default value is null (disabled) */
public LwjglGraphics.SetDisplayModeCallback setDisplayModeCallback;
/** enable HDPI mode on Mac OS X **/
public boolean useHDPI = false;

Array<String> iconPaths = new Array();
Array<FileType> iconFileTypes = new Array();
Expand Down
Expand Up @@ -81,14 +81,14 @@ public int getHeight () {
if (canvas != null)
return Math.max(1, canvas.getHeight());
else
return Display.getHeight();
return (int)(Display.getHeight() * Display.getPixelScaleFactor());
}

public int getWidth () {
if (canvas != null)
return Math.max(1, canvas.getWidth());
else
return Display.getWidth();
return (int)(Display.getWidth() * Display.getPixelScaleFactor());
}

public boolean isGL20Available () {
Expand Down Expand Up @@ -129,10 +129,14 @@ void updateTime () {
}

void setupDisplay () throws LWJGLException {
if(config.useHDPI) {
System.setProperty("org.lwjgl.opengl.Display.enableHighDPI", "true");
}

if (canvas != null) {
Display.setParent(canvas);
} else {
boolean displayCreated = setDisplayMode(config.width, config.height, config.fullscreen);
boolean displayCreated = setDisplayMode(config.width, config.height, config.fullscreen);
if (!displayCreated) {
if (config.setDisplayModeCallback != null) {
config = config.setDisplayModeCallback.onFailure(config);
Expand Down Expand Up @@ -318,16 +322,18 @@ public LwjglDisplayMode (int width, int height, int refreshRate, int bitsPerPixe

@Override
public boolean setDisplayMode (DisplayMode displayMode) {
org.lwjgl.opengl.DisplayMode mode = ((LwjglDisplayMode)displayMode).mode;
org.lwjgl.opengl.DisplayMode mode = ((LwjglDisplayMode)displayMode).mode;
try {
if (!mode.isFullscreenCapable()) {
Display.setDisplayMode(mode);
} else {
Display.setDisplayModeAndFullscreen(mode);
}
if (Gdx.gl != null) Gdx.gl.glViewport(0, 0, displayMode.width, displayMode.height);
config.width = displayMode.width;
config.height = displayMode.height;
System.out.println(Display.getPixelScaleFactor());
float scaleFactor = Display.getPixelScaleFactor();
config.width = (int)(mode.getWidth() * scaleFactor);
config.height = (int)(mode.getHeight() * scaleFactor);
if (Gdx.gl != null) Gdx.gl.glViewport(0, 0, config.width, config.height);
resize = true;
return true;
} catch (LWJGLException e) {
Expand Down Expand Up @@ -382,9 +388,10 @@ public boolean setDisplayMode (int width, int height, boolean fullscreen) {
Display.setFullscreen(fullscreen);
Display.setResizable(!fullscreen && config.resizable);

if (Gdx.gl != null) Gdx.gl.glViewport(0, 0, targetDisplayMode.getWidth(), targetDisplayMode.getHeight());
config.width = targetDisplayMode.getWidth();
config.height = targetDisplayMode.getHeight();
float scaleFactor = Display.getPixelScaleFactor();
config.width = (int)(targetDisplayMode.getWidth() * scaleFactor);
config.height = (int)(targetDisplayMode.getHeight() * scaleFactor);
if (Gdx.gl != null) Gdx.gl.glViewport(0, 0, config.width, config.height);
resize = true;
return true;
} catch (LWJGLException e) {
Expand Down
Expand Up @@ -46,6 +46,7 @@
import org.lwjgl.input.Cursor;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
Expand Down Expand Up @@ -196,11 +197,11 @@ public void windowGainedFocus (WindowEvent arg0) {
}

public int getX () {
return Mouse.getX();
return (int)(Mouse.getX() * Display.getPixelScaleFactor());
}

public int getY () {
return Gdx.graphics.getHeight() - 1 - Mouse.getY();
return Gdx.graphics.getHeight() - 1 - (int)(Mouse.getY() * Display.getPixelScaleFactor());
}

public boolean isAccelerometerAvailable () {
Expand Down Expand Up @@ -771,8 +772,8 @@ void updateMouse () {
int events = 0;
while (Mouse.next()) {
events++;
int x = Mouse.getEventX();
int y = Gdx.graphics.getHeight() - Mouse.getEventY() - 1;
int x = (int)(Mouse.getEventX() * Display.getPixelScaleFactor());
int y = Gdx.graphics.getHeight() - (int)(Mouse.getEventY() * Display.getPixelScaleFactor()) - 1;
int button = Mouse.getEventButton();
int gdxButton = toGdxButton(button);
if (button != -1 && gdxButton == -1) continue; // Ignore unknown button.
Expand Down Expand Up @@ -809,8 +810,8 @@ void updateMouse () {
touchEvents.add(event);
mouseX = event.x;
mouseY = event.y;
deltaX = Mouse.getEventDX();
deltaY = Mouse.getEventDY();
deltaX = (int)(Mouse.getEventDX() * Display.getPixelScaleFactor());
deltaY = (int)(Mouse.getEventDY() * Display.getPixelScaleFactor());
}

if (events == 0) {
Expand Down
Expand Up @@ -30,7 +30,7 @@ public final class LwjglNativesLoader {
static public boolean load = true;

static {
System.setProperty("org.lwjgl.input.Mouse.allowNegativeMouseCoords", "true");
System.setProperty("org.lwjgl.input.Mouse.allowNegativeMouseCoords", "true");

// Don't extract natives if using JWS.
try {
Expand Down
Expand Up @@ -19,6 +19,7 @@
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.tests.FullscreenTest;
import com.badlogic.gdx.tests.InputTest;
import com.badlogic.gdx.tests.JsonReaderTest;
import com.badlogic.gdx.tests.extensions.ControllersTest;
import com.badlogic.gdx.tests.utils.GdxTest;
Expand Down
24 changes: 17 additions & 7 deletions tests/gdx-tests/src/com/badlogic/gdx/tests/FullscreenTest.java
Expand Up @@ -53,21 +53,31 @@ public void render () {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

batch.begin();
batch.draw(tex, Gdx.input.getX(), Gdx.input.getY());
batch.draw(tex, Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY());
font.draw(batch, "" + Gdx.graphics.getWidth() + ", " + Gdx.graphics.getHeight(), 0, 20);
batch.end();

if (Gdx.input.justTouched()) {
if (fullscreen) {
Gdx.graphics.setDisplayMode(480, 320, false);
batch.getProjectionMatrix().setToOrtho2D(0, 0, 480, 320);
Gdx.gl.glViewport(0, 0, 480, 320);
batch.getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
fullscreen = false;
} else {
DisplayMode desktopDisplayMode = Gdx.graphics.getDesktopDisplayMode();
Gdx.graphics.setDisplayMode(desktopDisplayMode.width, desktopDisplayMode.height, true);
batch.getProjectionMatrix().setToOrtho2D(0, 0, desktopDisplayMode.width, desktopDisplayMode.height);
Gdx.gl.glViewport(0, 0, desktopDisplayMode.width, desktopDisplayMode.height);
DisplayMode m = null;
for(DisplayMode mode: Gdx.graphics.getDisplayModes()) {
if(m == null) {
m = mode;
} else {
if(m.width < mode.width) {
m = mode;
}
}
}

Gdx.graphics.setDisplayMode(m);
batch.getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
fullscreen = true;
}
}
Expand Down

16 comments on commit 744aa85

@frustaci
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey, i'm trying to use master branch after a long hiatus, but im getting a error in libgdx that might be related to this commit. Is there any chance i messed up or missing something?

Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: java.lang.NoSuchMethodError: org.lwjgl.opengl.Display.getPixelScaleFactor()F
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:121)
Caused by: java.lang.NoSuchMethodError: org.lwjgl.opengl.Display.getPixelScaleFactor()F
at com.badlogic.gdx.backends.lwjgl.LwjglGraphics.getWidth(LwjglGraphics.java:91)
at com.badlogic.gdx.backends.lwjgl.LwjglGraphics.setDisplayMode(LwjglGraphics.java:346)
at com.badlogic.gdx.backends.lwjgl.LwjglGraphics.setupDisplay(LwjglGraphics.java:139)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:132)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)

@frustaci
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it's something related with this not being up to date (http://libgdx.badlogicgames.com/jglfw/nightlies/dist/) and me using a arcane build method. :)

@frustaci
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even the "old style builds" nightly from http://libgdx.badlogicgames.com/download.html is broken :(

@badlogic
Copy link
Member Author

@badlogic badlogic commented on 744aa85 Jan 14, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frustaci
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually the problem is that getPixelScaleFactor is only implemented on OS X as per http://wiki.lwjgl.org/index.php?title=Using_High_DPI_Mode
Im on windows, tried about everything even updated lwjgl manually only to find that out, so i think the build still broken on windows :)
Thats why GdxRuntimeException -> NoSuchMethodError

@badlogic
Copy link
Member Author

@badlogic badlogic commented on 744aa85 Jan 14, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@badlogic
Copy link
Member Author

@badlogic badlogic commented on 744aa85 Jan 14, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frustaci
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well just tried a gradle sample, seems to be running just fine. So I'm at loss why my old project wont run without gradle.

@badlogic
Copy link
Member Author

@badlogic badlogic commented on 744aa85 Jan 14, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frustaci
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, replaced manually just to be sure and recompiled libgdx. I can even locate the Display.class from inside my project in gdx-backend-lwjgl.jar where I can see getPixelScaleFactor is defined. Natives updated too.

@badlogic
Copy link
Member Author

@badlogic badlogic commented on 744aa85 Jan 14, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frustaci
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only difference I can see is that in case of gradle there's both gdx-backend-lwjgl-1.5.2.jar without the lwjgl stuff and lwjgl-2.9.2.jar is included apart + natives.
On my project there's only gdx-backend-lwjgl.jar that includes everything (lwjgl stuff) the old way + natives.
My wild guess is that somehow the LwjglGraphics.getWidth cant find the org.lwjgl.opengl.Display.getPixelScaleFactor in the same package, but I have no clue why.

@badlogic
Copy link
Member Author

@badlogic badlogic commented on 744aa85 Jan 14, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@badlogic
Copy link
Member Author

@badlogic badlogic commented on 744aa85 Jan 14, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frustaci
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, ill try to figure out :)

@frustaci
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out I had a deprecated long forgotten backend jogl that had a copy of lwjgl in the path that was causing problems. Now it works. :)

Please sign in to comment.