/* * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. */ package fx3d; import java.nio.ByteBuffer; import javafx.application.Application; import javafx.scene.AmbientLight; import javafx.scene.Group; import javafx.scene.LightBase; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.PerspectiveCamera; import javafx.scene.PointLight; import javafx.scene.Scene; import javafx.scene.SubScene; import javafx.scene.image.PixelFormat; import javafx.scene.image.WritableImage; import javafx.scene.layout.GridPane; import javafx.scene.paint.Color; import javafx.scene.paint.PhongMaterial; import javafx.scene.shape.Sphere; import javafx.stage.Stage; /** * * @author Andrew Glushchenko */ public class SubSceneLightScopingTestApp extends Application { private Node nodes[]; private VisibleLight lights[]; private Group roots[]; protected static int WIDTH = 600; protected static int HEIGHT = 600; public final static int SS_WIDTH = 300; public final static int SS_HEIGHT = 300; protected static int SCALE = 100; private static int scenesCount = 3; private Scene scene; private GridPane gridRoot; private SubScene[] scenes = new SubScene[scenesCount]; protected Scene createScene(Parent p, double width, double height) { return new Scene(p, width, height, true, false); } protected SubScene createSubScene(Parent p, double width, double height) { return new SubScene(p, width, height, true, false); } @Override public void start(Stage stage) throws Exception { initScene(); stage.setScene(scene); stage.show(); } protected void initScene() { nodes = new Node[3]; lights = new VisibleLight[3]; roots = new Group[3]; gridRoot = new GridPane(); for (int i = 0; i < scenesCount; i++) { scenes[i] = buildGroup(i); } gridRoot.add(scenes[0], 0, 0); gridRoot.add(scenes[1], 1, 0); gridRoot.add(scenes[2], 0, 1); scene = createScene(gridRoot, WIDTH, HEIGHT); setLight(0, Color.RED, LightType.Ambient); setLight(1, Color.GREEN, LightType.Ambient); setLight(2, Color.BLUE, LightType.Ambient); } private SubScene buildGroup(int num) { Sphere s = new Sphere(50); nodes[num] = s; Group grp = new Group(s); grp.setTranslateX(SS_WIDTH / 2); grp.setTranslateY(SS_HEIGHT / 2); roots[num] = grp; SubScene ss = createSubScene(grp, SS_WIDTH, SS_HEIGHT); ss.setCamera(new PerspectiveCamera()); return ss; } public VisibleLight getLight(int num) { return lights[num]; } public Node getNode(int num) { return nodes[num]; } public void setLight(int num, Color color, LightType lt) { if (lights[num] != null) { roots[num].getChildren().remove(lights[num]); } lights[num] = new VisibleLight(color, lt); lights[num].setTranslateX(SS_WIDTH / 4); lights[num].setTranslateY(SS_HEIGHT / 4); roots[num].getChildren().add(lights[num]); } public static void main(String[] args) { launch(args); } public enum LightType { Ambient, Point } private class VisibleLight extends Group { private PhongMaterial material; private LightBase lightBase; private LightType type; private void makeConstantImage(WritableImage img, Color color) { int w = (int) img.getWidth(); int h = (int) img.getHeight(); ByteBuffer scanline = ByteBuffer.allocate(3 * w); byte r = (byte) ((int) Math.round(color.getRed() * 255.0)); byte g = (byte) ((int) Math.round(color.getGreen() * 255.0)); byte b = (byte) ((int) Math.round(color.getBlue() * 255.0)); for (int i = 0; i < w; i++) { scanline.put(r); scanline.put(g); scanline.put(b); } scanline.rewind(); img.getPixelWriter().setPixels(0, 0, w, w, PixelFormat.getByteRgbInstance(), scanline, 0); } public VisibleLight(Color color) { this(color, LightType.Point); } public VisibleLight(Color color, LightType lt) { type = lt; if (lt.equals(LightType.Point)) { lightBase = new PointLight(); } else { lightBase = new AmbientLight(); } material = new PhongMaterial(); material.setDiffuseMap(null); material.setBumpMap(null); material.setSpecularMap(null); material.setSpecularColor(Color.TRANSPARENT); setColor(color); final Sphere light = new Sphere(50); light.setScaleX(0.2); light.setScaleY(0.2); light.setScaleZ(0.2); light.setMaterial(material); this.getChildren().addAll(lightBase, light); } public AmbientLight getAmbient() { if (type == LightType.Point) { return null; } return (AmbientLight) lightBase; } public PointLight getPoint() { if (type == LightType.Ambient) { return null; } return (PointLight) lightBase; } public LightBase getBase() { return lightBase; } public void setLightType(LightType lt) { this.getChildren().remove(lightBase); if (lt.equals(LightType.Point)) { lightBase = new PointLight(lightBase.getColor()); } else { lightBase = new AmbientLight(lightBase.getColor()); } this.getChildren().add(lightBase); } public final void setColor(Color color) { lightBase.setColor(color); WritableImage selfIllumMap = new WritableImage(64, 64); makeConstantImage(selfIllumMap, color); material.setSelfIlluminationMap(selfIllumMap); } } }