Skip to content

Commit

Permalink
GWT: New config setting to use native resolution on mobile / Retina /…
Browse files Browse the repository at this point in the history
… HDPI screens (#5691)

* GWT: Option to use physical pixels for retina and hdpi displays

* GWT: Changes to resizable application template for usePhysicalPixels

* GWT: use physical pixels verbose JavaDoc

* GWT: HTMLLauncher template fix resize listener resets fullscreen mode

* Enable physical pixels for our tests

* Added GWT nativ res addition to CHANGES

* Formatting

Co-authored-by: SimonIT <simonit.orig@gmail.com>
  • Loading branch information
MrStahlfelge and SimonIT committed Aug 29, 2020
1 parent 1db2aa8 commit cca4726
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 36 deletions.
3 changes: 2 additions & 1 deletion CHANGES
Expand Up @@ -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
Expand Down
Expand Up @@ -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());
Expand Down
Expand Up @@ -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.<br/>
* 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. */
Expand All @@ -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;
}
}
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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 () /*-{
Expand Down Expand Up @@ -248,20 +247,19 @@ 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. */
if (config.fullscreenOrientation != null) lockOrientation(config.fullscreenOrientation);
}
}

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(
Expand All @@ -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(
Expand All @@ -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(
Expand All @@ -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(
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
}


Expand Down Expand Up @@ -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) {
}
Expand Down
Expand Up @@ -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);
// }
Expand Down
Expand Up @@ -14,9 +14,6 @@
</body>

<script>
document.getElementById('gameViewport').setAttribute('content',
'width=device-width initial-scale=' + 1/window.devicePixelRatio);

function handleMouseDown(evt) {
evt.preventDefault();
evt.stopPropagation();
Expand Down
Expand Up @@ -19,14 +19,18 @@
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.backends.gwt.GwtApplication;
import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration;
import com.badlogic.gdx.backends.gwt.GwtGraphics;
import com.badlogic.gdx.tests.gwt.GwtTestWrapper;

public class GwtTestStarter extends GwtApplication {
@Override
public GwtApplicationConfiguration getConfig () {
GwtApplicationConfiguration config = new GwtApplicationConfiguration(480, 320);
GwtApplicationConfiguration config = new GwtApplicationConfiguration(480, 320, true);
config.useGyroscope = true;
//config.openURLInNewWindow = true;
double density = GwtGraphics.getNativeScreenDensity();
config.width = (int) (config.width * density);
config.height = (int) (config.height * density);
return config;
}

Expand Down

0 comments on commit cca4726

Please sign in to comment.