Skip to content

Commit 069d4e7

Browse files
authored
Merge pull request #2443 from richardTingle/#2442-automate-TestInstanceNodeWithPbr
#2442 Automate test TestInstanceNodeWithPbr
2 parents 0925f98 + dcf1b3b commit 069d4e7

File tree

4 files changed

+135
-3
lines changed

4 files changed

+135
-3
lines changed

jme3-screenshot-tests/src/main/java/org/jmonkeyengine/screenshottests/testframework/TestDriver.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
*/
7373
public class TestDriver extends BaseAppState{
7474

75-
public static final String IMAGES_ARE_DIFFERENT = "Images are different.";
75+
public static final String IMAGES_ARE_DIFFERENT = "Images are different. (If you are running the test locally this is expected, images only reproducible on github CI infrastructure)";
7676

7777
public static final String IMAGES_ARE_DIFFERENT_SIZES = "Images are different sizes.";
7878

@@ -197,7 +197,7 @@ private Integer extractNumber(Path path){
197197
});
198198

199199
if(imageFiles.isEmpty()){
200-
fail("No screenshot found in the temporary directory.");
200+
fail("No screenshot found in the temporary directory. Did the application crash?");
201201
}
202202
if(imageFiles.size() != framesToTakeScreenshotsOn.size()){
203203
fail("Not all screenshots were taken, expected " + framesToTakeScreenshotsOn.size() + " but got " + imageFiles.size());
@@ -218,7 +218,7 @@ private Integer extractNumber(Path path){
218218
try{
219219
Path savedImage = saveGeneratedImageToChangedImages(generatedImage, thisFrameBaseImageFileName);
220220
attachImage("New image:", thisFrameBaseImageFileName + ".png", savedImage);
221-
String message = "Expected image not found, is this a new test? If so collect the new image from the step artefacts";
221+
String message = "Expected image not found, is this a new test? If so collect the new image from the step artefacts (on github). If running locally you can see them at build/changed-images but those should not be committed";
222222
if(failureMessage==null){ //only want the first thing to go wrong as the junit test fail reason
223223
failureMessage = message;
224224
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Copyright (c) 2024 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* * Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package org.jmonkeyengine.screenshottests.scene.instancing;
33+
34+
import com.jme3.app.Application;
35+
import com.jme3.app.SimpleApplication;
36+
import com.jme3.app.state.BaseAppState;
37+
import com.jme3.font.BitmapText;
38+
import com.jme3.light.DirectionalLight;
39+
import com.jme3.material.Material;
40+
import com.jme3.math.ColorRGBA;
41+
import com.jme3.math.Vector3f;
42+
import com.jme3.scene.Geometry;
43+
import com.jme3.scene.instancing.InstancedNode;
44+
import com.jme3.scene.shape.Box;
45+
import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase;
46+
import org.junit.jupiter.api.Test;
47+
48+
import java.util.Locale;
49+
50+
/**
51+
* This test specifically validates the corrected PBR rendering when combined
52+
* with instancing, as addressed in issue #2435.
53+
*
54+
* <p>
55+
* It creates an InstancedNode with a PBR-materialized Box to ensure the fix in
56+
* PBRLighting.vert correctly handles world position calculations for instanced geometry.
57+
* </p>
58+
*
59+
* @author Ryan McDonough - original test
60+
* @author Richard Tingle (aka richtea) - screenshot test adaptation
61+
*/
62+
public class TestInstanceNodeWithPbr extends ScreenshotTestBase {
63+
64+
@Test
65+
public void testInstanceNodeWithPbr() {
66+
screenshotTest(
67+
new BaseAppState() {
68+
private Geometry box;
69+
private float pos = -5;
70+
private float vel = 50;
71+
private BitmapText bmp;
72+
73+
@Override
74+
protected void initialize(Application app) {
75+
SimpleApplication simpleApp = (SimpleApplication) app;
76+
77+
app.getCamera().setLocation(Vector3f.UNIT_XYZ.mult(12));
78+
app.getCamera().lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
79+
80+
bmp = new BitmapText(app.getAssetManager().loadFont("Interface/Fonts/Default.fnt"));
81+
bmp.setText("<placeholder>");
82+
bmp.setLocalTranslation(10, app.getContext().getSettings().getHeight() - 20, 0);
83+
bmp.setColor(ColorRGBA.Red);
84+
simpleApp.getGuiNode().attachChild(bmp);
85+
86+
InstancedNode instancedNode = new InstancedNode("InstancedNode");
87+
simpleApp.getRootNode().attachChild(instancedNode);
88+
89+
Box mesh = new Box(0.5f, 0.5f, 0.5f);
90+
box = new Geometry("Box", mesh);
91+
Material pbrMaterial = createPbrMaterial(app, ColorRGBA.Red);
92+
box.setMaterial(pbrMaterial);
93+
94+
instancedNode.attachChild(box);
95+
instancedNode.instance();
96+
97+
DirectionalLight light = new DirectionalLight();
98+
light.setDirection(new Vector3f(-1, -2, -3).normalizeLocal());
99+
simpleApp.getRootNode().addLight(light);
100+
}
101+
102+
private Material createPbrMaterial(Application app, ColorRGBA color) {
103+
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/PBRLighting.j3md");
104+
mat.setColor("BaseColor", color);
105+
mat.setFloat("Roughness", 0.8f);
106+
mat.setFloat("Metallic", 0.1f);
107+
mat.setBoolean("UseInstancing", true);
108+
return mat;
109+
}
110+
111+
@Override
112+
public void update(float tpf) {
113+
pos += tpf * vel;
114+
box.setLocalTranslation(pos, 0f, 0f);
115+
116+
bmp.setText(String.format(Locale.ENGLISH, "BoxPosition: (%.2f, %.1f, %.1f)", pos, 0f, 0f));
117+
}
118+
119+
@Override
120+
protected void cleanup(Application app) {}
121+
122+
@Override
123+
protected void onEnable() {}
124+
125+
@Override
126+
protected void onDisable() { }
127+
}
128+
)
129+
.setFramesToTakeScreenshotsOn(1, 10)
130+
.run();
131+
}
132+
}
Loading
Loading

0 commit comments

Comments
 (0)