changeset 5879:268fe91a74e0

RT-32880: D3D: Near clip appears to clip further (away from viewer) than the specified near value Summary: Adjust projection matrix for Direct3D Reviewed-by: ckyang, kcr
author vadim
date Tue, 03 Dec 2013 12:24:50 +0400
parents 76c09d14cfbd
children 5da49a57a37f
files apps/toys/FX8-3DFeatures/src/fx83dfeatures/NearAndFarClipTest.java modules/graphics/src/main/java/com/sun/prism/d3d/D3DContext.java tests/system/src/test/java/test3d/NearAndFarClipTest.java
diffstat 3 files changed, 30 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/apps/toys/FX8-3DFeatures/src/fx83dfeatures/NearAndFarClipTest.java	Mon Dec 02 21:25:39 2013 -0800
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/NearAndFarClipTest.java	Tue Dec 03 12:24:50 2013 +0400
@@ -29,7 +29,9 @@
 import javafx.scene.Group;
 import javafx.scene.PerspectiveCamera;
 import javafx.scene.Scene;
+import javafx.scene.control.Slider;
 import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
@@ -72,9 +74,9 @@
         insideNearClip.setTranslateZ(nearClipDistance + nearClipDistanceOffset);
         insideNearClip.setId("Blue");
 
-        Rectangle outsideNearClip = new Rectangle(16, 16, Color.YELLOW);
-        outsideNearClip.setLayoutX(242);
-        outsideNearClip.setLayoutY(242);
+        Rectangle outsideNearClip = new Rectangle(8, 8, Color.YELLOW);
+        outsideNearClip.setLayoutX(246);
+        outsideNearClip.setLayoutY(246);
         outsideNearClip.setTranslateZ(nearClipDistance - nearClipDistanceOffset);
         outsideNearClip.setId("Yellow");
 
@@ -94,6 +96,9 @@
 
         // Render in painter order (far to near)
         root.getChildren().addAll(outsideFarClip, insideFarClip, insideRect, insideNearClip, outsideNearClip);
+        Slider near = new Slider(NEAR*0.9, NEAR*1.1, NEAR);
+        Slider far = new Slider(FAR*0.9, FAR*1.1, FAR);
+        root.getChildren().addAll(new VBox(near, far));
 
         // Intentionally set depth buffer to false to reduce test complexity
         Scene scene = new Scene(root, WIDTH, HEIGHT, false);
@@ -106,8 +111,8 @@
 
         PerspectiveCamera camera = new PerspectiveCamera();
         camera.setFieldOfView(FOV);
-        camera.setNearClip(NEAR);
-        camera.setFarClip(FAR);
+        camera.nearClipProperty().bind(near.valueProperty());
+        camera.farClipProperty().bind(far.valueProperty());
         scene.setCamera(camera);
         return scene;
     }
@@ -120,7 +125,7 @@
         stage.setResizable(false);
         stage.show();
         System.out.println("You should expect to see 3 overlapping squares in"
-                + " the order of Blue is on top of Green and Green is on top Red.");;
+                + " the order of Blue is on top of Green and Green is on top Red.");
     }
 
     public static void main(String[] args) {
--- a/modules/graphics/src/main/java/com/sun/prism/d3d/D3DContext.java	Mon Dec 02 21:25:39 2013 -0800
+++ b/modules/graphics/src/main/java/com/sun/prism/d3d/D3DContext.java	Tue Dec 03 12:24:50 2013 +0400
@@ -78,6 +78,7 @@
     // Temp. variables (Not Thread Safe)
     private static GeneralTransform3D tempTx = new GeneralTransform3D();
     private static Vec3d tempVec3d = new Vec3d();
+    private static double[] tempAdjustClipSpaceMat = new double[16];
 
     private State state;
     private boolean isLost = false;
@@ -170,12 +171,10 @@
         return hr == D3D_OK;
     }
 
-
     /**
      * Validates result of present operation,
      * sets the context lost status if necessary
      */
-
     boolean validatePresent(int res) {
         if (res == D3DERR_DEVICELOST || res == D3DERR_DEVICENOTRESET) {
             setLost();
@@ -186,6 +185,20 @@
         return res == D3D_OK;
     }
 
+    /**
+     * OpenGL projection transform use z-range of [-1, 1] while D3D expects it
+     * to be [0, 1], so we need to adjust the matrix, see RT-32880.
+     */
+    private GeneralTransform3D adjustClipSpace(GeneralTransform3D projViewTx) {
+        double[] m = projViewTx.get(tempAdjustClipSpaceMat);
+        m[8] = (m[8] + m[12])/2;
+        m[9] = (m[9] + m[13])/2;
+        m[10] = (m[10] + m[14])/2;
+        m[11] = (m[11] + m[15])/2; 
+        projViewTx.set(m);
+        return projViewTx;
+    }
+
     @Override
     protected State updateRenderTarget(RenderTarget target, NGCamera camera,
                                        boolean depthTest)  {
@@ -209,7 +222,7 @@
         }
 
         // Set projection view matrix
-        tempTx = camera.getProjViewTx(tempTx);
+        tempTx = adjustClipSpace(camera.getProjViewTx(tempTx));
         res = nSetProjViewMatrix(pContext, depthTest,
             tempTx.get(0),  tempTx.get(1),  tempTx.get(2),  tempTx.get(3),
             tempTx.get(4),  tempTx.get(5),  tempTx.get(6),  tempTx.get(7),
--- a/tests/system/src/test/java/test3d/NearAndFarClipTest.java	Mon Dec 02 21:25:39 2013 -0800
+++ b/tests/system/src/test/java/test3d/NearAndFarClipTest.java	Tue Dec 03 12:24:50 2013 +0400
@@ -130,11 +130,9 @@
                 }
 
                 Color color;
-                // Enable Near Clip test once RT-32880 is fixed.
-                // D3D: Near clip appears to clip further (away from viewer) than the specified near value 
-//                // Verify Near Clip
-//                Color color = getColor(testScene, WIDTH / 2, HEIGHT / 2);
-//                assertColorEquals(Color.BLUE, color, TOLERANCE);
+                // Verify Near Clip
+                color = getColor(testScene, WIDTH / 2, HEIGHT / 2);
+                assertColorEquals(Color.BLUE, color, TOLERANCE);
 
                 // Verify Inside Rect
                 color = getColor(testScene, (WIDTH / 3), HEIGHT / 2);