RFR: 8217472: Add attenuation for PointLight [v5]
Nir Lisker
nlisker at openjdk.java.net
Fri Sep 4 14:37:04 UTC 2020
On Wed, 2 Sep 2020 17:16:00 GMT, Kevin Rushforth <kcr at openjdk.org> wrote:
>> I wrote the following test:
>>
>> import static org.junit.Assert.assertTrue;
>> import static org.junit.Assert.fail;
>>
>> import java.util.concurrent.CountDownLatch;
>> import java.util.concurrent.TimeUnit;
>>
>> import org.junit.AfterClass;
>> import org.junit.BeforeClass;
>> import org.junit.Test;
>>
>> import javafx.application.Application;
>> import javafx.application.Platform;
>> import javafx.scene.Group;
>> import javafx.scene.PointLight;
>> import javafx.scene.Scene;
>> import javafx.scene.paint.Color;
>> import javafx.scene.shape.Box;
>> import javafx.stage.Stage;
>> import javafx.stage.WindowEvent;
>>
>> public class PointLightAttenuationTest {
>>
>> private static CountDownLatch startupLatch;
>> private static Stage stage;
>> private static PointLight light = new PointLight(Color.BLUE);
>> private static Box box = new Box(100, 100, 1);
>>
>> @BeforeClass
>> public static void initFX() throws Exception {
>> startupLatch = new CountDownLatch(1);
>> new Thread(() -> Application.launch(TestApp.class, (String[])null)).start();
>> assertTrue("Timeout waiting for FX runtime to start", startupLatch.await(15, TimeUnit.SECONDS));
>> }
>>
>> public class TestApp extends Application {
>>
>> @Override
>> public void start(Stage mainStage) {
>> stage = mainStage;
>> light.setTranslateZ(-50);
>> var root = new Group(light, box);
>> var scene = new Scene(root);
>> stage.setScene(scene);
>> stage.setFullScreen(true);
>> stage.addEventHandler(WindowEvent.WINDOW_SHOWN, e -> Platform.runLater(startupLatch::countDown));
>> stage.show();
>> }
>> }
>>
>> @Test
>> public void testAttenuation() {
>> var image = box.snapshot(null, null);
>> var nonAttenColor = image.getPixelReader().getColor(1, 1);
>>
>> light.setLinearAttenuation(2);
>> image = box.snapshot(null, null);
>> var attenColor = image.getPixelReader().getColor(1, 1);
>>
>> System.out.println(nonAttenColor);
>> System.out.println(attenColor);
>> if (nonAttenColor.getBlue() > attenColor.getBlue()) {
>> throw new AssertionError("Attenuation color should be less than non-attenuated");
>> }
>> }
>>
>> @AfterClass
>> public static void teardown() {
>> Platform.runLater(() -> {
>> stage.hide();
>> Platform.exit();
>> });
>> }
>> }
>> But when executing it with
>>
>> ./gradlew -PFULL_TEST=true -PUSE_ROBOT=true :systemTests:test --tests PointLightAttenuationTest
>>
>> I get the error
>>
>> test.javafx.scene.lighting3D.PointLightAttenuationTest > classMethod FAILED
>> java.lang.AssertionError: Timeout waiting for FX runtime to start
>> at org.junit.Assert.fail(Assert.java:91)
>> at org.junit.Assert.assertTrue(Assert.java:43)
>> at test.javafx.scene.lighting3D.PointLightAttenuationTest.initFX(PointLightAttenuationTest.java:59)
>>
>> So for some reason the Application doesn't start, it seems. I ran `ShapeViewOrderLeakTest` and `RestoreSceneSizeTest`
>> which look the same, and those work. Any idea?
>
> 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.
-------------
PR: https://git.openjdk.java.net/jfx/pull/43
More information about the openjfx-dev
mailing list