Skip to content

Commit 606fb03

Browse files
Use an offbuffer for the CI screenshot tests (#2751)
* Make the screenshot tests run in an off frame buffer and correct gamma issues in screenshots * Make the definition of "the same" a bit more flexible to avoid instability in the pipelines * Restore gamma correction * Set the colourspace for the off renderTexture * Set the Srgb for the off renderTexture * Rebake minor visual changes for off frame buffer * Update jme3-screenshot-tests/src/main/java/org/jmonkeyengine/screenshottests/testframework/TestDriver.java Correct to actually compare the scenario with the prime Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * Ensure the fileOutBuf is closed * Avoid intermediate colour object * Avoid the wildcard import --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 4e18b18 commit 606fb03

17 files changed

Lines changed: 183 additions & 429 deletions
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.jmonkeyengine.screenshottests.testframework;
2+
3+
import com.jme3.app.Application;
4+
import com.jme3.app.state.AbstractAppState;
5+
import com.jme3.app.state.AppStateManager;
6+
import com.jme3.renderer.Renderer;
7+
import com.jme3.system.JmeSystem;
8+
import com.jme3.texture.FrameBuffer;
9+
import com.jme3.texture.Texture2D;
10+
import com.jme3.util.BufferUtils;
11+
12+
import java.io.FileOutputStream;
13+
import java.io.IOException;
14+
import java.nio.ByteBuffer;
15+
import java.nio.file.Path;
16+
import java.util.Optional;
17+
18+
public class OffScreenshotAppState extends AbstractAppState{
19+
20+
private final Texture2D renderTexture;
21+
private Renderer renderer;
22+
private final FrameBuffer frameBuffer;
23+
private Optional<Path> capture = Optional.empty();
24+
25+
private ByteBuffer outBuf;
26+
27+
public void takeScreenshot(Path pathToSaveTo) {
28+
capture = Optional.of(pathToSaveTo);
29+
}
30+
31+
public OffScreenshotAppState(Texture2D renderTexture, FrameBuffer frameBuffer) {
32+
this.renderTexture = renderTexture;
33+
this.frameBuffer = frameBuffer;
34+
}
35+
36+
@Override
37+
public void initialize(AppStateManager stateManager, Application app) {
38+
super.initialize(stateManager, app);
39+
renderer = app.getRenderManager().getRenderer();
40+
outBuf = BufferUtils.createByteBuffer(renderTexture.getImage().getWidth() * renderTexture.getImage().getHeight() * 4);
41+
}
42+
43+
@Override
44+
public void postRender() {
45+
super.postRender();
46+
if (capture.isPresent()) {
47+
48+
renderer.readFrameBuffer(frameBuffer, outBuf);
49+
try (FileOutputStream fileOutBuf = new FileOutputStream(capture.get().toFile())){
50+
51+
JmeSystem.writeImageFile(fileOutBuf, "png",outBuf, renderTexture.getImage().getWidth(), renderTexture.getImage().getHeight());
52+
}catch (IOException e) {
53+
throw new RuntimeException(e);
54+
}
55+
capture = Optional.empty();
56+
}
57+
}
58+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
*/
3939
public enum PixelSamenessDegree{
4040
SAME(1, null),
41-
NEGLIGIBLY_DIFFERENT(1, ColorRGBA.Green),
41+
NEGLIGIBLY_DIFFERENT(3, ColorRGBA.Green),
4242
SUBTLY_DIFFERENT(10, ColorRGBA.Blue),
4343

4444
MEDIUMLY_DIFFERENT(20, ColorRGBA.Yellow),
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.jmonkeyengine.screenshottests.testframework;
2+
3+
import java.nio.file.Path;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
import java.util.Optional;
7+
8+
public class ScenarioScreenshotRecorder {
9+
10+
/**
11+
* scenario name -> frame number -> screenshot path
12+
*/
13+
Map<String, Map<Integer, Path>> screenshotsAtFrames = new HashMap<>();
14+
15+
public void recordScreenshot(String scenarioName, int frameNumber, Path screenshotPath){
16+
screenshotsAtFrames.computeIfAbsent(scenarioName, k -> new HashMap<>()).put(frameNumber, screenshotPath);
17+
}
18+
19+
public Optional<Path> getScreenshotsAtFrame(String scenarioName, int frameNumber){
20+
if(!screenshotsAtFrames.containsKey(scenarioName) || !screenshotsAtFrames.get(scenarioName).containsKey(frameNumber)){
21+
return Optional.empty();
22+
}else{
23+
return Optional.of(screenshotsAtFrames.get(scenarioName).get(frameNumber));
24+
}
25+
}
26+
27+
public void addAll(ScenarioScreenshotRecorder other) {
28+
for (Map.Entry<String, Map<Integer, Path>> scenarioEntry : other.screenshotsAtFrames.entrySet()) {
29+
String scenarioName = scenarioEntry.getKey();
30+
for (Map.Entry<Integer, Path> frameEntry : scenarioEntry.getValue().entrySet()) {
31+
recordScreenshot(scenarioName, frameEntry.getKey(), frameEntry.getValue());
32+
}
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)