RFR: 8217472: Add attenuation for PointLight [v5]

Nir Lisker nlisker at openjdk.java.net
Fri Sep 4 23:23:03 UTC 2020


On Fri, 4 Sep 2020 14:34:40 GMT, Nir Lisker <nlisker at openjdk.org> wrote:

>> If you run it with `--info` you will see something like this:
>> 
>> test.javafx.scene.shape.PointLightAttenuationTest STANDARD_ERROR
>>     Exception in Application constructor
>>     Exception in thread "Thread-4" java.lang.RuntimeException: Unable to construct Application instance: class
>>     test.javafx.scene.shape.PointLightAttenuationTest$TestApp
>>         at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:890)
>>         at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
>>         at java.base/java.lang.Thread.run(Thread.java:832)
>>     Caused by: java.lang.NoSuchMethodException: test.javafx.scene.shape.PointLightAttenuationTest$TestApp.<init>()
>>         at java.base/java.lang.Class.getConstructor0(Class.java:3427)
>>         at java.base/java.lang.Class.getConstructor(Class.java:2165)
>>         at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:801)
>>         at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
>>         at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
>>         at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
>>         at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
>>         at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
>>         at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
>>         at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
>>         ... 1 more
>> 
>> The nested `TestApp` class should be declared as `static`. Btw, I don't recommend using `setFullScreen` for a test such
>> as this.
>
> Thanks, the test runs now, but I've run into an issue with `snapshot`.
> 
> `Node#snapshot` uses its scene parameters (like lights) to render the image, but if the node is in a subscene then the
> image will be wrong since it takes the wrong data. Bounds transforms like `sceneToLocal` and `localToScene` do take
> care of this case. I think that this is a mistake in `snapshot`, and maybe it should use the subscene, or a `boolean
> subScene` parameter should be offered, or `SnapshotParameters` should allow to specify it.

Looks like there's more to it. I've created the test code:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Slider;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.stage.Stage;

public class PointLightAttenuationTest extends Application {

    public static void main(String[] args) throws Exception {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        var light = new PointLight(Color.BLUE);
        light.setTranslateZ(-10);
        Box box = new Box(100, 100, 1);
        var group = new Group(light, box);

        var scene = new Scene(group, 500, 500, true);
        var camera = new PerspectiveCamera(true);
        camera.setTranslateZ(-300);
        camera.setFarClip(1000);
        scene.setCamera(camera);
        stage.setScene(scene);
        stage.show();

        var imageView = new ImageView();
        var snapshotButton = new Button("Node Snaphot");
        snapshotButton.setOnAction(e -> imageView.setImage(scene.snapshot(null)));

        var slider = new Slider(0, 0.2, 0);
        slider.setShowTickMarks(true);
        slider.setShowTickLabels(true);
        light.linearAttenuationProperty().bindBidirectional(slider.valueProperty());

        var snapshotStage = new Stage();
        snapshotStage.setScene(new Scene(new BorderPane(imageView, snapshotButton, null, slider, null)));
        snapshotStage.setWidth(600);
        snapshotStage.setHeight(600);
        snapshotStage.show();
    }
}
If the line `snapshotButton.setOnAction(e -> imageView.setImage(scene.snapshot(null)));`  is replaced to use
`box.snapshot(null, null)` then the snapshot is wrong.

-------------

PR: https://git.openjdk.java.net/jfx/pull/43


More information about the openjfx-dev mailing list