1 /*
   2  * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.robot.test3d;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Collection;
  30 import java.util.concurrent.atomic.AtomicBoolean;
  31 import javafx.application.ConditionalFeature;
  32 import javafx.application.Platform;
  33 import javafx.scene.AmbientLight;
  34 import javafx.scene.Group;
  35 import javafx.scene.PerspectiveCamera;
  36 import javafx.scene.PointLight;
  37 import javafx.scene.Scene;
  38 import javafx.scene.image.WritableImage;
  39 import javafx.scene.paint.Color;
  40 import javafx.scene.paint.PhongMaterial;
  41 import javafx.scene.shape.Box;
  42 import javafx.scene.shape.Shape3D;
  43 import javafx.scene.shape.Sphere;
  44 import javafx.stage.Stage;
  45 import org.junit.Test;
  46 import org.junit.runner.RunWith;
  47 import org.junit.runners.Parameterized;
  48 import test.robot.testharness.VisualTestBase;
  49 
  50 /**
  51  * 3D Snapshot validation tests.
  52  */
  53 @RunWith(Parameterized.class)
  54 public class Snapshot3DTest extends VisualTestBase {
  55 
  56     private static Collection params = null;
  57 
  58     private static final Object[] pUseSphere = { Boolean.FALSE, Boolean.TRUE };
  59     private static final Object[] pNumLights = { 0, 1, 2, 3 };
  60 
  61     @Parameterized.Parameters
  62     public static Collection getParams() {
  63         if (params == null) {
  64             params = new ArrayList();
  65             for (Object o0 : pUseSphere) {
  66                 for (Object o1 : pNumLights) {
  67                     params.add(new Object[] { o0, o1 });
  68                 }
  69             }
  70         }
  71         return params;
  72     }
  73 
  74     private static final double TOLERANCE = 0.07;
  75     private static final int WIDTH = 400;
  76     private static final int HEIGHT = 400;
  77     private static final int SAMPLE_X1 = 100;
  78     private static final int SAMPLE_Y1 = 100;
  79     private static final int SAMPLE_X2 = 200;
  80     private static final int SAMPLE_Y2 = 200;
  81     private static final int SAMPLE_X3 = 300;
  82     private static final int SAMPLE_Y3 = 300;
  83     private static final Color bgColor = Color.rgb(10, 10, 40);
  84 
  85     private Stage testStage;
  86     private Scene testScene;
  87     private WritableImage wImage;
  88 
  89     private boolean createSphere;
  90     private int numLights;
  91 
  92     public Snapshot3DTest(boolean createSphere, int numLights) {
  93         this.createSphere = createSphere;
  94         this.numLights = numLights;
  95     }
  96 
  97     private Scene buildScene() {
  98         Group root = new Group();
  99 
 100         PhongMaterial material = new PhongMaterial();
 101         material.setDiffuseColor(Color.WHITE);
 102         material.setSpecularColor(null);
 103         Shape3D shape;
 104         if (createSphere) {
 105             shape = new Sphere(200);
 106         } else {
 107             shape = new Box(300, 300, 300);
 108         }
 109         shape.setTranslateX(200);
 110         shape.setTranslateY(200);
 111         shape.setTranslateZ(10);
 112         shape.setMaterial(material);
 113         root.getChildren().add(shape);
 114 
 115         if (numLights >= 1) {
 116             AmbientLight ambLight = new AmbientLight(Color.LIMEGREEN);
 117             root.getChildren().add(ambLight);
 118         }
 119 
 120         if (numLights >= 2) {
 121             PointLight pointLight = new PointLight(Color.RED);
 122             pointLight.setTranslateX(75);
 123             pointLight.setTranslateY(-50);
 124             pointLight.setTranslateZ(-200);
 125             root.getChildren().add(pointLight);
 126         }
 127 
 128         if (numLights >= 3) {
 129             PointLight pointLight = new PointLight(Color.BLUE);
 130             pointLight.setTranslateX(225);
 131             pointLight.setTranslateY(50);
 132             pointLight.setTranslateZ(-300);
 133             root.getChildren().add(pointLight);
 134         }
 135 
 136         PerspectiveCamera camera = new PerspectiveCamera();
 137 
 138         Scene scene = new Scene(root, WIDTH, HEIGHT, false);
 139         scene.setFill(bgColor);
 140         scene.setCamera(camera);
 141 
 142         return scene;
 143     }
 144 
 145     private void compareColors(Scene scene, WritableImage wImage, int x, int y) {
 146         Color exColor = getColor(scene, x, y);
 147         Color sColor = wImage.getPixelReader().getColor(x, y);
 148         assertColorEquals(exColor, sColor, TOLERANCE);
 149     }
 150 
 151     // -------------------------------------------------------------
 152     // Tests
 153     // -------------------------------------------------------------
 154 
 155     @Test(timeout=5000)
 156     public void testSnapshot3D() {
 157         final AtomicBoolean scene3dSupported = new AtomicBoolean();
 158         runAndWait(() -> scene3dSupported.set(Platform.isSupported(ConditionalFeature.SCENE3D)));
 159         if (!scene3dSupported.get()) {
 160             System.out.println("*************************************************************");
 161             System.out.println("*      Platform isn't SCENE3D capable, skipping 3D test.    *");
 162             System.out.println("*************************************************************");
 163             return;
 164         }
 165 
 166         runAndWait(() -> {
 167             testStage = getStage();
 168             testStage.setTitle("Snapshot 3D Test");
 169 
 170             testScene = buildScene();
 171 
 172             // Take snapshot
 173             wImage = testScene.snapshot(null);
 174 
 175             testStage.setScene(testScene);
 176             testStage.show();
 177         });
 178         waitFirstFrame();
 179         runAndWait(() -> {
 180             // Compare the colors in the snapshot image with those rendered to the scene
 181             compareColors(testScene, wImage, SAMPLE_X1, SAMPLE_Y1);
 182             compareColors(testScene, wImage, SAMPLE_X2, SAMPLE_Y2);
 183             compareColors(testScene, wImage, SAMPLE_X3, SAMPLE_Y3);
 184         });
 185     }
 186 
 187 }