screenshots refactoring
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-07-04 18:58:38 -04:00
parent f7887fc875
commit 6da4c001fa
6 changed files with 124 additions and 79 deletions

View File

@ -16,11 +16,6 @@
"Green Grass" "Green Grass"
], ],
"texture" : "/Textures/Ground/GrassTileable256.png" "texture" : "/Textures/Ground/GrassTileable256.png"
},
{
"id" : 3,
"name" : "baguette",
"texture" : "/Textures/Ground/baguette256.png"
} }
] ]
} }

View File

@ -522,6 +522,7 @@ gltf Support
- Fix bad data with human mesh textures not mapping - Fix bad data with human mesh textures not mapping
- Texture loading from gltf file - Texture loading from gltf file
FileUtils sanitation function check if requested file is in game root dir
Cellular Automata Fluid Dynamics System Cellular Automata Fluid Dynamics System
- Advect force - Advect force

View File

@ -106,6 +106,7 @@ import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.KeyboardEvent; import electrosphere.renderer.ui.events.KeyboardEvent;
import electrosphere.renderer.ui.events.MenuEvent; import electrosphere.renderer.ui.events.MenuEvent;
import electrosphere.renderer.ui.events.MenuEvent.MenuEventType; import electrosphere.renderer.ui.events.MenuEvent.MenuEventType;
import electrosphere.util.FileUtils;
import electrosphere.renderer.ui.events.MouseEvent; import electrosphere.renderer.ui.events.MouseEvent;
import electrosphere.renderer.ui.events.ScrollEvent; import electrosphere.renderer.ui.events.ScrollEvent;
@ -1195,7 +1196,10 @@ public class ControlHandler {
*/ */
menuNavigationControlList.add(controls.get(MENU_CAPTURE_SCREEN)); menuNavigationControlList.add(controls.get(MENU_CAPTURE_SCREEN));
controls.get(MENU_CAPTURE_SCREEN).setOnPress(new Control.ControlMethod() {public void execute(){ controls.get(MENU_CAPTURE_SCREEN).setOnPress(new Control.ControlMethod() {public void execute(){
RenderingEngine.screenFramebuffer.getPixels(Globals.renderingEngine.getOpenGLState()); FileUtils.writeBufferedImage(
RenderingEngine.defaultFramebuffer.getPixels(Globals.renderingEngine.getOpenGLState()),
"Screenshots/" + System.currentTimeMillis() + ".png"
);
}}); }});

View File

@ -116,6 +116,7 @@ public class RenderingEngine {
public static int screenTextureVAO; public static int screenTextureVAO;
public static ShaderProgram screenTextureShaders; public static ShaderProgram screenTextureShaders;
public static ShaderProgram drawChannel; public static ShaderProgram drawChannel;
public static Framebuffer defaultFramebuffer;
@ -319,6 +320,9 @@ public class RenderingEngine {
// initScreenTextureShaderProgram(); // initScreenTextureShaderProgram();
screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/simple1/simple1.vs", "/Shaders/screentexture/simple1/simple1.fs"); screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/simple1/simple1.vs", "/Shaders/screentexture/simple1/simple1.fs");
// screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.vs", "/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.fs"); // screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.vs", "/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.fs");
//default framebuffer
defaultFramebuffer = new Framebuffer(0);
//generate framebuffers //generate framebuffers
screenTextureColor = FramebufferUtils.generateScreenTextureColor(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); screenTextureColor = FramebufferUtils.generateScreenTextureColor(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());

View File

@ -46,6 +46,14 @@ public class Framebuffer {
framebufferPointer = glGenFramebuffers(); framebufferPointer = glGenFramebuffers();
} }
/**
* Creates a framebuffer with a predefined id
* @param framebufferId The predefined framebuffer id
*/
public Framebuffer(int framebufferId){
this.framebufferPointer = framebufferId;
}
/** /**
* Sets the texture attached to the framebuffer * Sets the texture attached to the framebuffer
* @param texture The texture attached to the framebuffer * @param texture The texture attached to the framebuffer
@ -229,22 +237,27 @@ public class Framebuffer {
*/ */
public BufferedImage getPixels(OpenGLState openGLState){ public BufferedImage getPixels(OpenGLState openGLState){
BufferedImage rVal = null; BufferedImage rVal = null;
bind(openGLState);
GL40.glReadBuffer(GL40.GL_COLOR_ATTACHMENT0);
int offsetX = 0; int offsetX = 0;
int offsetY = 0; int offsetY = 0;
int width = openGLState.getViewport().x; int width = openGLState.getViewport().x;
int height = openGLState.getViewport().y; int height = openGLState.getViewport().y;
int pixelFormat = GL40.GL_RGBA; int pixelFormat = GL40.GL_RGBA;
int type = GL40.GL_UNSIGNED_INT; int type = GL40.GL_UNSIGNED_INT;
if(attachTextureMap.containsKey(0)){
bind(openGLState);
GL40.glReadBuffer(GL40.GL_COLOR_ATTACHMENT0);
if(this.framebufferPointer == 0){
//this is the default framebuffer, read from backbuffer because it is default
GL40.glReadBuffer(GL40.GL_BACK);
} else if(attachTextureMap.containsKey(0)){
Texture texture = attachTextureMap.get(0); Texture texture = attachTextureMap.get(0);
pixelFormat = texture.getFormat(); pixelFormat = texture.getFormat();
type = texture.getDataType(); type = texture.getDataType();
width = texture.getWidth(); width = texture.getWidth();
height = texture.getHeight(); height = texture.getHeight();
} else { } else {
throw new IllegalStateException("Tried to get pixels from a framebuffer that does not have a texture attached to attachment point 0."); LoggerInterface.loggerRenderer.ERROR(new IllegalStateException("Tried to get pixels from a framebuffer that does not have a texture attached to attachment point 0."));
} }
//get pixel data //get pixel data
try { try {
@ -262,10 +275,6 @@ public class Framebuffer {
int red = buffer.get(i) & 0xFF; int red = buffer.get(i) & 0xFF;
int green = buffer.get(i + 1) & 0xFF; int green = buffer.get(i + 1) & 0xFF;
int blue = buffer.get(i + 2) & 0xFF; int blue = buffer.get(i + 2) & 0xFF;
if(red != 0 || green != 0 || blue != 0){
System.out.println(x + " " + y);
System.out.println(red + " " + green + " " + blue);
}
int alpha = 255; int alpha = 255;
if(pixelFormat == GL40.GL_RGBA){ if(pixelFormat == GL40.GL_RGBA){
alpha = buffer.get(i + 3) & 0xFF; alpha = buffer.get(i + 3) & 0xFF;
@ -273,19 +282,6 @@ public class Framebuffer {
rVal.setRGB(x, height - (y + 1), (alpha << 24) | (red << 16) | (green << 8) | blue); rVal.setRGB(x, height - (y + 1), (alpha << 24) | (red << 16) | (green << 8) | blue);
} }
} }
//write the buffered image out
try {
File outputFile = FileUtils.getAssetFile("Screenshots/" + System.currentTimeMillis() + ".png");
if(!outputFile.getParentFile().exists()){
outputFile.getParentFile().mkdirs();
}
if(!outputFile.exists()){
outputFile.createNewFile();
}
ImageIO.write(rVal,"png",outputFile);
} catch (IOException e) {
LoggerInterface.loggerRenderer.ERROR(e);
}
//memory management //memory management
MemoryUtil.memFree(buffer); MemoryUtil.memFree(buffer);
} catch (OutOfMemoryError e){ } catch (OutOfMemoryError e){

View File

@ -3,12 +3,12 @@ package electrosphere.util;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import electrosphere.engine.Main;
import electrosphere.game.data.creature.type.movement.MovementSystem; import electrosphere.game.data.creature.type.movement.MovementSystem;
import electrosphere.game.data.creature.type.movement.MovementSystemSerializer; import electrosphere.game.data.creature.type.movement.MovementSystemSerializer;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.util.annotation.AnnotationExclusionStrategy; import electrosphere.util.annotation.AnnotationExclusionStrategy;
import java.awt.image.BufferedImage;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -16,27 +16,48 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.StandardOpenOption; import java.nio.file.Paths;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
/**
* Utilities for dealing with files
*/
public class FileUtils { public class FileUtils {
/**
* Creates the gson instance
*/
static { static {
//init gson
GsonBuilder gsonBuilder = new GsonBuilder(); GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(MovementSystem.class, new MovementSystemSerializer()); gsonBuilder.registerTypeAdapter(MovementSystem.class, new MovementSystemSerializer());
gsonBuilder.addDeserializationExclusionStrategy(new AnnotationExclusionStrategy()); gsonBuilder.addDeserializationExclusionStrategy(new AnnotationExclusionStrategy());
gsonBuilder.addSerializationExclusionStrategy(new AnnotationExclusionStrategy()); gsonBuilder.addSerializationExclusionStrategy(new AnnotationExclusionStrategy());
gson = gsonBuilder.create(); gson = gsonBuilder.create();
//init gamedir
gameDir = Paths.get("").toFile();
} }
//used for serialization/deserialization in file operations
static Gson gson; static Gson gson;
//the game's root directory
static File gameDir = null;
//maximum number of attempt to read the file
static final int maxReadFails = 3; static final int maxReadFails = 3;
//Timeout duration between read attempts
static final int READ_TIMEOUT_DURATION = 5; static final int READ_TIMEOUT_DURATION = 5;
/**
* Reads a file to a string
* @param f The file
* @return The string
*/
public static String readFileToString(File f){ public static String readFileToString(File f){
String rVal = ""; String rVal = "";
BufferedReader reader; BufferedReader reader;
@ -113,16 +134,6 @@ public class FileUtils {
} }
// public static String sanitizeBakedFilePath(String filePath){
// String rVal = new String(filePath);
// rVal = rVal.trim();
// if(!rVal.startsWith("/")){
// rVal = "/" + rVal;
// }
// return rVal;
// }
/** /**
* Sanitizes a relative file path, guaranteeing that the initial slash is correct * Sanitizes a relative file path, guaranteeing that the initial slash is correct
* @param filePath The raw file path * @param filePath The raw file path
@ -139,14 +150,11 @@ public class FileUtils {
return rVal; return rVal;
} }
// public static String readStringFromBakedFile(String bakedFilePath){ /**
// String rVal = ""; * Serializes an object to a filepath
// String sanitizedFilePath = sanitizeBakedFilePath(bakedFilePath); * @param filePath The filepath
// rVal = readStreamToString(Main.class.getResourceAsStream(sanitizedFilePath)); * @param object The object
// return rVal; */
// }
public static void serializeObjectToFilePath(String filePath, Object object){ public static void serializeObjectToFilePath(String filePath, Object object){
Path path = new File(filePath).toPath(); Path path = new File(filePath).toPath();
try { try {
@ -156,12 +164,23 @@ public class FileUtils {
} }
} }
/**
* Gets an assets file
* @param pathName The relative path in the assets folder
* @return The file
*/
public static File getAssetFile(String pathName){ public static File getAssetFile(String pathName){
String sanitizedFilePath = sanitizeFilePath(pathName); String sanitizedFilePath = sanitizeFilePath(pathName);
File targetFile = new File("./assets" + sanitizedFilePath); File targetFile = new File("./assets" + sanitizedFilePath);
return targetFile; return targetFile;
} }
/**
* Gets a save file
* @param saveName The name of the save
* @param pathName The relative path in the save's folder
* @return the file
*/
public static File getSaveFile(String saveName, String pathName){ public static File getSaveFile(String saveName, String pathName){
String sanitizedFilePath = sanitizeFilePath(pathName); String sanitizedFilePath = sanitizeFilePath(pathName);
String fullPath = "./saves/" + saveName + "/" + sanitizedFilePath; String fullPath = "./saves/" + saveName + "/" + sanitizedFilePath;
@ -169,29 +188,54 @@ public class FileUtils {
return targetFile; return targetFile;
} }
/**
* Gets an asset file as a stream
* @param pathName The path of the file
* @return The stream
* @throws IOException Thrown if Files fails to create the stream
*/
public static InputStream getAssetFileAsStream(String pathName) throws IOException{ public static InputStream getAssetFileAsStream(String pathName) throws IOException{
String sanitizedFilePath = sanitizeFilePath(pathName); String sanitizedFilePath = sanitizeFilePath(pathName);
File targetFile = new File("./assets" + sanitizedFilePath); File targetFile = new File("./assets" + sanitizedFilePath);
return Files.newInputStream(targetFile.toPath()); return Files.newInputStream(targetFile.toPath());
} }
/**
* Gets an asset file as a string
* @param pathName The path of the file
* @return The string
* @throws IOException Thrown if Files fails to read the file
*/
public static String getAssetFileAsString(String pathName) throws IOException{ public static String getAssetFileAsString(String pathName) throws IOException{
String sanitizedFilePath = sanitizeFilePath(pathName); String sanitizedFilePath = sanitizeFilePath(pathName);
File targetFile = new File("./assets" + sanitizedFilePath); File targetFile = new File("./assets" + sanitizedFilePath);
return Files.readString(targetFile.toPath()); return Files.readString(targetFile.toPath());
} }
/**
* Loads an object from the assets folder
* @param <T> The type of object
* @param pathName The relative path to the file
* @param className The class of the object inside the file
* @return The file
*/
public static <T>T loadObjectFromAssetPath(String pathName, Class<T> className){ public static <T>T loadObjectFromAssetPath(String pathName, Class<T> className){
T rVal = null; T rVal = null;
String sanitizedFilePath = sanitizeFilePath(pathName); String sanitizedFilePath = sanitizeFilePath(pathName);
try { try {
rVal = gson.fromJson(Files.newBufferedReader(getAssetFile(sanitizedFilePath).toPath()), className); rVal = gson.fromJson(Files.newBufferedReader(getAssetFile(sanitizedFilePath).toPath()), className);
} catch (IOException ex) { } catch (IOException ex) {
ex.printStackTrace(); LoggerInterface.loggerFileIO.ERROR(ex);
} }
return rVal; return rVal;
} }
/**
* Gets an sql script file as a string
* @param pathName The path of the sql script
* @return The file's contents as a string
* @throws IOException Thrown if the engine fails to read the file
*/
public static String getSQLScriptFileAsString(String pathName) throws IOException { public static String getSQLScriptFileAsString(String pathName) throws IOException {
String sanitizedFilePath = sanitizeFilePath(pathName); String sanitizedFilePath = sanitizeFilePath(pathName);
File targetFile = new File("./src/main/sql" + sanitizedFilePath); File targetFile = new File("./src/main/sql" + sanitizedFilePath);
@ -306,7 +350,11 @@ public class FileUtils {
} }
} }
/**
* Lists the files in a directory
* @param directoryName The path of the directory
* @return A list containing the names of all files inside that directory
*/
public static List<String> listDirectory(String directoryName){ public static List<String> listDirectory(String directoryName){
List<String> rVal = new LinkedList<String>(); List<String> rVal = new LinkedList<String>();
String sanitizedPath = sanitizeFilePath(directoryName); String sanitizedPath = sanitizeFilePath(directoryName);
@ -318,6 +366,10 @@ public class FileUtils {
return rVal; return rVal;
} }
/**
* Recursively deletes a path
* @param path The path
*/
public static void recursivelyDelete(String path){ public static void recursivelyDelete(String path){
File file = new File(path); File file = new File(path);
if(file.isDirectory()){ if(file.isDirectory()){
@ -334,36 +386,29 @@ public class FileUtils {
} }
} }
} }
/**
* Writes a buffered image to a given path
* @param image The image
* @param path The path
*/
public static void writeBufferedImage(BufferedImage image, String path){
//write the buffered image out
try {
File outputFile = FileUtils.getAssetFile(path);
if(!outputFile.getParentFile().exists()){
outputFile.getParentFile().mkdirs();
}
if(!outputFile.exists()){
outputFile.createNewFile();
}
ImageIO.write(image,"png",outputFile);
} catch (IOException e) {
LoggerInterface.loggerRenderer.ERROR(e);
}
}
// public static <T>T loadModelObjectFromBakedJsonFile(String fileName, Class<T> className){
// T rVal = null;
// String sanitizedFilePath = sanitizeBakedFilePath(fileName);
// String rawJSON = readStreamToString(Main.class.getResourceAsStream(sanitizedFilePath));
// Gson gson = new Gson();
// rVal = gson.fromJson(rawJSON, className);
// return rVal;
// }
//
// public static File unpackBakedFileToFilePath(String bakedFilePath){
// String sanitizedFilePath = sanitizeBakedFilePath(bakedFilePath);
// if(!Files.exists(new File("./Models").toPath())){
// try {
// Files.createDirectory(new File("./Models").toPath());
// } catch (IOException ex) {
// ex.printStackTrace();
// }
// }
// File targetFile = new File("." + sanitizedFilePath);
// try {
// Files.write(targetFile.toPath(), Main.class.getResourceAsStream(sanitizedFilePath).readAllBytes(),StandardOpenOption.CREATE,StandardOpenOption.WRITE);
// } catch (IOException ex) {
// ex.printStackTrace();
// }
// return targetFile;
// }
} }