Skip to content

Commit b3ff35d

Browse files
committed
highdpi
1 parent 909708d commit b3ff35d

18 files changed

Lines changed: 1338 additions & 209 deletions

File tree

jme3-android/src/main/java/com/jme3/app/AndroidHarnessFragment.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ public void reshape(int width, int height) {
225225
app.reshape(width, height);
226226
}
227227

228+
@Override
229+
public void reshape(int logicalWidth, int logicalHeight, int framebufferWidth, int framebufferHeight) {
230+
app.reshape(logicalWidth, logicalHeight, framebufferWidth, framebufferHeight);
231+
}
232+
228233
@Override
229234
public void rescale(float x, float y) {
230235
app.rescale(x, y);

jme3-android/src/main/java/com/jme3/input/android/AndroidMouseInput14.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ public void loadSettings(AppSettings settings) {
145145
if (inputHandler.getView().getWidth() != 0 && inputHandler.getView().getHeight() != 0) {
146146
scaleX = settings.getWidth() / (float)inputHandler.getView().getWidth();
147147
scaleY = settings.getHeight() / (float)inputHandler.getView().getHeight();
148-
currentMouseState.setStartPosition(inputHandler.getView().getWidth()/2, inputHandler.getView().getHeight()/2);
148+
currentMouseState.setStartPosition(
149+
getJmeX(inputHandler.getView().getWidth() / 2f),
150+
getJmeY(inputHandler.getView().getHeight() / 2f));
149151
}
150152

151153
if (logger.isLoggable(Level.FINE)) {

jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java

Lines changed: 116 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,10 @@
3737
import android.content.DialogInterface;
3838
import android.content.pm.ConfigurationInfo;
3939
import android.graphics.PixelFormat;
40-
import android.graphics.Rect;
4140
import android.opengl.GLSurfaceView;
4241
import android.os.Build;
4342
import android.text.InputType;
4443
import android.view.Gravity;
45-
import android.view.SurfaceHolder;
46-
import android.view.SurfaceView;
4744
import android.view.View;
4845
import android.view.ViewGroup.LayoutParams;
4946
import android.widget.EditText;
@@ -58,6 +55,7 @@
5855
import com.jme3.input.controls.SoftTextDialogInputListener;
5956
import com.jme3.input.dummy.DummyKeyInput;
6057
import com.jme3.material.Material;
58+
import com.jme3.math.Vector2f;
6159
import com.jme3.renderer.Caps;
6260
import com.jme3.renderer.Camera;
6361
import com.jme3.renderer.RenderManager;
@@ -68,6 +66,7 @@
6866
import com.jme3.texture.FrameBuffer.FrameBufferTarget;
6967
import com.jme3.texture.Image;
7068
import com.jme3.texture.Image.Format;
69+
import com.jme3.texture.Texture;
7170
import com.jme3.texture.Texture2D;
7271
import com.jme3.texture.image.ColorSpace;
7372
import com.jme3.ui.Picture;
@@ -99,6 +98,11 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
9998
protected AndroidInputHandler androidInput;
10099
protected long minFrameDuration = 0; // No FPS cap
101100
protected long lastUpdateTime = 0;
101+
private int logicalWidth = 1;
102+
private int logicalHeight = 1;
103+
private int framebufferWidth = 1;
104+
private int framebufferHeight = 1;
105+
private final Vector2f displayScale = new Vector2f(1f, 1f);
102106
private Application application;
103107
private Material blitMaterial;
104108
private Picture blitGeometry;
@@ -452,17 +456,45 @@ public void onSurfaceChanged(GL10 gl, int width, int height) {
452456
new Object[] { width, height }
453457
);
454458
}
455-
// update the application settings with the new resolution
456-
settings.setResolution(width, height);
459+
framebufferWidth = Math.max(width, 1);
460+
framebufferHeight = Math.max(height, 1);
461+
float density = getAndroidDisplayDensity();
462+
displayScale.set(density, density);
463+
float mode = settings.getDisplayScaleMode();
464+
if (mode == AppSettings.DISPLAY_SCALE_DPI_AWARE || mode > 0f) {
465+
logicalWidth = Math.max(Math.round(framebufferWidth / density), 1);
466+
logicalHeight = Math.max(Math.round(framebufferHeight / density), 1);
467+
} else {
468+
logicalWidth = framebufferWidth;
469+
logicalHeight = framebufferHeight;
470+
}
471+
settings.setResolution(logicalWidth, logicalHeight);
457472
// Reload settings in androidInput so the correct touch event scaling can be
458473
// calculated in case the surface resolution is different than the view.
459474
androidInput.loadSettings(settings);
460475
// if the application has already been initialized (ie renderable is set)
461476
// then call reshape so the app can adjust to the new resolution.
462477
if (renderable.get()) {
463478
logger.log(Level.FINE, "App already initialized, calling reshape");
464-
listener.reshape(width, height);
479+
listener.reshape(logicalWidth, logicalHeight, getRenderFramebufferWidth(), getRenderFramebufferHeight());
480+
listener.rescale(displayScale.x, displayScale.y);
481+
}
482+
}
483+
484+
private float getAndroidDisplayDensity() {
485+
if (androidInput != null && androidInput.getView() != null
486+
&& androidInput.getView().getResources() != null) {
487+
android.util.DisplayMetrics metrics = androidInput.getView().getResources().getDisplayMetrics();
488+
if (metrics != null) {
489+
if (metrics.density > 0f) {
490+
return metrics.density;
491+
}
492+
if (metrics.densityDpi > 0) {
493+
return metrics.densityDpi / 160f;
494+
}
495+
}
465496
}
497+
return 1f;
466498
}
467499

468500
// SystemListener:update
@@ -477,6 +509,10 @@ public void onDrawFrame(GL10 gl) {
477509
if (created.get()) {
478510
logger.fine("GL Surface is setup, initializing application");
479511
listener.initialize();
512+
if (framebufferWidth > 0 && framebufferHeight > 0) {
513+
listener.reshape(logicalWidth, logicalHeight, getRenderFramebufferWidth(), getRenderFramebufferHeight());
514+
listener.rescale(displayScale.x, displayScale.y);
515+
}
480516
renderable.set(true);
481517
}
482518
} else {
@@ -549,12 +585,35 @@ private boolean useBlitSrgbConversion() {
549585
return settings.isGammaCorrection() && application != null;
550586
}
551587

588+
private boolean useBlitFrameBuffer() {
589+
return application != null && (useBlitSrgbConversion() || settings.getDisplayScaleMode() > 0f);
590+
}
591+
592+
private int getRenderFramebufferWidth() {
593+
float mode = settings.getDisplayScaleMode();
594+
if (mode > 0f) {
595+
return Math.max(Math.round(framebufferWidth * mode), 1);
596+
}
597+
return Math.max(framebufferWidth, 1);
598+
}
599+
600+
private int getRenderFramebufferHeight() {
601+
float mode = settings.getDisplayScaleMode();
602+
if (mode > 0f) {
603+
return Math.max(Math.round(framebufferHeight * mode), 1);
604+
}
605+
return Math.max(framebufferHeight, 1);
606+
}
607+
552608
private int getLinearFrameBufferSampleCount() {
553609
int samples = Math.max(settings.getSamples(), 1);
554-
if (samples > 1 && renderer != null && !renderer.getCaps().contains(Caps.TextureMultisample)) {
610+
if (samples > 1 && renderer != null
611+
&& (!renderer.getCaps().contains(Caps.TextureMultisample)
612+
|| !renderer.getCaps().contains(Caps.OpenGL32))) {
555613
if (!multisampleTextureWarningIssued) {
556-
logger.warning("sRGB blit conversion requires multisampled textures for MSAA. "
557-
+ "Falling back to a single-sample linear framebuffer.");
614+
logger.log(Level.WARNING,
615+
"Display scale blit requested {0}x MSAA, but this backend cannot sample multisample textures for the blit path. Falling back to a single-sample linear framebuffer.",
616+
samples);
558617
multisampleTextureWarningIssued = true;
559618
}
560619
return 1;
@@ -563,13 +622,13 @@ private int getLinearFrameBufferSampleCount() {
563622
}
564623

565624
private void rebuildLinearFrameBufferIfNeeded() {
566-
if (!useBlitSrgbConversion()) {
625+
if (!useBlitFrameBuffer()) {
567626
destroyLinearFrameBufferResources();
568627
return;
569628
}
570629

571-
int width = Math.max(settings.getWidth(), 1);
572-
int height = Math.max(settings.getHeight(), 1);
630+
int width = getRenderFramebufferWidth();
631+
int height = getRenderFramebufferHeight();
573632
int samples = getLinearFrameBufferSampleCount();
574633

575634
if (linearFrameBuffer != null && linearFrameBuffer.getWidth() == width
@@ -585,6 +644,8 @@ private void rebuildLinearFrameBufferIfNeeded() {
585644

586645
Texture2D colorTexture = new Texture2D(
587646
new Image(getLinearFrameBufferColorFormat(), width, height, null, ColorSpace.Linear));
647+
colorTexture.setMagFilter(Texture.MagFilter.Bilinear);
648+
colorTexture.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
588649
if (samples > 1) {
589650
colorTexture.getImage().setMultiSamples(samples);
590651
}
@@ -610,7 +671,7 @@ private Format getLinearFrameBufferColorFormat() {
610671
}
611672

612673
private boolean ensureBlitResources() {
613-
if (!useBlitSrgbConversion()) {
674+
if (!useBlitFrameBuffer()) {
614675
return false;
615676
}
616677

@@ -622,10 +683,10 @@ private boolean ensureBlitResources() {
622683

623684
if (blitMaterial == null) {
624685
blitMaterial = new Material(assetManager, BLIT_MATERIAL);
625-
blitMaterial.setBoolean("Srgb", true);
626686
blitMaterial.getAdditionalRenderState().setDepthTest(false);
627687
blitMaterial.getAdditionalRenderState().setDepthWrite(false);
628688
}
689+
blitMaterial.setBoolean("Srgb", useBlitSrgbConversion());
629690

630691
if (blitGeometry == null) {
631692
blitGeometry = new Picture("Linear to sRGB Blit");
@@ -667,7 +728,7 @@ private void destroyLinearFrameBufferResources() {
667728
}
668729

669730
private boolean renderFrameWithBlitSrgbConversion() {
670-
if (!useBlitSrgbConversion()) {
731+
if (!useBlitFrameBuffer()) {
671732
return false;
672733
}
673734

@@ -699,8 +760,8 @@ private boolean renderFrameWithBlitSrgbConversion() {
699760
Camera previousCamera = renderManager.getCurrentCamera();
700761
try {
701762
renderer.setFrameBuffer(null);
702-
int blitWidth = linearFrameBuffer.getWidth();
703-
int blitHeight = linearFrameBuffer.getHeight();
763+
int blitWidth = Math.max(getFramebufferWidth(), 1);
764+
int blitHeight = Math.max(getFramebufferHeight(), 1);
704765
if (blitCamera.getWidth() != blitWidth || blitCamera.getHeight() != blitHeight) {
705766
blitCamera.resize(blitWidth, blitHeight, true);
706767
}
@@ -816,11 +877,19 @@ public void onClick(DialogInterface dialog, int whichButton) {
816877
*
817878
* @return the height (in pixels)
818879
*/
880+
@Override
881+
public int getLogicalHeight() {
882+
return logicalHeight;
883+
}
884+
885+
@Override
886+
public int getLogicalWidth() {
887+
return logicalWidth;
888+
}
889+
819890
@Override
820891
public int getFramebufferHeight() {
821-
Rect rect = getSurfaceFrame();
822-
int result = rect.height();
823-
return result;
892+
return framebufferHeight;
824893
}
825894

826895
/**
@@ -830,9 +899,33 @@ public int getFramebufferHeight() {
830899
*/
831900
@Override
832901
public int getFramebufferWidth() {
833-
Rect rect = getSurfaceFrame();
834-
int result = rect.width();
835-
return result;
902+
return framebufferWidth;
903+
}
904+
905+
@Override
906+
public Vector2f getDisplayScale(Vector2f store) {
907+
if (store == null) {
908+
store = new Vector2f();
909+
}
910+
return store.set(displayScale);
911+
}
912+
913+
@Override
914+
public Vector2f getPixelDensity(Vector2f store) {
915+
if (store == null) {
916+
store = new Vector2f();
917+
}
918+
return store.set((float) framebufferWidth / Math.max(logicalWidth, 1),
919+
(float) framebufferHeight / Math.max(logicalHeight, 1));
920+
}
921+
922+
@Override
923+
public Vector2f getInputScale(Vector2f store) {
924+
if (store == null) {
925+
store = new Vector2f();
926+
}
927+
return store.set((float) logicalWidth / Math.max(framebufferWidth, 1),
928+
(float) logicalHeight / Math.max(framebufferHeight, 1));
836929
}
837930

838931
/**
@@ -855,19 +948,6 @@ public int getWindowYPosition() {
855948
throw new UnsupportedOperationException("not implemented yet");
856949
}
857950

858-
/**
859-
* Retrieves the dimensions of the input surface. Note: do not modify the
860-
* returned object.
861-
*
862-
* @return the dimensions (in pixels, left and top are 0)
863-
*/
864-
private Rect getSurfaceFrame() {
865-
SurfaceView view = (SurfaceView) androidInput.getView();
866-
SurfaceHolder holder = view.getHolder();
867-
Rect result = holder.getSurfaceFrame();
868-
return result;
869-
}
870-
871951
@Override
872952
public Displays getDisplays() {
873953
// TODO Auto-generated method stub

jme3-core/src/main/java/com/jme3/app/LegacyApplication.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,8 +593,13 @@ public void startCanvas(boolean waitFor) {
593593
*/
594594
@Override
595595
public void reshape(int w, int h) {
596+
reshape(w, h, w, h);
597+
}
598+
599+
@Override
600+
public void reshape(int logicalWidth, int logicalHeight, int framebufferWidth, int framebufferHeight) {
596601
if (renderManager != null) {
597-
renderManager.notifyReshape(w, h);
602+
renderManager.notifyReshape(logicalWidth, logicalHeight, framebufferWidth, framebufferHeight);
598603
}
599604
}
600605

0 commit comments

Comments
 (0)