diff options
author | phil <[email protected]> | 2019-09-21 16:55:42 +1200 |
---|---|---|
committer | phil <[email protected]> | 2019-09-21 16:55:42 +1200 |
commit | 1775dd20eec91ef26ed03741a1d24a9d04a85833 (patch) | |
tree | eac79142e81f0d08ba4612e8c64412ffdb8d7d31 | |
parent | 2d5601907709810913846f1832bb6601c8ee550b (diff) |
HiDPI fix improved to work when moving a Canvas between screens, also
mouse interactions are now scaled correctly when using the
canvas.getPixelLocationInImagePlate(xpos,ypos,mousePosn); as seen in the
java3d-utils PickCanvas class
-rw-r--r-- | src/main/java/org/jogamp/java3d/Canvas3D.java | 11 | ||||
-rw-r--r-- | src/main/java/org/jogamp/java3d/CanvasViewCache.java | 39 | ||||
-rw-r--r-- | src/main/java/org/jogamp/java3d/CanvasViewEventCatcher.java | 7 |
3 files changed, 36 insertions, 21 deletions
diff --git a/src/main/java/org/jogamp/java3d/Canvas3D.java b/src/main/java/org/jogamp/java3d/Canvas3D.java index a4f2b95..c678631 100644 --- a/src/main/java/org/jogamp/java3d/Canvas3D.java +++ b/src/main/java/org/jogamp/java3d/Canvas3D.java @@ -32,14 +32,12 @@ import java.awt.Container; import java.awt.Dimension; import java.awt.Frame; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.IllegalComponentStateException; import java.awt.Point; import java.awt.Window; -import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Hashtable; @@ -824,8 +822,6 @@ ArrayList<Integer> textureIdResourceFreeList = new ArrayList<Integer>(); // CanvasViewEventCatcher. Point newPosition = new Point(); Dimension newSize = new Dimension(); - double xscale = 1.0; - double yscale = 1.0; // Remember OGL context resources to free // before context is destroy. @@ -1232,14 +1228,9 @@ ArrayList<TextureRetained> textureIDResourceTable = new ArrayList<TextureRetaine if (!firstPaintCalled && added && validCanvas && validGraphicsMode()) { - final Graphics2D g2d = (Graphics2D) g; - final AffineTransform t = g2d.getTransform(); try { - Dimension scaledSize = getSize(); - xscale = t.getScaleX(); - yscale = t.getScaleY(); - newSize = new Dimension((int)(scaledSize.getWidth()*xscale), (int)(scaledSize.getHeight()*yscale)); + newSize = getSize(); newPosition = getLocationOnScreen(); } catch (IllegalComponentStateException e) { return; diff --git a/src/main/java/org/jogamp/java3d/CanvasViewCache.java b/src/main/java/org/jogamp/java3d/CanvasViewCache.java index 8195302..1edb33e 100644 --- a/src/main/java/org/jogamp/java3d/CanvasViewCache.java +++ b/src/main/java/org/jogamp/java3d/CanvasViewCache.java @@ -26,7 +26,11 @@ package org.jogamp.java3d; +import java.awt.Graphics2D; +import java.awt.GraphicsDevice; +import java.awt.IllegalComponentStateException; import java.awt.Rectangle; +import java.awt.geom.AffineTransform; import org.jogamp.vecmath.Matrix4d; import org.jogamp.vecmath.Point2d; @@ -177,6 +181,11 @@ class CanvasViewCache extends Object { // ViewPlatform scale that takes coordinates from view platform // coordinates and scales them to physical coordinates private double viewPlatformScale; + + + // HiDPI scale + private double hiDPIXScale = 1.0; + private double hiDPIYScale = 1.0; // Various derived transforms @@ -568,9 +577,27 @@ class CanvasViewCache extends Object { screenWidth = screenViewCache.screenWidth; screenHeight = screenViewCache.screenHeight; + + // Find the current scale value for the screen, note this actually a + // property of the Screen3D but getting the value here makes refreshing + // on screen changes (for example when Canvs3D is moved to another screen + // at a different scale) easier. + // Note moving a JFrame from one screen scaling to another (in a multi-screen setup) + // in some setups will actually resize the by an incorrect amount, possibly it is a double factor. + // Hence a JFrame on a 100% screen moved to a 150% screen will resize to + // 150%x150% = 225%, and conversely a a 150% scale to a 100% scale will result in a + // 0.666x0.666 = 0.444 scaling. This is not a Java3D issue. + try { + final Graphics2D g2d = (Graphics2D) canvas.getGraphics(); + final AffineTransform t = g2d.getTransform(); + hiDPIXScale = t.getScaleX(); + hiDPIYScale = t.getScaleY(); + } catch (IllegalComponentStateException e) {} metersPerPixelX = screenViewCache.metersPerPixelX; metersPerPixelY = screenViewCache.metersPerPixelY; + + // If a multi-screen virtual device (e.g. Xinerama) is being used, // then awtCanvasX and awtCanvasY are relative to the origin of that @@ -581,8 +608,8 @@ class CanvasViewCache extends Object { canvasY = awtCanvasY - screenBounds.y; // Use awtCanvasWidth and awtCanvasHeight as reported. - canvasWidth = awtCanvasWidth; - canvasHeight = awtCanvasHeight; + canvasWidth = (int)(awtCanvasWidth * hiDPIXScale); + canvasHeight = (int)(awtCanvasHeight * hiDPIYScale); // Convert the window system ``pixel'' coordinate location and size // of the window into physical units (meters) and coordinate system. @@ -1906,14 +1933,14 @@ class CanvasViewCache extends Object { // Transform the specified X point in AWT window-relative coordinates // to image plate coordinates double getWindowXInImagePlate(double x) { - double xScreen = x + (double)canvasX; + double xScreen = (x * hiDPIXScale) + (double)canvasX; return metersPerPixelX * xScreen; } // Transform the specified Y point in AWT window-relative coordinates // to image plate coordinates double getWindowYInImagePlate(double y) { - double yScreen = y + (double)canvasY; + double yScreen = (y * hiDPIYScale) + (double)canvasY; return metersPerPixelY * ((double)(screenHeight - 1) - yScreen); } @@ -1929,8 +1956,8 @@ class CanvasViewCache extends Object { void getPixelLocationInImagePlate(double x, double y, double z, Point3d imagePlatePoint) { - double screenx = (x + canvasX)*metersPerPixelX; - double screeny = (screenHeight - 1 - canvasY - y)*metersPerPixelY; + double screenx = ((x * hiDPIYScale) + canvasX)*metersPerPixelX; + double screeny = (screenHeight - 1 - canvasY - (y * hiDPIYScale))*metersPerPixelY; if ((viewCache.projectionPolicy == View.PERSPECTIVE_PROJECTION) && (centerEyeInImagePlate.z != 0)) { diff --git a/src/main/java/org/jogamp/java3d/CanvasViewEventCatcher.java b/src/main/java/org/jogamp/java3d/CanvasViewEventCatcher.java index 966f359..f0413c1 100644 --- a/src/main/java/org/jogamp/java3d/CanvasViewEventCatcher.java +++ b/src/main/java/org/jogamp/java3d/CanvasViewEventCatcher.java @@ -26,7 +26,6 @@ package org.jogamp.java3d; -import java.awt.Dimension; import java.awt.IllegalComponentStateException; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; @@ -66,8 +65,7 @@ class CanvasViewEventCatcher extends ComponentAdapter { // see comment below try { - Dimension size = canvas.getSize(); - canvas.newSize = new Dimension((int)(size.getWidth()*canvas.xscale), (int)(size.getHeight()*canvas.yscale)); + canvas.newSize = canvas.getSize(); canvas.newPosition = canvas.getLocationOnScreen(); } catch (IllegalComponentStateException ex) {} @@ -92,8 +90,7 @@ class CanvasViewEventCatcher extends ComponentAdapter { // first, then canvas lock in removeComponentListener() try { - Dimension size = canvas.getSize(); - canvas.newSize = new Dimension((int)(size.getWidth()*canvas.xscale), (int)(size.getHeight()*canvas.yscale)); + canvas.newSize = canvas.getSize(); canvas.newPosition = canvas.getLocationOnScreen(); } catch (IllegalComponentStateException ex) {} |