无法将JavaFX灯添加到多个SubScenes

时间:2015-07-02 04:26:01

标签: javafx 3d javafx-8 javafx-3d

问题

在JavaFX中,每个3D场景都是默认灯光。它是一个从场景顶部闪耀的PointLight。

我试图在我的程序中展示光的不同可能性,但我遇到了麻烦。如果我只使用默认的PointLight和AmbientLight添加SubScene,那么一切都按预期工作。但是,如果我再添加一个具有环境光和点光的SubScene,我将在屏幕截图2中显示结果。似乎所有其他SubScene都失去了它们的光并且回到了它的默认光。也许我遇到了一个错误?

系统测试

  • 操作系统:Windows 8.1 x64,Windows 7 x64
  • 图形:AMD 4200 HD,Intel HD 3000
  • Java:1.8.0_45 JDK / JRE x86(32位),1.8.0_60ea x64

具有3个子场的阶段 - 默认,点,环境

3Lights

具有4个子场景的舞台 - 默认,点,环境,(点,环境)

4Lights

实施例

这是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;
  }
}

MCVE输出:

javafx.runtime.version=8.0.45-b11
OS X 10.9.5
2014 Macbook Pro

mac test

问题

我做错了,还是这个错误?有人可以确认相同的行为吗?

更新

我做了一个新测试,我添加了两个新灯:pointLight2和ambient2。 我已经加入了第四个领域。这个解决方案有效。

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);

4Lights-new

似乎灯光将被合并,只会添加到一个场景中,并从所有其他场景中删除。

结论

正如jewselsea在答案中解释的那样,不是错误!但是从我的观点来看,他们应该再次在Light Classes中重复这个陈述,或者做一个提示,因为它有点令人困惑。

SubScene需要在他的构造函数中以Parent为根,因此您无法做出选择。

1 个答案:

答案 0 :(得分:3)

这不是错误。 PointLightNode。节点javadoc声明:“如果程序将子节点添加到父节点(包括组,区域等),并且该节点已经是不同父节点的子节点或场景的根节点,则会自动(并静默)删除该节点来自它的前任父母。“因此应用程序似乎表现得如预期。