diff --git a/CHANGES b/CHANGES index d96c73924c2..763e09f4f05 100755 --- a/CHANGES +++ b/CHANGES @@ -14,7 +14,8 @@ - API Addition: Added AndroidLiveWallpaper.notifyColorsChanged() to communicate visually significant colors back to the wallpaper engine. - API Change: AssetManager invokes the loaded callback when an asset is unloaded from the load queue if the asset is already loaded. - GWT: changed audio backend to WebAudio API. Now working on mobiles, pitch implemented. Configuration change: preferFlash removed. When updating existing projects, you can remove the soundmanager js files from your webapp folder and the references to it from index.html -- GWT added possibility to lazy load assets via AssetManager instead of preload them before game start. See GWT specifics wiki article for more information. +- GWT: added possibility to lazy load assets via AssetManager instead of preload them before game start. See GWT specifics wiki article for more information. +- GWT: New configuration setting usePhysicalPixels to use native resolution on mobile / Retina / HDPI screens. When using this option, make sure to update your code in index.html and HTMLLauncher from setup template. - Added support for Linux ARM builds. - 32-bit: ARMv7/armhf - 64-bit: ARMv8/AArch64 diff --git a/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtApplication.java b/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtApplication.java index 3f7e3c2ecf2..943390aecf3 100644 --- a/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtApplication.java +++ b/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtApplication.java @@ -114,20 +114,28 @@ public void onModuleLoad () { this.root = config.rootPanel; } else { Element element = Document.get().getElementById("embed-" + GWT.getModuleName()); + int width = config.width; + int height = config.height; + if (config.usePhysicalPixels) { + double density = GwtGraphics.getNativeScreenDensity(); + width = (int) (width / density); + height = (int) (height / density); + } + if (element == null) { VerticalPanel panel = new VerticalPanel(); - panel.setWidth("" + config.width + "px"); - panel.setHeight("" + config.height + "px"); + panel.setWidth("" + width + "px"); + panel.setHeight("" + height + "px"); panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); RootPanel.get().add(panel); - RootPanel.get().setWidth("" + config.width + "px"); - RootPanel.get().setHeight("" + config.height + "px"); + RootPanel.get().setWidth("" + width + "px"); + RootPanel.get().setHeight("" + height + "px"); this.root = panel; } else { VerticalPanel panel = new VerticalPanel(); - panel.setWidth("" + config.width + "px"); - panel.setHeight("" + config.height + "px"); + panel.setWidth("" + width + "px"); + panel.setHeight("" + height + "px"); panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); element.appendChild(panel.getElement()); diff --git a/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtApplicationConfiguration.java b/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtApplicationConfiguration.java index acd4ba85b64..86d972c3ae4 100644 --- a/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtApplicationConfiguration.java +++ b/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtApplicationConfiguration.java @@ -38,6 +38,14 @@ public class GwtApplicationConfiguration { /** the id of a canvas element to be used as the drawing area, can be null in which case a Panel and Canvas are added to the * body element of the DOM **/ public String canvasId; + /** Whether to use physical device pixels or CSS pixels for scaling the canvas. Makes a difference on mobile + * devices and HDPI and Retina displays. Set to true for resizable and fullscreen games on mobile devices and for + * Desktops if you want to use the full resolution of HDPI/Retina displays.
+ * Setting to false mostly makes sense for + * fixed-size games or non-mobile games expecting performance issues on huge resolutions. If you target mobiles + * and desktops, consider using physical device pixels on mobile devices only by using the return value of + * {@link GwtApplication#isMobileDevice()} . */ + public boolean usePhysicalPixels; /** a TextArea to log messages to, can be null in which case a TextArea will be added to the body element of the DOM. */ public TextArea log; /** whether to use debugging mode for OpenGL calls. Errors will result in a RuntimeException being thrown. */ @@ -64,4 +72,10 @@ public GwtApplicationConfiguration (int width, int height) { this.width = width; this.height = height; } + + public GwtApplicationConfiguration (int width, int height, boolean usePhysicalPixels) { + this.width = width; + this.height = height; + this.usePhysicalPixels = usePhysicalPixels; + } } diff --git a/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtGraphics.java b/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtGraphics.java index 1552c272a30..2b1e453bd55 100644 --- a/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtGraphics.java +++ b/backends/gdx-backends-gwt/src/com/badlogic/gdx/backends/gwt/GwtGraphics.java @@ -19,7 +19,6 @@ import com.badlogic.gdx.Application; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Graphics; -import com.badlogic.gdx.backends.gwt.GwtGraphics.OrientationLockType; import com.badlogic.gdx.graphics.Cursor; import com.badlogic.gdx.graphics.Cursor.SystemCursor; import com.badlogic.gdx.graphics.GL20; @@ -29,6 +28,7 @@ import com.badlogic.gdx.utils.GdxRuntimeException; import com.google.gwt.canvas.client.Canvas; import com.google.gwt.dom.client.CanvasElement; +import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.webgl.client.WebGLContextAttributes; import com.google.gwt.webgl.client.WebGLRenderingContext; @@ -69,9 +69,8 @@ public GwtGraphics (Panel root, GwtApplicationConfiguration config) { if (canvasWidget == null) throw new GdxRuntimeException("Canvas not supported"); canvas = canvasWidget.getCanvasElement(); root.add(canvasWidget); - canvas.setWidth(config.width); - canvas.setHeight(config.height); this.config = config; + setCanvasSize(config.width, config.height); WebGLContextAttributes attributes = WebGLContextAttributes.create(); attributes.setAntialias(config.antialiasing); @@ -169,22 +168,22 @@ public GLVersion getGLVersion () { @Override public float getPpiX () { - return 96; + return 96f * (float) getNativeScreenDensity(); } @Override public float getPpiY () { - return 96; + return 96f * (float) getNativeScreenDensity(); } @Override public float getPpcX () { - return 96 / 2.54f; + return getPpiX() / 2.54f; } @Override public float getPpcY () { - return 96 / 2.54f; + return getPpiY() / 2.54f; } @Override @@ -210,7 +209,7 @@ private native boolean supportsFullscreenJSNI () /*-{ @Override public DisplayMode[] getDisplayModes () { - return new DisplayMode[] {new DisplayMode(getScreenWidthJSNI(), getScreenHeightJSNI(), 60, 8) {}}; + return new DisplayMode[] {getDisplayMode()}; } private native int getScreenWidthJSNI () /*-{ @@ -248,8 +247,7 @@ private native boolean isFullscreenJSNI () /*-{ private void fullscreenChanged () { if (!isFullscreen()) { - canvas.setWidth(config.width); - canvas.setHeight(config.height); + setCanvasSize(config.width, config.height); if (config.fullscreenOrientation != null) unlockOrientation(); } else { /* We just managed to go full-screen. Check if the user has requested a specific orientation. */ @@ -257,11 +255,11 @@ private void fullscreenChanged () { } } - private native boolean setFullscreenJSNI (GwtGraphics graphics, CanvasElement element) /*-{ + private native boolean setFullscreenJSNI(GwtGraphics graphics, CanvasElement element, int screenWidth, int screenHeight)/*-{ // Attempt to use the non-prefixed standard API (https://fullscreen.spec.whatwg.org) if (element.requestFullscreen) { - element.width = $wnd.screen.width; - element.height = $wnd.screen.height; + element.width = screenWidth; + element.height = screenHeight; element.requestFullscreen(); $doc .addEventListener( @@ -273,8 +271,8 @@ private native boolean setFullscreenJSNI (GwtGraphics graphics, CanvasElement el } // Attempt to the vendor specific variants of the API if (element.webkitRequestFullScreen) { - element.width = $wnd.screen.width; - element.height = $wnd.screen.height; + element.width = screenWidth; + element.height = screenHeight; element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); $doc .addEventListener( @@ -285,8 +283,8 @@ private native boolean setFullscreenJSNI (GwtGraphics graphics, CanvasElement el return true; } if (element.mozRequestFullScreen) { - element.width = $wnd.screen.width; - element.height = $wnd.screen.height; + element.width = screenWidth; + element.height = screenHeight; element.mozRequestFullScreen(); $doc .addEventListener( @@ -297,8 +295,8 @@ private native boolean setFullscreenJSNI (GwtGraphics graphics, CanvasElement el return true; } if (element.msRequestFullscreen) { - element.width = $wnd.screen.width; - element.height = $wnd.screen.height; + element.width = screenWidth; + element.height = screenHeight; element.msRequestFullscreen(); $doc .addEventListener( @@ -327,7 +325,9 @@ private native void exitFullscreen () /*-{ @Override public DisplayMode getDisplayMode () { - return new DisplayMode(getScreenWidthJSNI(), getScreenHeightJSNI(), 60, 8) {}; + double density = config.usePhysicalPixels ? getNativeScreenDensity() : 1; + return new DisplayMode((int) (getScreenWidthJSNI() * density), + (int) (getScreenHeightJSNI() * density), 60, 8) {}; } @Override @@ -352,16 +352,27 @@ public int getSafeInsetRight() { @Override public boolean setFullscreenMode (DisplayMode displayMode) { - if (displayMode.width != getScreenWidthJSNI() && displayMode.height != getScreenHeightJSNI()) return false; - return setFullscreenJSNI(this, canvas); + DisplayMode supportedMode = getDisplayMode(); + if (displayMode.width != supportedMode.width && displayMode.height != supportedMode.height) return false; + return setFullscreenJSNI(this, canvas, displayMode.width, displayMode.height); } @Override public boolean setWindowedMode (int width, int height) { if (isFullscreenJSNI()) exitFullscreen(); + setCanvasSize(width, height); + return true; + } + + private void setCanvasSize(int width, int height) { canvas.setWidth(width); canvas.setHeight(height); - return true; + + if (config.usePhysicalPixels) { + double density = getNativeScreenDensity(); + canvas.getStyle().setWidth(width / density, Style.Unit.PX); + canvas.getStyle().setHeight(height / density, Style.Unit.PX); + } } @@ -490,9 +501,20 @@ public void setVSync (boolean vsync) { @Override public float getDensity () { - return 96.0f / 160; + return (getPpiX()) / 160; } + /** + * See https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio for more information + * + * @return value indicating the ratio of the display's resolution in physical pixels to the resolution in CSS + * pixels. A value of 1 indicates a classic 96 DPI (76 DPI on some platforms) display, while a value of 2 + * is expected for HiDPI/Retina displays. + */ + public static native double getNativeScreenDensity() /*-{ + return $wnd.devicePixelRatio || 1; + }-*/; + @Override public void setContinuousRendering (boolean isContinuous) { } diff --git a/extensions/gdx-setup/res/com/badlogic/gdx/setup/resources/html/src/HtmlLauncher b/extensions/gdx-setup/res/com/badlogic/gdx/setup/resources/html/src/HtmlLauncher index 05541480212..6d61bb17420 100644 --- a/extensions/gdx-setup/res/com/badlogic/gdx/setup/resources/html/src/HtmlLauncher +++ b/extensions/gdx-setup/res/com/badlogic/gdx/setup/resources/html/src/HtmlLauncher @@ -27,17 +27,31 @@ public class HtmlLauncher extends GwtApplication { // Window.enableScrolling(false); // Window.setMargin("0"); // Window.addResizeHandler(new ResizeListener()); - // cfg.preferFlash = false; + // + // If you want to support mobile screens, set usePhysicalPixels and convert the size + // cfg.usePhysicalPixels = true; + // double density = GwtGraphics.getNativeScreenDensity(); + // cfg.width = (int) (cfg.width * density); + // cfg.height = (int) (cfg.height * density); + // // return cfg; // } // // class ResizeListener implements ResizeHandler { // @Override // public void onResize(ResizeEvent event) { + // if (Gdx.graphics.isFullscreen()) + // return; + // // int width = event.getWidth() - PADDING; // int height = event.getHeight() - PADDING; // getRootPanel().setWidth("" + width + "px"); // getRootPanel().setHeight("" + height + "px"); + // if (cfg.usePhysicalPixels) { + // double density = GwtGraphics.getNativeScreenDensity(); + // width = (int) (width * density); + // height = (int) (height * density); + // } // getApplicationListener().resize(width, height); // Gdx.graphics.setWindowedMode(width, height); // } diff --git a/extensions/gdx-setup/res/com/badlogic/gdx/setup/resources/html/war/index b/extensions/gdx-setup/res/com/badlogic/gdx/setup/resources/html/war/index index da0078a1476..848dfabe365 100644 --- a/extensions/gdx-setup/res/com/badlogic/gdx/setup/resources/html/war/index +++ b/extensions/gdx-setup/res/com/badlogic/gdx/setup/resources/html/war/index @@ -14,9 +14,6 @@