Reputation: 4803
In JavaFX is a default light on every 3D Scene. It's a PointLight shining from top of Scene.
I've tried to show in my program the different possibilities of light, but I ran in trouble. If I only add a SubScene with default, PointLight and AmbientLight, everything works as aspected. But if I then add one more SubScene with a combined Light of Ambient and Point, I'll get the result showing in Screenshot 2. It seems all other SubScene lost their light and fall back to it's default light. Maybe I hit a bug?
Here is a Minimal, Complete, and Verifiable example
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.*;
import javafx.stage.Stage;
public class Shapes3DViewer extends Application {
PhongMaterial material;
@Override
public void start(Stage stage) {
material = new PhongMaterial();
material.setDiffuseColor(Color.FIREBRICK);
material.setSpecularColor(Color.YELLOW);
PointLight pointLight = new PointLight(Color.WHITE);
pointLight.setTranslateX(100);
pointLight.setTranslateY(100);
pointLight.setTranslateZ(-300);
pointLight.setRotate(90);
AmbientLight ambient = new AmbientLight();
Group g1 = createSphereGroup(100, "Default light");
Group g2 = createSphereGroup(100, "Point light");
Group g3 = createSphereGroup(100, "Ambient light");
Group g4 = createSphereGroup(100, "Ambient & Point light");
g2.getChildren().add(pointLight);
g3.getChildren().add(ambient);
g4.getChildren().addAll(pointLight, ambient);
SubScene s1 = createSubScene(g1, 400, 400);
SubScene s2 = createSubScene(g2, 400, 400);
SubScene s3 = createSubScene(g3, 400, 400);
SubScene s4 = createSubScene(g4, 400, 400);
HBox root = new HBox();
root.getChildren().addAll(s1, s2, s3, s4);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
private Group createSphereGroup(double radius, String text) {
Sphere c = new Sphere(radius);
c.setMaterial(material);
c.setDrawMode(DrawMode.FILL);
c.setTranslateX(radius * 1.33);
c.setTranslateY(radius * 2);
Label lbl = new Label(text);
lbl.setStyle("-fx-text-fill: red;-fx-font-size: 18pt;");
return new Group(c, lbl);
}
private SubScene createSubScene(Group group, double width, double height) {
SubScene s = new SubScene(group, width, height);
s.setCamera(new PerspectiveCamera());
s.setFill(Color.color(.1, .1, .1));
return s;
}
}
Output of MCVE on:
javafx.runtime.version=8.0.45-b11
OS X 10.9.5
2014 Macbook Pro
Am I doing wrong, or is this a bug? Can someone confirm the same behaviour?
I've made a new test where I added two new lights: pointLight2 and ambient2. That both I've added to the fourth sphere. This solution works.
PointLight pointLight2 = new PointLight(Color.WHITE);
pointLight.setTranslateX(100);
pointLight.setTranslateY(100);
pointLight.setTranslateZ(-300);
pointLight.setRotate(90);
AmbientLight ambient2 = new AmbientLight();
g4.getChildren().addAll(pointLight2, ambient2);
It seems that the lights will be merged and only added to one Scene and removed from all other scenes.
As jewselsea explained in his answer, this is not a bug! But from my point of view they should repeat that statement in the Light Classes again or make a hint, because it's a little bit confusing.
SubScene needs a Parent as root in his constructor, so you don't have a choice.
Upvotes: 4
Views: 1945
Reputation: 159436
This is not a bug. A PointLight is a Node. Node javadoc states: "If a program adds a child node to a Parent (including Group, Region, etc) and that node is already a child of a different Parent or the root of a Scene, the node is automatically (and silently) removed from its former parent." So the application appears to be behaving as expected.
Upvotes: 3