diff --git a/jme3-screenshot-tests/src/main/java/org/jmonkeyengine/screenshottests/testframework/ScreenshotTest.java b/jme3-screenshot-tests/src/main/java/org/jmonkeyengine/screenshottests/testframework/ScreenshotTest.java index f207e73d27..f566aff13c 100644 --- a/jme3-screenshot-tests/src/main/java/org/jmonkeyengine/screenshottests/testframework/ScreenshotTest.java +++ b/jme3-screenshot-tests/src/main/java/org/jmonkeyengine/screenshottests/testframework/ScreenshotTest.java @@ -102,6 +102,7 @@ public ScreenshotTest setBaseImageFileName(String baseImageFileName){ public void run(){ AppSettings settings = new AppSettings(true); + settings.setRenderer(AppSettings.LWJGL_OPENGL32); settings.setResolution(resolution.getWidth(), resolution.getHeight()); settings.setAudioRenderer(null); // Disable audio (for headless) settings.setUseInput(false); //while it will run with inputs on it causes non-fatal errors. diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/animation/TestIssue2076.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/animation/TestIssue2076.java deleted file mode 100644 index 50435b1218..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/animation/TestIssue2076.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.animation; - -import com.jme3.anim.SkinningControl; -import com.jme3.anim.util.AnimMigrationUtils; -import com.jme3.animation.SkeletonControl; -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.light.AmbientLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Node; -import com.jme3.scene.VertexBuffer; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.Test; - -/** - * Screenshot test for JMonkeyEngine issue #2076: software skinning requires vertex - * normals. - * - *

If the issue is resolved, 2 copies of the Jaime model will be rendered in the screenshot. - * - *

If the issue is present, then the application will immediately crash, - * typically with a {@code NullPointerException}. - * - * @author Stephen Gold (original test) - * @author Richard Tingle (screenshot test adaptation) - */ -public class TestIssue2076 extends ScreenshotTestBase { - - /** - * This test creates a scene with two Jaime models, one using the old animation system - * and one using the new animation system, both with software skinning and no vertex normals. - */ - @Test - public void testIssue2076() { - screenshotTest(new BaseAppState() { - @Override - protected void initialize(Application app) { - SimpleApplication simpleApplication = (SimpleApplication) app; - Node rootNode = simpleApplication.getRootNode(); - AssetManager assetManager = simpleApplication.getAssetManager(); - - // Add ambient light - AmbientLight ambientLight = new AmbientLight(); - ambientLight.setColor(new ColorRGBA(1f, 1f, 1f, 1f)); - rootNode.addLight(ambientLight); - - /* - * The original Jaime model was chosen for testing because it includes - * tangent buffers (needed to trigger issue #2076) and uses the old - * animation system (so it can be easily used to test both systems). - */ - String assetPath = "Models/Jaime/Jaime.j3o"; - - // Test old animation system - Node oldJaime = (Node) assetManager.loadModel(assetPath); - rootNode.attachChild(oldJaime); - oldJaime.setLocalTranslation(-1f, 0f, 0f); - - // Enable software skinning - SkeletonControl skeletonControl = oldJaime.getControl(SkeletonControl.class); - skeletonControl.setHardwareSkinningPreferred(false); - - // Remove its vertex normals - Geometry oldGeometry = (Geometry) oldJaime.getChild(0); - Mesh oldMesh = oldGeometry.getMesh(); - oldMesh.clearBuffer(VertexBuffer.Type.Normal); - oldMesh.clearBuffer(VertexBuffer.Type.BindPoseNormal); - - // Test new animation system - Node newJaime = (Node) assetManager.loadModel(assetPath); - AnimMigrationUtils.migrate(newJaime); - rootNode.attachChild(newJaime); - newJaime.setLocalTranslation(1f, 0f, 0f); - - // Enable software skinning - SkinningControl skinningControl = newJaime.getControl(SkinningControl.class); - skinningControl.setHardwareSkinningPreferred(false); - - // Remove its vertex normals - Geometry newGeometry = (Geometry) newJaime.getChild(0); - Mesh newMesh = newGeometry.getMesh(); - newMesh.clearBuffer(VertexBuffer.Type.Normal); - newMesh.clearBuffer(VertexBuffer.Type.BindPoseNormal); - - // Position the camera to see both models - simpleApplication.getCamera().setLocation(new Vector3f(0f, 0f, 5f)); - } - - @Override - protected void cleanup(Application app) { - } - - @Override - protected void onEnable() { - } - - @Override - protected void onDisable() { - } - - @Override - public void update(float tpf) { - super.update(tpf); - } - }).run(); - } -} \ No newline at end of file diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/animation/TestMotionPath.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/animation/TestMotionPath.java deleted file mode 100644 index 28a5e042d2..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/animation/TestMotionPath.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.animation; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.cinematic.MotionPath; -import com.jme3.cinematic.MotionPathListener; -import com.jme3.cinematic.events.MotionEvent; -import com.jme3.font.BitmapText; -import com.jme3.input.ChaseCamera; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Box; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.Test; - -/** - * Screenshot test for the MotionPath functionality. - * - *

This test creates a teapot model that follows a predefined path with several waypoints. - * The animation is automatically started and screenshots are taken at frames 10 and 60 - * to capture the teapot at different positions along the path. - * - * @author Richard Tingle (screenshot test adaptation) - */ -public class TestMotionPath extends ScreenshotTestBase { - - /** - * This test creates a scene with a teapot following a motion path. - */ - @Test - public void testMotionPath() { - screenshotTest(new BaseAppState() { - private Spatial teapot; - private MotionPath path; - private MotionEvent motionControl; - private BitmapText wayPointsText; - - @Override - protected void initialize(Application app) { - SimpleApplication simpleApplication = (SimpleApplication) app; - Node rootNode = simpleApplication.getRootNode(); - Node guiNode = simpleApplication.getGuiNode(); - AssetManager assetManager = simpleApplication.getAssetManager(); - - // Set camera position - app.getCamera().setLocation(new Vector3f(8.4399185f, 11.189463f, 14.267577f)); - - // Create the scene - createScene(rootNode, assetManager); - - // Create the motion path - path = new MotionPath(); - path.addWayPoint(new Vector3f(10, 3, 0)); - path.addWayPoint(new Vector3f(10, 3, 10)); - path.addWayPoint(new Vector3f(-40, 3, 10)); - path.addWayPoint(new Vector3f(-40, 3, 0)); - path.addWayPoint(new Vector3f(-40, 8, 0)); - path.addWayPoint(new Vector3f(10, 8, 0)); - path.addWayPoint(new Vector3f(10, 8, 10)); - path.addWayPoint(new Vector3f(15, 8, 10)); - path.enableDebugShape(assetManager, rootNode); - - // Create the motion event - motionControl = new MotionEvent(teapot, path); - motionControl.setDirectionType(MotionEvent.Direction.PathAndRotation); - motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y)); - motionControl.setInitialDuration(10f); - motionControl.setSpeed(2f); - - // Create text for waypoint notifications - wayPointsText = new BitmapText(assetManager.loadFont("Interface/Fonts/Default.fnt")); - wayPointsText.setSize(wayPointsText.getFont().getCharSet().getRenderedSize()); - guiNode.attachChild(wayPointsText); - - // Add listener for waypoint events - path.addListener(new MotionPathListener() { - @Override - public void onWayPointReach(MotionEvent control, int wayPointIndex) { - if (path.getNbWayPoints() == wayPointIndex + 1) { - wayPointsText.setText(control.getSpatial().getName() + " Finished!!! "); - } else { - wayPointsText.setText(control.getSpatial().getName() + " Reached way point " + wayPointIndex); - } - wayPointsText.setLocalTranslation( - (app.getCamera().getWidth() - wayPointsText.getLineWidth()) / 2, - app.getCamera().getHeight(), - 0); - } - }); - - // note that the ChaseCamera is self-initialising, so just creating this object attaches it - new ChaseCamera(getApplication().getCamera(), teapot); - - // Start the animation automatically - motionControl.play(); - } - - private void createScene(Node rootNode, AssetManager assetManager) { - // Create materials - Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - mat.setFloat("Shininess", 1f); - mat.setBoolean("UseMaterialColors", true); - mat.setColor("Ambient", ColorRGBA.Black); - mat.setColor("Diffuse", ColorRGBA.DarkGray); - mat.setColor("Specular", ColorRGBA.White.mult(0.6f)); - - Material matSoil = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); - matSoil.setBoolean("UseMaterialColors", true); - matSoil.setColor("Ambient", ColorRGBA.Black); - matSoil.setColor("Diffuse", ColorRGBA.Black); - matSoil.setColor("Specular", ColorRGBA.Black); - - // Create teapot - teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); - teapot.setName("Teapot"); - teapot.setLocalScale(3); - teapot.setMaterial(mat); - rootNode.attachChild(teapot); - - // Create ground - Geometry soil = new Geometry("soil", new Box(50, 1, 50)); - soil.setLocalTranslation(0, -1, 0); - soil.setMaterial(matSoil); - rootNode.attachChild(soil); - - // Add light - DirectionalLight light = new DirectionalLight(); - light.setDirection(new Vector3f(0, -1, 0).normalizeLocal()); - light.setColor(ColorRGBA.White.mult(1.5f)); - rootNode.addLight(light); - } - - @Override - protected void cleanup(Application app) { - } - - @Override - protected void onEnable() { - } - - @Override - protected void onDisable() { - } - }) - .setFramesToTakeScreenshotsOn(10, 60) - .run(); - } -} \ No newline at end of file diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/effects/TestIssue1773.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/effects/TestIssue1773.java deleted file mode 100644 index 05eb097ee7..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/effects/TestIssue1773.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.effects; - -import com.jme3.animation.LoopMode; -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.cinematic.MotionPath; -import com.jme3.cinematic.events.MotionEvent; -import com.jme3.effect.ParticleEmitter; -import com.jme3.effect.ParticleMesh; -import com.jme3.effect.shapes.EmitterMeshVertexShape; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.material.Materials; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.BloomFilter; -import com.jme3.post.filters.FXAAFilter; -import com.jme3.renderer.Camera; -import com.jme3.renderer.ViewPort; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.CenterQuad; -import com.jme3.scene.shape.Torus; -import com.jme3.shadow.DirectionalLightShadowFilter; -import com.jme3.texture.Texture; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.TestInfo; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import java.util.Arrays; - -/** - * @author Richard Tingle (aka richtea) - */ -public class TestIssue1773 extends ScreenshotTestBase{ - - /** - * Test case for Issue 1773 (Wrong particle position when using - * 'EmitterMeshVertexShape' or 'EmitterMeshFaceShape' and worldSpace - * flag equal to true) - * - * If the test succeeds, the particles will be generated from the vertices - * (for EmitterMeshVertexShape) or from the faces (for EmitterMeshFaceShape) - * of the torus mesh. If the test fails, the particles will appear in the - * center of the torus when worldSpace flag is set to true. - * - */ - @ParameterizedTest(name = "Test Issue 1773 (emit in worldSpace = {0})") - @ValueSource(booleans = {true, false}) - public void testIssue1773(boolean worldSpace, TestInfo testInfo){ - - String imageName = testInfo.getTestClass().get().getName() + "." + testInfo.getTestMethod().get().getName() + (worldSpace ? "_worldSpace" : "_localSpace"); - - screenshotTest(new BaseAppState(){ - private ParticleEmitter emit; - private Node myModel; - - AssetManager assetManager; - - Node rootNode; - - Camera cam; - - ViewPort viewPort; - - @Override - public void initialize(Application app) { - assetManager = app.getAssetManager(); - rootNode = ((SimpleApplication)app).getRootNode(); - cam = app.getCamera(); - viewPort = app.getViewPort(); - configCamera(); - setupLights(); - setupGround(); - setupCircle(); - createMotionControl(); - } - - @Override - protected void cleanup(Application app){} - - @Override - protected void onEnable(){} - - @Override - protected void onDisable(){} - - /** - * Crates particle emitter and adds it to root node. - */ - private void setupCircle() { - myModel = new Node("FieryCircle"); - - Geometry torus = createTorus(1f); - myModel.attachChild(torus); - - emit = createParticleEmitter(torus, true); - myModel.attachChild(emit); - - rootNode.attachChild(myModel); - } - - /** - * Creates torus geometry used for the emitter shape. - */ - private Geometry createTorus(float radius) { - float s = radius / 8f; - Geometry geo = new Geometry("CircleXZ", new Torus(64, 4, s, radius)); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", ColorRGBA.Blue); - mat.getAdditionalRenderState().setWireframe(true); - geo.setMaterial(mat); - return geo; - } - - /** - * Creates a particle emitter that will emit the particles from - * the given shape's vertices. - */ - private ParticleEmitter createParticleEmitter(Geometry geo, boolean pointSprite) { - ParticleMesh.Type type = pointSprite ? ParticleMesh.Type.Point : ParticleMesh.Type.Triangle; - ParticleEmitter emitter = new ParticleEmitter("Emitter", type, 1000); - Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); - mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); - mat.setBoolean("PointSprite", pointSprite); - emitter.setMaterial(mat); - emitter.setLowLife(1); - emitter.setHighLife(1); - emitter.setImagesX(15); - emitter.setStartSize(0.04f); - emitter.setEndSize(0.02f); - emitter.setStartColor(ColorRGBA.Orange); - emitter.setEndColor(ColorRGBA.Red); - emitter.setParticlesPerSec(900); - emitter.setGravity(0, 0f, 0); - //emitter.getParticleInfluencer().setVelocityVariation(1); - //emitter.getParticleInfluencer().setInitialVelocity(new Vector3f(0, .5f, 0)); - emitter.setShape(new EmitterMeshVertexShape(Arrays.asList(geo.getMesh()))); - emitter.setInWorldSpace(worldSpace); - //emitter.setShape(new EmitterMeshFaceShape(Arrays.asList(geo.getMesh()))); - return emitter; - } - - /** - * Creates a motion control that will move particle emitter in - * a circular path. - */ - private void createMotionControl() { - - float radius = 5f; - float height = 1.10f; - - MotionPath path = new MotionPath(); - path.setCycle(true); - - for (int i = 0; i < 8; i++) { - float x = FastMath.sin(FastMath.QUARTER_PI * i) * radius; - float z = FastMath.cos(FastMath.QUARTER_PI * i) * radius; - path.addWayPoint(new Vector3f(x, height, z)); - } - MotionEvent motionControl = new MotionEvent(myModel, path); - motionControl.setLoopMode(LoopMode.Loop); - motionControl.setDirectionType(MotionEvent.Direction.Path); - motionControl.play(); - } - - private void configCamera() { - cam.setLocation(new Vector3f(0, 6f, 9.2f)); - cam.lookAt(Vector3f.UNIT_Y, Vector3f.UNIT_Y); - - float aspect = (float) cam.getWidth() / cam.getHeight(); - cam.setFrustumPerspective(45, aspect, 0.1f, 1000f); - } - - /** - * Adds a ground to the scene - */ - private void setupGround() { - CenterQuad quad = new CenterQuad(12, 12); - quad.scaleTextureCoordinates(new Vector2f(2, 2)); - Geometry floor = new Geometry("Floor", quad); - Material mat = new Material(assetManager, Materials.LIGHTING); - Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); - tex.setWrap(Texture.WrapMode.Repeat); - mat.setTexture("DiffuseMap", tex); - floor.setMaterial(mat); - floor.rotate(-FastMath.HALF_PI, 0, 0); - rootNode.attachChild(floor); - } - - /** - * Adds lights and filters - */ - private void setupLights() { - viewPort.setBackgroundColor(ColorRGBA.DarkGray); - rootNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive); - - AmbientLight ambient = new AmbientLight(); - ambient.setColor(ColorRGBA.White); - //rootNode.addLight(ambient); - - DirectionalLight sun = new DirectionalLight(); - sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal()); - sun.setColor(ColorRGBA.White); - rootNode.addLight(sun); - - DirectionalLightShadowFilter dlsf = new DirectionalLightShadowFilter(assetManager, 4096, 3); - dlsf.setLight(sun); - dlsf.setShadowIntensity(0.4f); - dlsf.setShadowZExtend(256); - - FXAAFilter fxaa = new FXAAFilter(); - BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - fpp.addFilter(bloom); - fpp.addFilter(dlsf); - fpp.addFilter(fxaa); - viewPort.addProcessor(fpp); - } - - - }).setFramesToTakeScreenshotsOn(45) - .setBaseImageFileName(imageName) - .run(); - } -} diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/export/TestOgreConvert.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/export/TestOgreConvert.java deleted file mode 100644 index f076902f2d..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/export/TestOgreConvert.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.export; - -import com.jme3.anim.AnimComposer; -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.export.binary.BinaryExporter; -import com.jme3.export.binary.BinaryImporter; -import com.jme3.light.DirectionalLight; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -/** - * @author Richard Tingle (aka richtea) - */ -public class TestOgreConvert extends ScreenshotTestBase{ - - /** - * This tests loads an Ogre model, converts it to binary, and then reloads it. - *

- * Note that the model is animated and the animation is played back. That is why - * two screenshots are taken - *

- */ - @Test - public void testOgreConvert(){ - - screenshotTest( - new BaseAppState(){ - @Override - protected void initialize(Application app){ - AssetManager assetManager = app.getAssetManager(); - Node rootNode = ((SimpleApplication)app).getRootNode(); - Camera cam = app.getCamera(); - Spatial ogreModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); - - DirectionalLight dl = new DirectionalLight(); - dl.setColor(ColorRGBA.White); - dl.setDirection(new Vector3f(0,-1,-1).normalizeLocal()); - rootNode.addLight(dl); - - cam.setLocation(new Vector3f(0, 0, 15)); - - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryExporter exp = new BinaryExporter(); - exp.save(ogreModel, baos); - - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - BinaryImporter imp = new BinaryImporter(); - imp.setAssetManager(assetManager); - Node ogreModelReloaded = (Node) imp.load(bais, null, null); - - AnimComposer composer = ogreModelReloaded.getControl(AnimComposer.class); - composer.setCurrentAction("Walk"); - - rootNode.attachChild(ogreModelReloaded); - } catch (IOException ex){ - throw new RuntimeException(ex); - } - } - - @Override - protected void cleanup(Application app){} - - @Override - protected void onEnable(){} - - @Override - protected void onDisable(){} - } - ) - .setFramesToTakeScreenshotsOn(1, 5) - .run(); - - } -} diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/gui/TestBitmapText3D.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/gui/TestBitmapText3D.java deleted file mode 100644 index b68e4589df..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/gui/TestBitmapText3D.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.gui; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.font.BitmapFont; -import com.jme3.font.BitmapText; -import com.jme3.font.Rectangle; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.shape.Quad; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.Test; - -/** - * @author Richard Tingle (aka richtea) - */ -public class TestBitmapText3D extends ScreenshotTestBase{ - - /** - * This tests both that bitmap text is rendered correctly and that it is - * wrapped correctly. - */ - @Test - public void testBitmapText3D(){ - - screenshotTest( - new BaseAppState(){ - @Override - protected void initialize(Application app){ - String txtB = "ABCDEFGHIKLMNOPQRSTUVWXYZ1234567890`~!@#$%^&*()-=_+[]\\;',./{}|:<>?"; - - AssetManager assetManager = app.getAssetManager(); - Node rootNode = ((SimpleApplication)app).getRootNode(); - - Quad q = new Quad(6, 3); - Geometry g = new Geometry("quad", q); - g.setLocalTranslation(-1.5f, -3, -0.0001f); - g.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - rootNode.attachChild(g); - - BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt"); - BitmapText txt = new BitmapText(fnt); - txt.setBox(new Rectangle(0, 0, 6, 3)); - txt.setQueueBucket(RenderQueue.Bucket.Transparent); - txt.setSize( 0.5f ); - txt.setText(txtB); - txt.setLocalTranslation(-1.5f,0,0); - rootNode.attachChild(txt); - } - - @Override - protected void cleanup(Application app){} - - @Override - protected void onEnable(){} - - @Override - protected void onDisable(){} - } - ).run(); - - - } -} diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/light/pbr/TestPBRLighting.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/light/pbr/TestPBRLighting.java deleted file mode 100644 index 0cbd19da24..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/light/pbr/TestPBRLighting.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.light.pbr; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.environment.EnvironmentCamera; -import com.jme3.environment.FastLightProbeFactory; -import com.jme3.light.DirectionalLight; -import com.jme3.light.LightProbe; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.ToneMapFilter; -import com.jme3.renderer.Camera; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.texture.plugins.ktx.KTXLoader; -import com.jme3.util.SkyFactory; -import com.jme3.util.mikktspace.MikktspaceTangentGenerator; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.TestInfo; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -/** - * Screenshot tests for PBR lighting. - * - * @author nehon - original test - * @author Richard Tingle (aka richtea) - screenshot test adaptation - * - */ -public class TestPBRLighting extends ScreenshotTestBase { - - private static Stream testParameters() { - return Stream.of( - Arguments.of("LowRoughness", 0.1f, false), - Arguments.of("HighRoughness", 1.0f, false), - Arguments.of("DefaultDirectionalLight", 0.5f, false), - Arguments.of("UpdatedDirectionalLight", 0.5f, true) - ); - } - - /** - * Test PBR lighting with different parameters - * - * @param testName The name of the test (used for screenshot filename) - * @param roughness The roughness value to use - * @param updateLight Whether to update the directional light to match camera direction - */ - @ParameterizedTest(name = "{0}") - @MethodSource("testParameters") - public void testPBRLighting(String testName, float roughness, boolean updateLight, TestInfo testInfo) { - - if(!testInfo.getTestClass().isPresent() || !testInfo.getTestMethod().isPresent()) { - throw new RuntimeException("Test preconditions not met"); - } - - String imageName = testInfo.getTestClass().get().getName() + "." + testInfo.getTestMethod().get().getName() + "_" + testName; - - screenshotTest(new BaseAppState() { - private static final int RESOLUTION = 256; - - private Node modelNode; - private int frame = 0; - - @Override - protected void initialize(Application app) { - Camera cam = app.getCamera(); - cam.setLocation(new Vector3f(18, 10, 0)); - cam.lookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y); - - AssetManager assetManager = app.getAssetManager(); - assetManager.registerLoader(KTXLoader.class, "ktx"); - - app.getViewPort().setBackgroundColor(ColorRGBA.White); - - modelNode = new Node("modelNode"); - Geometry model = (Geometry) assetManager.loadModel("Models/Tank/tank.j3o"); - MikktspaceTangentGenerator.generate(model); - modelNode.attachChild(model); - - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); - SimpleApplication simpleApp = (SimpleApplication) app; - simpleApp.getRootNode().addLight(dl); - dl.setColor(ColorRGBA.White); - - // If we need to update the light direction to match camera - if (updateLight) { - dl.setDirection(app.getCamera().getDirection().normalize()); - } - - simpleApp.getRootNode().attachChild(modelNode); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - int numSamples = app.getContext().getSettings().getSamples(); - if (numSamples > 0) { - fpp.setNumSamples(numSamples); - } - - fpp.addFilter(new ToneMapFilter(Vector3f.UNIT_XYZ.mult(4.0f))); - app.getViewPort().addProcessor(fpp); - - Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap); - simpleApp.getRootNode().attachChild(sky); - - Material pbrMat = assetManager.loadMaterial("Models/Tank/tank.j3m"); - pbrMat.setFloat("Roughness", roughness); - model.setMaterial(pbrMat); - - // Set up environment camera - EnvironmentCamera envCam = new EnvironmentCamera(RESOLUTION, new Vector3f(0, 3f, 0)); - app.getStateManager().attach(envCam); - } - - @Override - protected void cleanup(Application app) {} - - @Override - protected void onEnable() {} - - @Override - protected void onDisable() {} - - @Override - public void update(float tpf) { - frame++; - - if (frame == 2) { - modelNode.removeFromParent(); - LightProbe probe; - - SimpleApplication simpleApp = (SimpleApplication) getApplication(); - probe = FastLightProbeFactory.makeProbe(simpleApp.getRenderManager(), - simpleApp.getAssetManager(), - RESOLUTION, - Vector3f.ZERO, - 1f, - 1000f, - simpleApp.getRootNode()); - - probe.getArea().setRadius(100); - simpleApp.getRootNode().addLight(probe); - } - - if (frame > 10 && modelNode.getParent() == null) { - SimpleApplication simpleApp = (SimpleApplication) getApplication(); - simpleApp.getRootNode().attachChild(modelNode); - } - } - }).setBaseImageFileName(imageName) - .setFramesToTakeScreenshotsOn(12) - .run(); - } -} diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/light/pbr/TestPBRSimple.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/light/pbr/TestPBRSimple.java deleted file mode 100644 index 70220f7eef..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/light/pbr/TestPBRSimple.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.light.pbr; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.environment.EnvironmentProbeControl; -import com.jme3.material.Material; -import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; -import com.jme3.scene.Geometry; -import com.jme3.scene.Spatial; -import com.jme3.util.SkyFactory; -import com.jme3.util.mikktspace.MikktspaceTangentGenerator; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.TestInfo; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -/** - * A simpler PBR example that uses EnvironmentProbeControl to bake the environment - * - * @author Richard Tingle (aka richtea) - screenshot test adaptation - */ -public class TestPBRSimple extends ScreenshotTestBase { - - private static Stream testParameters() { - return Stream.of( - Arguments.of("WithRealtimeBaking", true), - Arguments.of("WithoutRealtimeBaking", false) - ); - } - - /** - * Test PBR simple with different parameters - * - * @param testName The name of the test (used for screenshot filename) - * @param realtimeBaking Whether to use realtime baking - */ - @ParameterizedTest(name = "{0}") - @MethodSource("testParameters") - public void testPBRSimple(String testName, boolean realtimeBaking, TestInfo testInfo) { - if(!testInfo.getTestClass().isPresent() || !testInfo.getTestMethod().isPresent()) { - throw new RuntimeException("Test preconditions not met"); - } - - String imageName = testInfo.getTestClass().get().getName() + "." + testInfo.getTestMethod().get().getName() + "_" + testName; - - screenshotTest(new BaseAppState() { - private int frame = 0; - - @Override - protected void initialize(Application app) { - Camera cam = app.getCamera(); - cam.setLocation(new Vector3f(18, 10, 0)); - cam.lookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y); - - AssetManager assetManager = app.getAssetManager(); - SimpleApplication simpleApp = (SimpleApplication) app; - - // Create the tank model - Geometry model = (Geometry) assetManager.loadModel("Models/Tank/tank.j3o"); - MikktspaceTangentGenerator.generate(model); - - Material pbrMat = assetManager.loadMaterial("Models/Tank/tank.j3m"); - model.setMaterial(pbrMat); - simpleApp.getRootNode().attachChild(model); - - // Create sky - Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap); - simpleApp.getRootNode().attachChild(sky); - - // Create baker control - EnvironmentProbeControl envProbe = new EnvironmentProbeControl(assetManager, 256); - simpleApp.getRootNode().addControl(envProbe); - - // Tag the sky, only the tagged spatials will be rendered in the env map - envProbe.tag(sky); - } - - @Override - protected void cleanup(Application app) {} - - @Override - protected void onEnable() {} - - @Override - protected void onDisable() {} - - @Override - public void update(float tpf) { - if (realtimeBaking) { - frame++; - if (frame == 2) { - SimpleApplication simpleApp = (SimpleApplication) getApplication(); - simpleApp.getRootNode().getControl(EnvironmentProbeControl.class).rebake(); - } - } - } - }).setBaseImageFileName(imageName) - .setFramesToTakeScreenshotsOn(10) - .run(); - } -} \ No newline at end of file diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/material/TestSimpleBumps.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/material/TestSimpleBumps.java deleted file mode 100644 index 0e4e53df54..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/material/TestSimpleBumps.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.material; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.light.PointLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.shape.Quad; -import com.jme3.scene.shape.Sphere; -import com.jme3.util.mikktspace.MikktspaceTangentGenerator; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.Test; - -/** - * Screenshot test for the SimpleBumps material test. - * - *

This test creates a quad with a bump map material and a point light that orbits around it. - * The light's position is represented by a small red sphere. Screenshots are taken at frames 10 and 60 - * to capture the light at different positions in its orbit. - * - * @author Richard Tingle (screenshot test adaptation) - */ -public class TestSimpleBumps extends ScreenshotTestBase { - - /** - * This test creates a scene with a bump-mapped quad and an orbiting light. - */ - @Test - public void testSimpleBumps() { - screenshotTest(new BaseAppState() { - private float angle; - private PointLight pl; - private Spatial lightMdl; - - @Override - protected void initialize(Application app) { - SimpleApplication simpleApplication = (SimpleApplication) app; - Node rootNode = simpleApplication.getRootNode(); - AssetManager assetManager = simpleApplication.getAssetManager(); - - // Create quad with bump map material - Quad quadMesh = new Quad(1, 1); - Geometry sphere = new Geometry("Rock Ball", quadMesh); - Material mat = assetManager.loadMaterial("Textures/BumpMapTest/SimpleBump.j3m"); - sphere.setMaterial(mat); - MikktspaceTangentGenerator.generate(sphere); - rootNode.attachChild(sphere); - - // Create light representation - lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f)); - lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m")); - rootNode.attachChild(lightMdl); - - // Create point light - pl = new PointLight(); - pl.setColor(ColorRGBA.White); - pl.setPosition(new Vector3f(0f, 0f, 4f)); - rootNode.addLight(pl); - } - - @Override - protected void cleanup(Application app) { - } - - @Override - protected void onEnable() { - } - - @Override - protected void onDisable() { - } - - @Override - public void update(float tpf) { - super.update(tpf); - - angle += tpf * 2f; - angle %= FastMath.TWO_PI; - - pl.setPosition(new Vector3f(FastMath.cos(angle) * 4f, 0.5f, FastMath.sin(angle) * 4f)); - lightMdl.setLocalTranslation(pl.getPosition()); - } - }) - .setFramesToTakeScreenshotsOn(10, 60) - .run(); - } -} \ No newline at end of file diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/model/shape/TestBillboard.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/model/shape/TestBillboard.java deleted file mode 100644 index 096662503b..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/model/shape/TestBillboard.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2025 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.model.shape; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Node; -import com.jme3.scene.control.BillboardControl; -import com.jme3.scene.debug.Arrow; -import com.jme3.scene.debug.Grid; -import com.jme3.scene.shape.Quad; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.TestInfo; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -/** - * Screenshot test for the Billboard test. - * - *

This test creates three different billboard alignments (Screen, Camera, AxialY) - * with different colored quads. Each billboard is positioned at a different x-coordinate - * and has a blue Z-axis arrow attached to it. Screenshots are taken from three different angles: - * front, above, and right. - * - * @author Richard Tingle (screenshot test adaptation) - */ -@SuppressWarnings("OptionalGetWithoutIsPresent") -public class TestBillboard extends ScreenshotTestBase { - - private static Stream testParameters() { - return Stream.of( - Arguments.of("fromFront", new Vector3f(0, 1, 15)), - Arguments.of("fromAbove", new Vector3f(0, 15, 6)), - Arguments.of("fromRight", new Vector3f(-15, 10, 5)) - ); - } - - /** - * A billboard test with the specified camera parameters. - * - * @param cameraPosition The position of the camera - */ - @ParameterizedTest(name = "{0}") - @MethodSource("testParameters") - public void testBillboard(String testName, Vector3f cameraPosition, TestInfo testInfo) { - String imageName = testInfo.getTestClass().get().getName() + "." + testInfo.getTestMethod().get().getName() + "_" + testName; - - screenshotTest(new BaseAppState() { - @Override - protected void initialize(Application app) { - SimpleApplication simpleApplication = (SimpleApplication) app; - Node rootNode = simpleApplication.getRootNode(); - - // Set up the camera - simpleApplication.getCamera().setLocation(cameraPosition); - simpleApplication.getCamera().lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - - // Set background color - simpleApplication.getViewPort().setBackgroundColor(ColorRGBA.DarkGray); - - // Create grid - Geometry grid = makeShape(simpleApplication, "DebugGrid", new Grid(21, 21, 2), ColorRGBA.Gray); - grid.center().move(0, 0, 0); - rootNode.attachChild(grid); - - // Create billboards with different alignments - Node node = createBillboard(simpleApplication, BillboardControl.Alignment.Screen, ColorRGBA.Red); - node.setLocalTranslation(-6f, 0, 0); - rootNode.attachChild(node); - - node = createBillboard(simpleApplication, BillboardControl.Alignment.Camera, ColorRGBA.Green); - node.setLocalTranslation(-2f, 0, 0); - rootNode.attachChild(node); - - node = createBillboard(simpleApplication, BillboardControl.Alignment.AxialY, ColorRGBA.Blue); - node.setLocalTranslation(2f, 0, 0); - rootNode.attachChild(node); - } - - @Override - protected void cleanup(Application app) {} - - @Override - protected void onEnable() {} - - @Override - protected void onDisable() {} - - private Node createBillboard(SimpleApplication app, BillboardControl.Alignment alignment, ColorRGBA color) { - Node node = new Node("Parent"); - Quad quad = new Quad(2, 2); - Geometry g = makeShape(app, alignment.name(), quad, color); - BillboardControl bc = new BillboardControl(); - bc.setAlignment(alignment); - g.addControl(bc); - node.attachChild(g); - node.attachChild(makeShape(app, "ZAxis", new Arrow(Vector3f.UNIT_Z), ColorRGBA.Blue)); - return node; - } - - private Geometry makeShape(SimpleApplication app, String name, Mesh shape, ColorRGBA color) { - Geometry geo = new Geometry(name, shape); - Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); - mat.setColor("Color", color); - geo.setMaterial(mat); - return geo; - } - }) - .setBaseImageFileName(imageName) - .setFramesToTakeScreenshotsOn(1) - .run(); - } -} diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/post/TestCartoonEdge.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/post/TestCartoonEdge.java deleted file mode 100644 index 3f40859c18..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/post/TestCartoonEdge.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2025 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.post; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.FastMath; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.CartoonEdgeFilter; -import com.jme3.renderer.Caps; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.Spatial.CullHint; -import com.jme3.texture.Texture; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.Test; - -/** - * Screenshot test for the CartoonEdge filter. - * - *

This test creates a scene with a monkey head model that has a cartoon/cel-shaded effect - * applied to it. The CartoonEdgeFilter is used to create yellow outlines around the edges - * of the model, and a toon shader is applied to the model's material to create the cel-shaded look. - * - * @author Richard Tingle (screenshot test adaptation) - */ -public class TestCartoonEdge extends ScreenshotTestBase { - - /** - * This test creates a scene with a cartoon-shaded monkey head model. - */ - @Test - public void testCartoonEdge() { - screenshotTest(new BaseAppState() { - @Override - protected void initialize(Application app) { - SimpleApplication simpleApplication = (SimpleApplication) app; - Node rootNode = simpleApplication.getRootNode(); - - simpleApplication.getViewPort().setBackgroundColor(ColorRGBA.Gray); - - simpleApplication.getCamera().setLocation(new Vector3f(-1, 2, -5)); - simpleApplication.getCamera().lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - simpleApplication.getCamera().setFrustumFar(300); - - rootNode.setCullHint(CullHint.Never); - - setupLighting(rootNode); - - setupModel(simpleApplication, rootNode); - - setupFilters(simpleApplication); - } - - private void setupFilters(SimpleApplication app) { - if (app.getRenderer().getCaps().contains(Caps.GLSL100)) { - FilterPostProcessor fpp = new FilterPostProcessor(app.getAssetManager()); - - CartoonEdgeFilter toon = new CartoonEdgeFilter(); - toon.setEdgeColor(ColorRGBA.Yellow); - fpp.addFilter(toon); - app.getViewPort().addProcessor(fpp); - } - } - - private void setupLighting(Node rootNode) { - DirectionalLight dl = new DirectionalLight(); - dl.setDirection(new Vector3f(-1, -1, 1).normalizeLocal()); - dl.setColor(new ColorRGBA(2, 2, 2, 1)); - rootNode.addLight(dl); - } - - private void setupModel(SimpleApplication app, Node rootNode) { - Spatial model = app.getAssetManager().loadModel("Models/MonkeyHead/MonkeyHead.mesh.xml"); - makeToonish(app, model); - model.rotate(0, FastMath.PI, 0); - rootNode.attachChild(model); - } - - private void makeToonish(SimpleApplication app, Spatial spatial) { - if (spatial instanceof Node) { - Node n = (Node) spatial; - for (Spatial child : n.getChildren()) { - makeToonish(app, child); - } - } else if (spatial instanceof Geometry) { - Geometry g = (Geometry) spatial; - Material m = g.getMaterial(); - if (m.getMaterialDef().getMaterialParam("UseMaterialColors") != null) { - Texture t = app.getAssetManager().loadTexture("Textures/ColorRamp/toon.png"); - m.setTexture("ColorRamp", t); - m.setBoolean("UseMaterialColors", true); - m.setColor("Specular", ColorRGBA.Black); - m.setColor("Diffuse", ColorRGBA.White); - m.setBoolean("VertexLighting", true); - } - } - } - - @Override - protected void cleanup(Application app) { - } - - @Override - protected void onEnable() { - } - - @Override - protected void onDisable() { - } - }) - .setFramesToTakeScreenshotsOn(1) - .run(); - } -} \ No newline at end of file diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/post/TestFog.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/post/TestFog.java deleted file mode 100644 index d92b9af020..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/post/TestFog.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2025 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.post; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.FogFilter; -import com.jme3.renderer.queue.RenderQueue; -import com.jme3.scene.Node; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.util.SkyFactory; -import org.jmonkeyengine.screenshottests.testframework.Scenario; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.Test; - -/** - * Screenshot test for the Fog filter. - * - *

This test creates a scene with a terrain and sky, with a fog effect applied. - * The fog is a light gray color and has a specific density and distance setting. - * - * @author Richard Tingle (screenshot test adaptation) - */ -public class TestFog extends ScreenshotTestBase { - - /** - * This test creates a scene with a fog effect. - */ - @Test - public void testFog() { - screenshotMultiScenarioTest(new Scenario("FullscreenQuad",new BaseAppState() { - @Override - protected void initialize(Application app) { - SimpleApplication simpleApplication = (SimpleApplication) app; - Node rootNode = simpleApplication.getRootNode(); - - simpleApplication.getCamera().setLocation(new Vector3f(-34.74095f, 95.21318f, -287.4945f)); - simpleApplication.getCamera().setRotation(new Quaternion(0.023536969f, 0.9361278f, -0.016098259f, -0.35050195f)); - - Node mainScene = new Node(); - - mainScene.attachChild(SkyFactory.createSky(simpleApplication.getAssetManager(), - "Textures/Sky/Bright/BrightSky.dds", - SkyFactory.EnvMapType.CubeMap)); - - createTerrain(mainScene, app.getAssetManager()); - - DirectionalLight sun = new DirectionalLight(); - Vector3f lightDir = new Vector3f(-0.37352666f, -0.50444174f, -0.7784704f); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(2)); - mainScene.addLight(sun); - - rootNode.attachChild(mainScene); - - FilterPostProcessor fpp = new FilterPostProcessor(simpleApplication.getAssetManager()); - - FogFilter fog = new FogFilter(); - fog.setFogColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.0f)); - fog.setFogDistance(155); - fog.setFogDensity(1.0f); - fpp.addFilter(fog); - simpleApplication.getViewPort().addProcessor(fpp); - } - - - private void createTerrain(Node rootNode, AssetManager assetManager) { - Material matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matRock.setBoolean("useTriPlanarMapping", false); - matRock.setBoolean("WardIso", true); - matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("DiffuseMap", grass); - matRock.setFloat("DiffuseMap_0_scale", 64); - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("DiffuseMap_1", dirt); - matRock.setFloat("DiffuseMap_1_scale", 16); - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("DiffuseMap_2", rock); - matRock.setFloat("DiffuseMap_2_scale", 128); - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(Texture.WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(Texture.WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("NormalMap", normalMap0); - matRock.setTexture("NormalMap_1", normalMap1); - matRock.setTexture("NormalMap_2", normalMap2); - - AbstractHeightMap heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); - heightmap.load(); - - TerrainQuad terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - - terrain.setMaterial(matRock); - terrain.setLocalScale(new Vector3f(5, 5, 5)); - terrain.setLocalTranslation(new Vector3f(0, -30, 0)); - terrain.setLocked(false); // unlock it so we can edit the height - - terrain.setShadowMode(RenderQueue.ShadowMode.Receive); - rootNode.attachChild(terrain); - - } - - - @Override - protected void cleanup(Application app) { - } - - @Override - protected void onEnable() { - } - - @Override - protected void onDisable() { - } - - @Override - public void update(float tpf) { - super.update(tpf); - System.out.println(getApplication().getCamera().getLocation()); - } - - }),new Scenario("FullscreenTriangle",new BaseAppState() { - @Override - protected void initialize(Application app) { - SimpleApplication simpleApplication = (SimpleApplication) app; - Node rootNode = simpleApplication.getRootNode(); - - simpleApplication.getCamera().setLocation(new Vector3f(-34.74095f, 95.21318f, -287.4945f)); - simpleApplication.getCamera().setRotation(new Quaternion(0.023536969f, 0.9361278f, -0.016098259f, -0.35050195f)); - - Node mainScene = new Node(); - - mainScene.attachChild(SkyFactory.createSky(simpleApplication.getAssetManager(), - "Textures/Sky/Bright/BrightSky.dds", - SkyFactory.EnvMapType.CubeMap)); - - createTerrain(mainScene, app.getAssetManager()); - - DirectionalLight sun = new DirectionalLight(); - Vector3f lightDir = new Vector3f(-0.37352666f, -0.50444174f, -0.7784704f); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(2)); - mainScene.addLight(sun); - - rootNode.attachChild(mainScene); - - FilterPostProcessor fpp = new FilterPostProcessor(simpleApplication.getAssetManager(),true); - - FogFilter fog = new FogFilter(); - fog.setFogColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.0f)); - fog.setFogDistance(155); - fog.setFogDensity(1.0f); - fpp.addFilter(fog); - simpleApplication.getViewPort().addProcessor(fpp); - } - - - private void createTerrain(Node rootNode, AssetManager assetManager) { - Material matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matRock.setBoolean("useTriPlanarMapping", false); - matRock.setBoolean("WardIso", true); - matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("DiffuseMap", grass); - matRock.setFloat("DiffuseMap_0_scale", 64); - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("DiffuseMap_1", dirt); - matRock.setFloat("DiffuseMap_1_scale", 16); - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("DiffuseMap_2", rock); - matRock.setFloat("DiffuseMap_2_scale", 128); - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(Texture.WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(Texture.WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(Texture.WrapMode.Repeat); - matRock.setTexture("NormalMap", normalMap0); - matRock.setTexture("NormalMap_1", normalMap1); - matRock.setTexture("NormalMap_2", normalMap2); - - AbstractHeightMap heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); - heightmap.load(); - - TerrainQuad terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - - terrain.setMaterial(matRock); - terrain.setLocalScale(new Vector3f(5, 5, 5)); - terrain.setLocalTranslation(new Vector3f(0, -30, 0)); - terrain.setLocked(false); // unlock it so we can edit the height - - terrain.setShadowMode(RenderQueue.ShadowMode.Receive); - rootNode.attachChild(terrain); - - } - - - @Override - protected void cleanup(Application app) { - } - - @Override - protected void onEnable() { - } - - @Override - protected void onDisable() { - } - - @Override - public void update(float tpf) { - super.update(tpf); - System.out.println(getApplication().getCamera().getLocation()); - } - - })) - .setFramesToTakeScreenshotsOn(1) - .run(); - } -} \ No newline at end of file diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/post/TestLightScattering.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/post/TestLightScattering.java deleted file mode 100644 index 5353226f90..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/post/TestLightScattering.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2025 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.post; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.LightScatteringFilter; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Geometry; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.util.SkyFactory; -import com.jme3.util.mikktspace.MikktspaceTangentGenerator; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.Test; - -/** - * Screenshot test for the LightScattering filter. - * - *

This test creates a scene with a terrain model and a sky, with a light scattering - * (god rays) effect applied. The effect simulates light rays scattering through the atmosphere - * from a bright light source (like the sun). - * - * @author Richard Tingle (screenshot test adaptation) - */ -public class TestLightScattering extends ScreenshotTestBase { - - /** - * This test creates a scene with a light scattering effect. - */ - @Test - public void testLightScattering() { - screenshotTest(new BaseAppState() { - @Override - protected void initialize(Application app) { - SimpleApplication simpleApplication = (SimpleApplication) app; - Node rootNode = simpleApplication.getRootNode(); - - simpleApplication.getCamera().setLocation(new Vector3f(55.35316f, -0.27061665f, 27.092093f)); - simpleApplication.getCamera().setRotation(new Quaternion(0.010414706f, 0.9874893f, 0.13880467f, -0.07409228f)); - - Material mat = simpleApplication.getAssetManager().loadMaterial("Textures/Terrain/Rocky/Rocky.j3m"); - Spatial scene = simpleApplication.getAssetManager().loadModel("Models/Terrain/Terrain.mesh.xml"); - MikktspaceTangentGenerator.generate(((Geometry) ((Node) scene).getChild(0)).getMesh()); - scene.setMaterial(mat); - scene.setShadowMode(ShadowMode.CastAndReceive); - scene.setLocalScale(400); - scene.setLocalTranslation(0, -10, -120); - rootNode.attachChild(scene); - - rootNode.attachChild(SkyFactory.createSky(simpleApplication.getAssetManager(), - "Textures/Sky/Bright/FullskiesBlueClear03.dds", - SkyFactory.EnvMapType.CubeMap)); - - DirectionalLight sun = new DirectionalLight(); - Vector3f lightDir = new Vector3f(-0.12f, -0.3729129f, 0.74847335f); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(2)); - scene.addLight(sun); - - FilterPostProcessor fpp = new FilterPostProcessor(simpleApplication.getAssetManager()); - - Vector3f lightPos = lightDir.normalize().negate().multLocal(3000); - LightScatteringFilter filter = new LightScatteringFilter(lightPos); - - filter.setLightDensity(1.0f); - filter.setBlurStart(0.02f); - filter.setBlurWidth(0.9f); - filter.setLightPosition(lightPos); - - fpp.addFilter(filter); - simpleApplication.getViewPort().addProcessor(fpp); - } - - @Override - protected void cleanup(Application app) { - } - - @Override - protected void onEnable() { - } - - @Override - protected void onDisable() { - } - }) - .setFramesToTakeScreenshotsOn(1) - .run(); - } -} \ No newline at end of file diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/scene/instancing/TestInstanceNodeWithPbr.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/scene/instancing/TestInstanceNodeWithPbr.java deleted file mode 100644 index 9069fb4464..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/scene/instancing/TestInstanceNodeWithPbr.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.scene.instancing; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.font.BitmapText; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.instancing.InstancedNode; -import com.jme3.scene.shape.Box; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.Test; - -import java.util.Locale; - -/** - * This test specifically validates the corrected PBR rendering when combined - * with instancing, as addressed in issue #2435. - * - *

- * It creates an InstancedNode with a PBR-materialized Box to ensure the fix in - * PBRLighting.vert correctly handles world position calculations for instanced geometry. - *

- * - * @author Ryan McDonough - original test - * @author Richard Tingle (aka richtea) - screenshot test adaptation - */ -public class TestInstanceNodeWithPbr extends ScreenshotTestBase { - - @Test - public void testInstanceNodeWithPbr() { - screenshotTest( - new BaseAppState() { - private Geometry box; - private float pos = -5; - private float vel = 50; - private BitmapText bmp; - - @Override - protected void initialize(Application app) { - SimpleApplication simpleApp = (SimpleApplication) app; - - app.getCamera().setLocation(Vector3f.UNIT_XYZ.mult(12)); - app.getCamera().lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - - bmp = new BitmapText(app.getAssetManager().loadFont("Interface/Fonts/Default.fnt")); - bmp.setText(""); - bmp.setLocalTranslation(10, app.getContext().getSettings().getHeight() - 20, 0); - bmp.setColor(ColorRGBA.Red); - simpleApp.getGuiNode().attachChild(bmp); - - InstancedNode instancedNode = new InstancedNode("InstancedNode"); - simpleApp.getRootNode().attachChild(instancedNode); - - Box mesh = new Box(0.5f, 0.5f, 0.5f); - box = new Geometry("Box", mesh); - Material pbrMaterial = createPbrMaterial(app, ColorRGBA.Red); - box.setMaterial(pbrMaterial); - - instancedNode.attachChild(box); - instancedNode.instance(); - - DirectionalLight light = new DirectionalLight(); - light.setDirection(new Vector3f(-1, -2, -3).normalizeLocal()); - simpleApp.getRootNode().addLight(light); - } - - private Material createPbrMaterial(Application app, ColorRGBA color) { - Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/PBRLighting.j3md"); - mat.setColor("BaseColor", color); - mat.setFloat("Roughness", 0.8f); - mat.setFloat("Metallic", 0.1f); - mat.setBoolean("UseInstancing", true); - return mat; - } - - @Override - public void update(float tpf) { - pos += tpf * vel; - box.setLocalTranslation(pos, 0f, 0f); - - bmp.setText(String.format(Locale.ENGLISH, "BoxPosition: (%.2f, %.1f, %.1f)", pos, 0f, 0f)); - } - - @Override - protected void cleanup(Application app) {} - - @Override - protected void onEnable() {} - - @Override - protected void onDisable() { } - } - ) - .setFramesToTakeScreenshotsOn(1, 10) - .run(); - } -} \ No newline at end of file diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/terrain/TestPBRTerrain.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/terrain/TestPBRTerrain.java deleted file mode 100644 index 37f8063300..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/terrain/TestPBRTerrain.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.terrain; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.asset.TextureKey; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.light.LightProbe; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.TestInfo; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -/** - * This test uses 'PBRTerrain.j3md' to create a terrain Material for PBR. - * - * Upon running the app, the user should see a mountainous, terrain-based - * landscape with some grassy areas, some snowy areas, and some tiled roads and - * gravel paths weaving between the valleys. Snow should be slightly - * shiny/reflective, and marble texture should be even shinier. If you would - * like to know what each texture is supposed to look like, you can find the - * textures used for this test case located in jme3-testdata. - * - * Uses assets from CC0Textures.com, licensed under CC0 1.0 Universal. For more - * information on the textures this test case uses, view the license.txt file - * located in the jme3-testdata directory where these textures are located: - * jme3-testdata/src/main/resources/Textures/Terrain/PBR - * - * @author yaRnMcDonuts (Original manual test) - * @author Richard Tingle (aka richtea) - screenshot test adaptation - */ -@SuppressWarnings("FieldCanBeLocal") -public class TestPBRTerrain extends ScreenshotTestBase { - - private static Stream testParameters() { - return Stream.of( - Arguments.of("FinalRender", 0), - Arguments.of("NormalMap", 1), - Arguments.of("RoughnessMap", 2), - Arguments.of("MetallicMap", 3), - Arguments.of("GeometryNormals", 8) - ); - } - - /** - * Test PBR terrain with different debug modes - * - * @param testName The name of the test (used for screenshot filename) - * @param debugMode The debug mode to use - */ - @ParameterizedTest(name = "{0}") - @MethodSource("testParameters") - public void testPBRTerrain(String testName, int debugMode, TestInfo testInfo) { - - if(!testInfo.getTestClass().isPresent() || !testInfo.getTestMethod().isPresent()) { - throw new RuntimeException("Test preconditions not met"); - } - - String imageName = testInfo.getTestClass().get().getName() + "." + testInfo.getTestMethod().get().getName() + "_" + testName; - - screenshotTest(new BaseAppState() { - private TerrainQuad terrain; - private Material matTerrain; - - private final int terrainSize = 512; - private final int patchSize = 256; - private final float dirtScale = 24; - private final float darkRockScale = 24; - private final float snowScale = 64; - private final float tileRoadScale = 64; - private final float grassScale = 24; - private final float marbleScale = 64; - private final float gravelScale = 64; - - @Override - protected void initialize(Application app) { - SimpleApplication simpleApp = (SimpleApplication) app; - AssetManager assetManager = app.getAssetManager(); - - setUpTerrain(simpleApp, assetManager); - setUpTerrainMaterial(assetManager); - setUpLights(simpleApp, assetManager); - setUpCamera(app); - - // Set debug mode - matTerrain.setInt("DebugValuesMode", debugMode); - } - - private void setUpTerrainMaterial(AssetManager assetManager) { - // PBR terrain matdef - matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/PBRTerrain.j3md"); - - matTerrain.setBoolean("useTriPlanarMapping", false); - - // ALPHA map (for splat textures) - matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alpha1.png")); - matTerrain.setTexture("AlphaMap_1", assetManager.loadTexture("Textures/Terrain/splat/alpha2.png")); - - // DIRT texture - Texture dirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); - dirt.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_0", dirt); - matTerrain.setFloat("AlbedoMap_0_scale", dirtScale); - matTerrain.setFloat("Roughness_0", 1); - matTerrain.setFloat("Metallic_0", 0); - - // DARK ROCK texture - Texture darkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Color.png"); - darkRock.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_1", darkRock); - matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale); - matTerrain.setFloat("Roughness_1", 0.92f); - matTerrain.setFloat("Metallic_1", 0.02f); - - // SNOW texture - Texture snow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Color.png"); - snow.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_2", snow); - matTerrain.setFloat("AlbedoMap_2_scale", snowScale); - matTerrain.setFloat("Roughness_2", 0.55f); - matTerrain.setFloat("Metallic_2", 0.12f); - - // TILES texture - Texture tiles = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Color.png"); - tiles.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_3", tiles); - matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale); - matTerrain.setFloat("Roughness_3", 0.87f); - matTerrain.setFloat("Metallic_3", 0.08f); - - // GRASS texture - Texture grass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); - grass.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_4", grass); - matTerrain.setFloat("AlbedoMap_4_scale", grassScale); - matTerrain.setFloat("Roughness_4", 1); - matTerrain.setFloat("Metallic_4", 0); - - // MARBLE texture - Texture marble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Color.png"); - marble.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_5", marble); - matTerrain.setFloat("AlbedoMap_5_scale", marbleScale); - matTerrain.setFloat("Roughness_5", 0.06f); - matTerrain.setFloat("Metallic_5", 0.8f); - - // Gravel texture - Texture gravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Color.png"); - gravel.setWrap(WrapMode.Repeat); - matTerrain.setTexture("AlbedoMap_6", gravel); - matTerrain.setFloat("AlbedoMap_6_scale", gravelScale); - matTerrain.setFloat("Roughness_6", 0.9f); - matTerrain.setFloat("Metallic_6", 0.07f); - - // NORMAL MAPS - Texture normalMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_1K_Normal.png"); - normalMapDirt.setWrap(WrapMode.Repeat); - - Texture normalMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Normal.png"); - normalMapDarkRock.setWrap(WrapMode.Repeat); - - Texture normalMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Normal.png"); - normalMapSnow.setWrap(WrapMode.Repeat); - - Texture normalMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Normal.png"); - normalMapGravel.setWrap(WrapMode.Repeat); - - Texture normalMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Normal.png"); - normalMapGrass.setWrap(WrapMode.Repeat); - - Texture normalMapTiles = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Normal.png"); - normalMapTiles.setWrap(WrapMode.Repeat); - - matTerrain.setTexture("NormalMap_0", normalMapDirt); - matTerrain.setTexture("NormalMap_1", normalMapDarkRock); - matTerrain.setTexture("NormalMap_2", normalMapSnow); - matTerrain.setTexture("NormalMap_3", normalMapTiles); - matTerrain.setTexture("NormalMap_4", normalMapGrass); - matTerrain.setTexture("NormalMap_6", normalMapGravel); - - terrain.setMaterial(matTerrain); - } - - private void setUpTerrain(SimpleApplication simpleApp, AssetManager assetManager) { - // HEIGHTMAP image (for the terrain heightmap) - TextureKey hmKey = new TextureKey("Textures/Terrain/splat/mountains512.png", false); - Texture heightMapImage = assetManager.loadTexture(hmKey); - - // CREATE HEIGHTMAP - AbstractHeightMap heightmap; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.3f); - heightmap.load(); - heightmap.smooth(0.9f, 1); - } catch (Exception e) { - throw new RuntimeException(e); - } - - terrain = new TerrainQuad("terrain", patchSize + 1, terrainSize + 1, heightmap.getHeightMap()); - TerrainLodControl control = new TerrainLodControl(terrain, getApplication().getCamera()); - control.setLodCalculator(new DistanceLodCalculator(patchSize + 1, 2.7f)); // patch size, and a multiplier - terrain.addControl(control); - terrain.setMaterial(matTerrain); - terrain.setLocalTranslation(0, -100, 0); - terrain.setLocalScale(1f, 1f, 1f); - simpleApp.getRootNode().attachChild(terrain); - } - - private void setUpLights(SimpleApplication simpleApp, AssetManager assetManager) { - LightProbe probe = (LightProbe) assetManager.loadAsset("Scenes/LightProbes/quarry_Probe.j3o"); - - probe.setAreaType(LightProbe.AreaType.Spherical); - probe.getArea().setRadius(2000); - probe.getArea().setCenter(new Vector3f(0, 0, 0)); - simpleApp.getRootNode().addLight(probe); - - DirectionalLight directionalLight = new DirectionalLight(); - directionalLight.setDirection((new Vector3f(-0.3f, -0.5f, -0.3f)).normalize()); - directionalLight.setColor(ColorRGBA.White); - simpleApp.getRootNode().addLight(directionalLight); - - AmbientLight ambientLight = new AmbientLight(); - ambientLight.setColor(ColorRGBA.White); - simpleApp.getRootNode().addLight(ambientLight); - } - - private void setUpCamera(Application app) { - app.getCamera().setLocation(new Vector3f(0, 10, -10)); - app.getCamera().lookAtDirection(new Vector3f(0, -1.5f, -1).normalizeLocal(), Vector3f.UNIT_Y); - } - - @Override - protected void cleanup(Application app) {} - - @Override - protected void onEnable() {} - - @Override - protected void onDisable() {} - - }).setBaseImageFileName(imageName) - .setFramesToTakeScreenshotsOn(5) - .run(); - } -} diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/terrain/TestPBRTerrainAdvanced.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/terrain/TestPBRTerrainAdvanced.java deleted file mode 100644 index a1f5830896..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/terrain/TestPBRTerrainAdvanced.java +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.terrain; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.asset.TextureKey; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.light.LightProbe; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Vector3f; -import com.jme3.shader.VarType; -import com.jme3.terrain.geomipmap.TerrainLodControl; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.texture.Texture.MagFilter; -import com.jme3.texture.Texture.MinFilter; -import com.jme3.texture.TextureArray; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.TestInfo; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Stream; - - -/** - * This test uses 'AdvancedPBRTerrain.j3md' to create a terrain Material with - * more textures than 'PBRTerrain.j3md' can handle. - * - * Upon running the app, the user should see a mountainous, terrain-based - * landscape with some grassy areas, some snowy areas, and some tiled roads and - * gravel paths weaving between the valleys. Snow should be slightly - * shiny/reflective, and marble texture should be even shinier. If you would - * like to know what each texture is supposed to look like, you can find the - * textures used for this test case located in jme3-testdata. - - * The MetallicRoughness map stores: - *
    - *
  • AmbientOcclusion in the Red channel
  • - *
  • Roughness in the Green channel
  • - *
  • Metallic in the Blue channel
  • - *
  • EmissiveIntensity in the Alpha channel
  • - *
- * - * The shaders are still subject to the GLSL max limit of 16 textures, however - * each TextureArray counts as a single texture, and each TextureArray can store - * multiple images. For more information on texture arrays see: - * https://www.khronos.org/opengl/wiki/Array_Texture - * - * Uses assets from CC0Textures.com, licensed under CC0 1.0 Universal. For more - * information on the textures this test case uses, view the license.txt file - * located in the jme3-testdata directory where these textures are located: - * jme3-testdata/src/main/resources/Textures/Terrain/PBR - * - * @author yaRnMcDonuts - original test - * @author Richard Tingle (aka richtea) - screenshot test adaptation - */ -@SuppressWarnings("FieldCanBeLocal") -public class TestPBRTerrainAdvanced extends ScreenshotTestBase { - - private static Stream testParameters() { - return Stream.of( - Arguments.of("FinalRender", 0), - Arguments.of("AmbientOcclusion", 4), - Arguments.of("Emissive", 5) - ); - } - - /** - * Test advanced PBR terrain with different debug modes - * - * @param testName The name of the test (used for screenshot filename) - * @param debugMode The debug mode to use - */ - @ParameterizedTest(name = "{0}") - @MethodSource("testParameters") - public void testPBRTerrainAdvanced(String testName, int debugMode, TestInfo testInfo) { - if(!testInfo.getTestClass().isPresent() || !testInfo.getTestMethod().isPresent()) { - throw new RuntimeException("Test preconditions not met"); - } - - String imageName = testInfo.getTestClass().get().getName() + "." + testInfo.getTestMethod().get().getName() + "_" + testName; - - screenshotTest(new BaseAppState() { - private TerrainQuad terrain; - private Material matTerrain; - - private final int terrainSize = 512; - private final int patchSize = 256; - private final float dirtScale = 24; - private final float darkRockScale = 24; - private final float snowScale = 64; - private final float tileRoadScale = 64; - private final float grassScale = 24; - private final float marbleScale = 64; - private final float gravelScale = 64; - - private final ColorRGBA tilesEmissiveColor = new ColorRGBA(0.12f, 0.02f, 0.23f, 0.85f); //dim magenta emission - private final ColorRGBA marbleEmissiveColor = new ColorRGBA(0.0f, 0.0f, 1.0f, 1.0f); //fully saturated blue emission - - @Override - protected void initialize(Application app) { - SimpleApplication simpleApp = (SimpleApplication) app; - AssetManager assetManager = app.getAssetManager(); - - setUpTerrain(simpleApp, assetManager); - setUpTerrainMaterial(assetManager); - setUpLights(simpleApp, assetManager); - setUpCamera(app); - - // Set debug mode - matTerrain.setInt("DebugValuesMode", debugMode); - } - - private void setUpTerrainMaterial(AssetManager assetManager) { - // advanced PBR terrain matdef - matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/AdvancedPBRTerrain.j3md"); - - matTerrain.setBoolean("useTriPlanarMapping", false); - - // ALPHA map (for splat textures) - matTerrain.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alpha1.png")); - matTerrain.setTexture("AlphaMap_1", assetManager.loadTexture("Textures/Terrain/splat/alpha2.png")); - - // load textures for texture arrays - // These MUST all have the same dimensions and format in order to be put into a texture array. - //ALBEDO MAPS - Texture dirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); - Texture darkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Color.png"); - Texture snow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Color.png"); - Texture tileRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Color.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Color.png"); - Texture marble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Color.png"); - Texture gravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Color.png"); - - // NORMAL MAPS - Texture normalMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_1K_Normal.png"); - Texture normalMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_1K_Normal.png"); - Texture normalMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_1K_Normal.png"); - Texture normalMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel015_1K_Normal.png"); - Texture normalMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_1K_Normal.png"); - Texture normalMapMarble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_1K_Normal.png"); - Texture normalMapRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_1K_Normal.png"); - - //PACKED METALLIC/ROUGHNESS / AMBIENT OCCLUSION / EMISSIVE INTENSITY MAPS - Texture metallicRoughnessAoEiMapDirt = assetManager.loadTexture("Textures/Terrain/PBR/Ground036_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapDarkRock = assetManager.loadTexture("Textures/Terrain/PBR/Rock035_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapSnow = assetManager.loadTexture("Textures/Terrain/PBR/Snow006_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapGravel = assetManager.loadTexture("Textures/Terrain/PBR/Gravel_015_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapGrass = assetManager.loadTexture("Textures/Terrain/PBR/Ground037_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapMarble = assetManager.loadTexture("Textures/Terrain/PBR/Marble013_PackedMetallicRoughnessMap.png"); - Texture metallicRoughnessAoEiMapRoad = assetManager.loadTexture("Textures/Terrain/PBR/Tiles083_PackedMetallicRoughnessMap.png"); - - // put all images into lists to create texture arrays. - List albedoImages = new ArrayList<>(); - List normalMapImages = new ArrayList<>(); - List metallicRoughnessAoEiMapImages = new ArrayList<>(); - - albedoImages.add(dirt.getImage()); //0 - albedoImages.add(darkRock.getImage()); //1 - albedoImages.add(snow.getImage()); //2 - albedoImages.add(tileRoad.getImage()); //3 - albedoImages.add(grass.getImage()); //4 - albedoImages.add(marble.getImage()); //5 - albedoImages.add(gravel.getImage()); //6 - - normalMapImages.add(normalMapDirt.getImage()); //0 - normalMapImages.add(normalMapDarkRock.getImage()); //1 - normalMapImages.add(normalMapSnow.getImage()); //2 - normalMapImages.add(normalMapRoad.getImage()); //3 - normalMapImages.add(normalMapGrass.getImage()); //4 - normalMapImages.add(normalMapMarble.getImage()); //5 - normalMapImages.add(normalMapGravel.getImage()); //6 - - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapDirt.getImage()); //0 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapDarkRock.getImage()); //1 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapSnow.getImage()); //2 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapRoad.getImage()); //3 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapGrass.getImage()); //4 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapMarble.getImage()); //5 - metallicRoughnessAoEiMapImages.add(metallicRoughnessAoEiMapGravel.getImage()); //6 - - //initiate texture arrays - TextureArray albedoTextureArray = new TextureArray(albedoImages); - TextureArray normalParallaxTextureArray = new TextureArray(normalMapImages); // parallax is not used currently - TextureArray metallicRoughnessAoEiTextureArray = new TextureArray(metallicRoughnessAoEiMapImages); - - //apply wrapMode to the whole texture array, rather than each individual texture in the array - setWrapAndMipMaps(albedoTextureArray); - setWrapAndMipMaps(normalParallaxTextureArray); - setWrapAndMipMaps(metallicRoughnessAoEiTextureArray); - - //assign texture array to materials - matTerrain.setParam("AlbedoTextureArray", VarType.TextureArray, albedoTextureArray); - matTerrain.setParam("NormalParallaxTextureArray", VarType.TextureArray, normalParallaxTextureArray); - matTerrain.setParam("MetallicRoughnessAoEiTextureArray", VarType.TextureArray, metallicRoughnessAoEiTextureArray); - - //set up texture slots: - matTerrain.setInt("AlbedoMap_0", 0); // dirt is index 0 in the albedo image list - matTerrain.setFloat("AlbedoMap_0_scale", dirtScale); - matTerrain.setFloat("Roughness_0", 1); - matTerrain.setFloat("Metallic_0", 0.02f); - - matTerrain.setInt("AlbedoMap_1", 1); // darkRock is index 1 in the albedo image list - matTerrain.setFloat("AlbedoMap_1_scale", darkRockScale); - matTerrain.setFloat("Roughness_1", 1); - matTerrain.setFloat("Metallic_1", 0.04f); - - matTerrain.setInt("AlbedoMap_2", 2); - matTerrain.setFloat("AlbedoMap_2_scale", snowScale); - matTerrain.setFloat("Roughness_2", 0.72f); - matTerrain.setFloat("Metallic_2", 0.12f); - - matTerrain.setInt("AlbedoMap_3", 3); - matTerrain.setFloat("AlbedoMap_3_scale", tileRoadScale); - matTerrain.setFloat("Roughness_3", 1); - matTerrain.setFloat("Metallic_3", 0.04f); - - matTerrain.setInt("AlbedoMap_4", 4); - matTerrain.setFloat("AlbedoMap_4_scale", grassScale); - matTerrain.setFloat("Roughness_4", 1); - matTerrain.setFloat("Metallic_4", 0); - - matTerrain.setInt("AlbedoMap_5", 5); - matTerrain.setFloat("AlbedoMap_5_scale", marbleScale); - matTerrain.setFloat("Roughness_5", 1); - matTerrain.setFloat("Metallic_5", 0.2f); - - matTerrain.setInt("AlbedoMap_6", 6); - matTerrain.setFloat("AlbedoMap_6_scale", gravelScale); - matTerrain.setFloat("Roughness_6", 1); - matTerrain.setFloat("Metallic_6", 0.01f); - - // NORMAL MAPS - matTerrain.setInt("NormalMap_0", 0); - matTerrain.setInt("NormalMap_1", 1); - matTerrain.setInt("NormalMap_2", 2); - matTerrain.setInt("NormalMap_3", 3); - matTerrain.setInt("NormalMap_4", 4); - matTerrain.setInt("NormalMap_5", 5); - matTerrain.setInt("NormalMap_6", 6); - - //METALLIC/ROUGHNESS/AO/EI MAPS - matTerrain.setInt("MetallicRoughnessMap_0", 0); - matTerrain.setInt("MetallicRoughnessMap_1", 1); - matTerrain.setInt("MetallicRoughnessMap_2", 2); - matTerrain.setInt("MetallicRoughnessMap_3", 3); - matTerrain.setInt("MetallicRoughnessMap_4", 4); - matTerrain.setInt("MetallicRoughnessMap_5", 5); - matTerrain.setInt("MetallicRoughnessMap_6", 6); - - //EMISSIVE - matTerrain.setColor("EmissiveColor_5", marbleEmissiveColor); - matTerrain.setColor("EmissiveColor_3", tilesEmissiveColor); - - terrain.setMaterial(matTerrain); - } - - private void setWrapAndMipMaps(Texture texture) { - texture.setWrap(WrapMode.Repeat); - texture.setMinFilter(MinFilter.Trilinear); - texture.setMagFilter(MagFilter.Bilinear); - } - - private void setUpTerrain(SimpleApplication simpleApp, AssetManager assetManager) { - // HEIGHTMAP image (for the terrain heightmap) - TextureKey hmKey = new TextureKey("Textures/Terrain/splat/mountains512.png", false); - Texture heightMapImage = assetManager.loadTexture(hmKey); - - // CREATE HEIGHTMAP - AbstractHeightMap heightmap; - try { - heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.3f); - heightmap.load(); - heightmap.smooth(0.9f, 1); - } catch (Exception e) { - throw new RuntimeException(e); - } - - terrain = new TerrainQuad("terrain", patchSize + 1, terrainSize + 1, heightmap.getHeightMap()); - TerrainLodControl control = new TerrainLodControl(terrain, getApplication().getCamera()); - control.setLodCalculator(new DistanceLodCalculator(patchSize + 1, 2.7f)); // patch size, and a multiplier - terrain.addControl(control); - terrain.setMaterial(matTerrain); - terrain.setLocalTranslation(0, -100, 0); - terrain.setLocalScale(1f, 1f, 1f); - simpleApp.getRootNode().attachChild(terrain); - } - - private void setUpLights(SimpleApplication simpleApp, AssetManager assetManager) { - LightProbe probe = (LightProbe) assetManager.loadAsset("Scenes/LightProbes/quarry_Probe.j3o"); - - probe.setAreaType(LightProbe.AreaType.Spherical); - probe.getArea().setRadius(2000); - probe.getArea().setCenter(new Vector3f(0, 0, 0)); - simpleApp.getRootNode().addLight(probe); - - DirectionalLight directionalLight = new DirectionalLight(); - directionalLight.setDirection((new Vector3f(-0.3f, -0.5f, -0.3f)).normalize()); - directionalLight.setColor(ColorRGBA.White); - simpleApp.getRootNode().addLight(directionalLight); - - AmbientLight ambientLight = new AmbientLight(); - ambientLight.setColor(ColorRGBA.White); - simpleApp.getRootNode().addLight(ambientLight); - } - - private void setUpCamera(Application app) { - app.getCamera().setLocation(new Vector3f(0, 10, -10)); - app.getCamera().lookAtDirection(new Vector3f(0, -1.5f, -1).normalizeLocal(), Vector3f.UNIT_Y); - } - - @Override - protected void cleanup(Application app) {} - - @Override - protected void onEnable() {} - - @Override - protected void onDisable() {} - - }).setBaseImageFileName(imageName) - .setFramesToTakeScreenshotsOn(5) - .run(); - } -} \ No newline at end of file diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/texture/TestSingleChannelTexture.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/texture/TestSingleChannelTexture.java deleted file mode 100644 index 170f35f01f..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/texture/TestSingleChannelTexture.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2026 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.texture; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; -import com.jme3.ui.Picture; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.jmonkeyengine.screenshottests.testframework.TestResolution; -import org.junit.jupiter.api.Test; - -/** - * Screenshot test for single-channel PNG loading. - */ -public class TestSingleChannelTexture extends ScreenshotTestBase { - - private static final int TEXTURE_SIZE = 251; - - @Test - public void testSingleChannelTexture() { - screenshotTest(new BaseAppState() { - @Override - protected void initialize(Application app) { - SimpleApplication simpleApplication = (SimpleApplication) app; - - attachPicture(simpleApplication, "single-channel-r16", - "Textures/singleChannel/R16.png", 0f); - attachPicture(simpleApplication, "single-channel-r8", - "Textures/singleChannel/R8.png", TEXTURE_SIZE); - } - - private void attachPicture(SimpleApplication app, String name, String texturePath, float x) { - Texture texture = app.getAssetManager().loadTexture(texturePath); - Picture picture = new Picture(name); - picture.setTexture(app.getAssetManager(), (Texture2D) texture, false); - picture.setPosition(x, 0f); - picture.setWidth(TEXTURE_SIZE); - picture.setHeight(TEXTURE_SIZE); - app.getGuiNode().attachChild(picture); - } - - @Override - protected void cleanup(Application app) { - } - - @Override - protected void onEnable() { - } - - @Override - protected void onDisable() { - } - }) - .setTestResolution(new TestResolution(TEXTURE_SIZE * 2, TEXTURE_SIZE)) - .setFramesToTakeScreenshotsOn(1) - .run(); - } -} diff --git a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/water/TestPostWater.java b/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/water/TestPostWater.java deleted file mode 100644 index 7868ecd71e..0000000000 --- a/jme3-screenshot-tests/src/test/java/org/jmonkeyengine/screenshottests/water/TestPostWater.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2024 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package org.jmonkeyengine.screenshottests.water; - -import com.jme3.app.Application; -import com.jme3.app.SimpleApplication; -import com.jme3.app.state.BaseAppState; -import com.jme3.asset.AssetManager; -import com.jme3.light.AmbientLight; -import com.jme3.light.DirectionalLight; -import com.jme3.material.Material; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.BloomFilter; -import com.jme3.post.filters.DepthOfFieldFilter; -import com.jme3.post.filters.FXAAFilter; -import com.jme3.post.filters.LightScatteringFilter; -import com.jme3.renderer.queue.RenderQueue.ShadowMode; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.terrain.geomipmap.TerrainQuad; -import com.jme3.terrain.heightmap.AbstractHeightMap; -import com.jme3.terrain.heightmap.ImageBasedHeightMap; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapMode; -import com.jme3.texture.Texture2D; -import com.jme3.util.SkyFactory; -import com.jme3.util.SkyFactory.EnvMapType; -import com.jme3.water.WaterFilter; -import org.jmonkeyengine.screenshottests.testframework.ScreenshotTestBase; -import org.junit.jupiter.api.Test; - -/** - * @author Richard Tingle (aka richtea) - */ -public class TestPostWater extends ScreenshotTestBase{ - - /** - * This test creates a scene with a terrain and post process water filter. - */ - @Test - public void testPostWater(){ - screenshotTest(new BaseAppState(){ - @Override - protected void initialize(Application app){ - Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f); - SimpleApplication simpleApplication = ((SimpleApplication)app); - Node rootNode = simpleApplication.getRootNode(); - AssetManager assetManager = simpleApplication.getAssetManager(); - - Node mainScene = new Node("Main Scene"); - rootNode.attachChild(mainScene); - - createTerrain(mainScene, assetManager); - DirectionalLight sun = new DirectionalLight(); - sun.setDirection(lightDir); - sun.setColor(ColorRGBA.White.clone().multLocal(1f)); - mainScene.addLight(sun); - - AmbientLight al = new AmbientLight(); - al.setColor(new ColorRGBA(0.1f, 0.1f, 0.1f, 1.0f)); - mainScene.addLight(al); - - - simpleApplication.getCamera().setLocation(new Vector3f(-370.31592f, 182.04016f, 196.81192f)); - simpleApplication.getCamera().setRotation(new Quaternion(0.10058216f, 0.51807004f, -0.061508257f, 0.8471738f)); - - Spatial sky = SkyFactory.createSky(assetManager, - "Scenes/Beach/FullskiesSunset0068.dds", EnvMapType.CubeMap); - sky.setLocalScale(350); - - mainScene.attachChild(sky); - simpleApplication.getCamera().setFrustumFar(4000); - - //Water Filter - WaterFilter water = new WaterFilter(rootNode, lightDir); - water.setWaterColor(new ColorRGBA().setAsSrgb(0.0078f, 0.3176f, 0.5f, 1.0f)); - water.setDeepWaterColor(new ColorRGBA().setAsSrgb(0.0039f, 0.00196f, 0.145f, 1.0f)); - water.setUnderWaterFogDistance(80); - water.setWaterTransparency(0.12f); - water.setFoamIntensity(0.4f); - water.setFoamHardness(0.3f); - water.setFoamExistence(new Vector3f(0.8f, 8f, 1f)); - water.setReflectionDisplace(50); - water.setRefractionConstant(0.25f); - water.setColorExtinction(new Vector3f(30, 50, 70)); - water.setCausticsIntensity(0.4f); - water.setWaveScale(0.003f); - water.setMaxAmplitude(2f); - water.setFoamTexture((Texture2D) assetManager.loadTexture("Common/MatDefs/Water/Textures/foam2.jpg")); - water.setRefractionStrength(0.2f); - //0.8f; - float initialWaterHeight = 90f; - water.setWaterHeight(initialWaterHeight); - - //Bloom Filter - BloomFilter bloom = new BloomFilter(); - bloom.setExposurePower(55); - bloom.setBloomIntensity(1.0f); - - //Light Scattering Filter - LightScatteringFilter lsf = new LightScatteringFilter(lightDir.mult(-300)); - lsf.setLightDensity(0.5f); - - //Depth of field Filter - DepthOfFieldFilter dof = new DepthOfFieldFilter(); - dof.setFocusDistance(0); - dof.setFocusRange(100); - - FilterPostProcessor fpp = new FilterPostProcessor(assetManager); - - fpp.addFilter(water); - fpp.addFilter(bloom); - fpp.addFilter(dof); - fpp.addFilter(lsf); - fpp.addFilter(new FXAAFilter()); - - int numSamples = simpleApplication.getContext().getSettings().getSamples(); - if (numSamples > 0) { - fpp.setNumSamples(numSamples); - } - simpleApplication.getViewPort().addProcessor(fpp); - } - - @Override protected void cleanup(Application app){} - - @Override protected void onEnable(){} - - @Override protected void onDisable(){} - - @Override - public void update(float tpf){ - super.update(tpf); - } - - private void createTerrain(Node rootNode, AssetManager assetManager) { - Material matRock = new Material(assetManager, - "Common/MatDefs/Terrain/TerrainLighting.j3md"); - matRock.setBoolean("useTriPlanarMapping", false); - matRock.setBoolean("WardIso", true); - matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png")); - Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png"); - Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg"); - grass.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap", grass); - matRock.setFloat("DiffuseMap_0_scale", 64); - Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg"); - dirt.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_1", dirt); - matRock.setFloat("DiffuseMap_1_scale", 16); - Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg"); - rock.setWrap(WrapMode.Repeat); - matRock.setTexture("DiffuseMap_2", rock); - matRock.setFloat("DiffuseMap_2_scale", 128); - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); - normalMap0.setWrap(WrapMode.Repeat); - Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); - normalMap1.setWrap(WrapMode.Repeat); - Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png"); - normalMap2.setWrap(WrapMode.Repeat); - matRock.setTexture("NormalMap", normalMap0); - matRock.setTexture("NormalMap_1", normalMap1); - matRock.setTexture("NormalMap_2", normalMap2); - - AbstractHeightMap heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f); - heightmap.load(); - - TerrainQuad terrain - = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap()); - terrain.setMaterial(matRock); - terrain.setLocalScale(new Vector3f(5, 5, 5)); - terrain.setLocalTranslation(new Vector3f(0, -30, 0)); - terrain.setLocked(false); // unlock it so we can edit the height - - terrain.setShadowMode(ShadowMode.Receive); - rootNode.attachChild(terrain); - } - }).run(); - } - -} \ No newline at end of file