testing fix
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-09-15 13:04:08 -04:00
parent 79e2fdf512
commit a7c8571afa
18 changed files with 246 additions and 63 deletions

View File

@ -1,6 +1,6 @@
@page humanprogress Human @page skeletonprogres Skeleton
Progress on the human creature Progress on the skeleton creature
## Third Person Model ## Third Person Model
- [X] Meshed - [X] Meshed

View File

@ -765,6 +765,7 @@ Fix movement packet timing bug
Fix all items spawning above player head Fix all items spawning above player head
Fix items falling below terrain Fix items falling below terrain
Fix gridded data cell manager saving attached items on realm save Fix gridded data cell manager saving attached items on realm save
Fix render signals caching between frames (not reseting global flags per usual)
# TODO # TODO

View File

@ -240,8 +240,8 @@ public class Globals {
//OpenGL - Other //OpenGL - Other
// //
public static int WINDOW_WIDTH = 1920; public static int WINDOW_WIDTH;
public static int WINDOW_HEIGHT = 1080; public static int WINDOW_HEIGHT;
public static boolean WINDOW_DECORATED = true; //used to control whether the window is created with decorations or not (ie for testing) public static boolean WINDOW_DECORATED = true; //used to control whether the window is created with decorations or not (ie for testing)
public static boolean WINDOW_FULLSCREEN = false; //used to control whether the window is created fullscreen or not (ie for testing) public static boolean WINDOW_FULLSCREEN = false; //used to control whether the window is created fullscreen or not (ie for testing)
@ -444,10 +444,22 @@ public class Globals {
Globals.javaPID = ManagementFactory.getRuntimeMXBean().getName(); Globals.javaPID = ManagementFactory.getRuntimeMXBean().getName();
} }
//load user settings //load user settings
Globals.WINDOW_WIDTH = 1920;
Globals.WINDOW_HEIGHT = 1080;
UserSettings.loadUserSettings(); UserSettings.loadUserSettings();
//timekeeper //timekeeper
timekeeper = new Timekeeper(); timekeeper = new Timekeeper();
threadManager = new ThreadManager(); Globals.threadManager = new ThreadManager();
Globals.threadManager.init();
//render flags
RENDER_FLAG_RENDER_SHADOW_MAP = false;
RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = false;
RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = false;
RENDER_FLAG_RENDER_BLACK_BACKGROUND = true;
RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
RENDER_FLAG_RENDER_UI = true;
RENDER_FLAG_RENDER_UI_BOUNDS = false;
//load in default texture map //load in default texture map
textureMapDefault = TextureMap.construct("Textures/default_texture_map.json"); textureMapDefault = TextureMap.construct("Textures/default_texture_map.json");
//load model pretransforms //load model pretransforms
@ -667,6 +679,7 @@ public class Globals {
Globals.clientScene = null; Globals.clientScene = null;
Globals.audioEngine = null; Globals.audioEngine = null;
Globals.renderingEngine = null; Globals.renderingEngine = null;
Globals.threadManager = null;
Globals.signalSystem = null; Globals.signalSystem = null;
Globals.serviceManager = null; Globals.serviceManager = null;
Globals.clientConnection = null; Globals.clientConnection = null;
@ -681,6 +694,7 @@ public class Globals {
Globals.RENDER_FLAG_RENDER_UI = false; Globals.RENDER_FLAG_RENDER_UI = false;
Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false; Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false;
Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false; Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
Globals.window = -1;
LoggerInterface.destroyLoggers(); LoggerInterface.destroyLoggers();
} }

View File

@ -17,18 +17,27 @@ import electrosphere.util.CodeUtils;
public class ThreadManager { public class ThreadManager {
//Threadsafes the manager //Threadsafes the manager
Semaphore threadLock = new Semaphore(1); Semaphore threadLock;
//All threads that are actively running //All threads that are actively running
private List<LabeledThread> activeThreads = new LinkedList<LabeledThread>(); private List<LabeledThread> activeThreads;
//All loading threads that are actively running //All loading threads that are actively running
private List<LoadingThread> loadingThreads = new LinkedList<LoadingThread>(); private List<LoadingThread> loadingThreads;
//Used by main thread to alert other threads whether they should keep running or not //Used by main thread to alert other threads whether they should keep running or not
private boolean shouldKeepRunning = true; private boolean shouldKeepRunning;
/**
* Initializes the thread manager
*/
public void init(){
threadLock = new Semaphore(1);
activeThreads = new LinkedList<LabeledThread>();
loadingThreads = new LinkedList<LoadingThread>();
shouldKeepRunning = true;
}
/** /**
* Updates what threads are being tracked * Updates what threads are being tracked

View File

@ -20,7 +20,7 @@ import electrosphere.renderer.shader.ShaderProgram;
public class OpenGLState { public class OpenGLState {
//tracks whether caching should be used or not (to deduplicate opengl calls) //tracks whether caching should be used or not (to deduplicate opengl calls)
private static final boolean DISABLE_CACHING = false; private static final boolean DISABLE_CACHING = true;
//the max texture allowed by the current environment //the max texture allowed by the current environment
int MAX_TEXTURE_WIDTH; int MAX_TEXTURE_WIDTH;
@ -67,14 +67,18 @@ public class OpenGLState {
*/ */
public void init(){ public void init(){
this.MAX_TEXTURE_WIDTH = 0; this.MAX_TEXTURE_WIDTH = 0;
this.viewport = new Vector2i(0,0); this.viewport = new Vector2i(Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT);
GL45.glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
this.depthTest = false; this.depthTest = false;
GL45.glDisable(GL45.GL_DEPTH_TEST);
this.depthFunction = -1; this.depthFunction = -1;
this.blendTest = false; this.blendTest = false;
GL45.glDisable(GL45.GL_BLEND);
this.blendFuncMap = new HashMap<Integer,int[]>(); this.blendFuncMap = new HashMap<Integer,int[]>();
activeTexture = 0; activeTexture = -1;
framebufferType = 0; framebufferType = GL45.GL_FRAMEBUFFER;
framebufferPointer = 0; framebufferPointer = 0;
GL45.glBindFramebuffer(this.framebufferType, this.framebufferPointer);
activeShader = null; activeShader = null;
this.unitToPointerMap = new HashMap<Integer,Integer>(); this.unitToPointerMap = new HashMap<Integer,Integer>();
this.indexBlockMap = new HashMap<Integer,UniformBlockBinding>(); this.indexBlockMap = new HashMap<Integer,UniformBlockBinding>();

View File

@ -1,20 +1,6 @@
package electrosphere.renderer; package electrosphere.renderer;
import static electrosphere.renderer.RenderUtils.createScreenTextureVAO; import static electrosphere.renderer.RenderUtils.createScreenTextureVAO;
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR;
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR;
import static org.lwjgl.glfw.GLFW.GLFW_FALSE;
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_CORE_PROFILE;
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_PROFILE;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.glfw.GLFW.glfwMaximizeWindow;
import static org.lwjgl.glfw.GLFW.glfwPollEvents;
import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
import static org.lwjgl.glfw.GLFW.glfwTerminate;
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
@ -190,47 +176,52 @@ public class RenderingEngine {
// //
//set error callback //set error callback
// GLFWErrorCallback //
GLFW.glfwSetErrorCallback((int error, long descriptionPtr) -> { GLFW.glfwSetErrorCallback((int error, long descriptionPtr) -> {
String description = GLFWErrorCallback.getDescription(descriptionPtr); String description = GLFWErrorCallback.getDescription(descriptionPtr);
System.err.println(description); System.err.println(description);
}); });
//Initializes opengl //Initializes opengl
boolean glfwInited = glfwInit(); boolean glfwInited = GLFW.glfwInit();
if(!glfwInited){ if(!glfwInited){
String message = "Failed to initialize glfw!\n" + String message = "Failed to initialize glfw!\n" +
"Error code: " + this.getGLFWErrorMessage(this.getGLFWError()); "Error code: " + this.getGLFWErrorMessage(this.getGLFWError());
throw new IllegalStateException(message); throw new IllegalStateException(message);
} }
//Gives hints to glfw to control how opengl will be used //Gives hints to glfw to control how opengl will be used
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 5);
glslVersion = "#version 430"; glslVersion = "#version 450";
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
//headless option //headless option
if(Globals.RUN_HIDDEN){ if(Globals.RUN_HIDDEN){
glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE); GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
} }
if(!Globals.WINDOW_DECORATED){ if(!Globals.WINDOW_DECORATED){
glfwWindowHint(GLFW.GLFW_DECORATED, GLFW_FALSE); GLFW.glfwWindowHint(GLFW.GLFW_DECORATED, GLFW.GLFW_FALSE);
}
if(Globals.ENGINE_DEBUG){
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_DEBUG_CONTEXT, GLFW.GLFW_TRUE);
}
if(Globals.userSettings.getDisplayWidth() <= 0 || Globals.userSettings.getDisplayHeight() <= 0){
throw new Error("Trying to create window with width or height less than 1! " + Globals.userSettings.getDisplayWidth() + " " + Globals.userSettings.getDisplayHeight());
} }
// glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); Allows you to make the background transparent
// glfwWindowHint(GLFW_OPACITY, 23);
//Creates the window reference object //Creates the window reference object
if(Globals.userSettings.displayFullscreen() || Globals.WINDOW_FULLSCREEN){ if(Globals.userSettings.displayFullscreen() || Globals.WINDOW_FULLSCREEN){
//below line is for fullscreen //below line is for fullscreen
Globals.window = glfwCreateWindow(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, "ORPG", glfwGetPrimaryMonitor(), NULL); Globals.window = GLFW.glfwCreateWindow(Globals.userSettings.getDisplayWidth(), Globals.userSettings.getDisplayHeight(), "ORPG", GLFW.glfwGetPrimaryMonitor(), NULL);
} else { } else {
Globals.window = glfwCreateWindow(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, "ORPG", NULL, NULL); Globals.window = GLFW.glfwCreateWindow(Globals.userSettings.getDisplayWidth(), Globals.userSettings.getDisplayHeight(), "ORPG", NULL, NULL);
} }
// Errors for failure to create window (IE: No GUI mode on linux ?) // Errors for failure to create window (IE: No GUI mode on linux ?)
if (Globals.window == NULL) { if (Globals.window == NULL) {
String message = "Failed to create window!\n" + String message = "Failed to create window!\n" +
"Error code: " + this.getGLFWErrorMessage(this.getGLFWError()); "Error code: " + this.getGLFWErrorMessage(this.getGLFWError());
; ;
LoggerInterface.loggerEngine.ERROR(new Exception(message)); GLFW.glfwTerminate();
glfwTerminate(); throw new Error(message);
} }
//set resize callback //set resize callback
@ -239,9 +230,9 @@ public class RenderingEngine {
Globals.WINDOW_WIDTH = width; Globals.WINDOW_WIDTH = width;
}); });
//Makes the window that was just created the current OS-level window context //Makes the window that was just created the current OS-level window context
glfwMakeContextCurrent(Globals.window); GLFW.glfwMakeContextCurrent(Globals.window);
//Maximize it //Maximize it
glfwMaximizeWindow(Globals.window); GLFW.glfwMaximizeWindow(Globals.window);
GLFW.glfwPollEvents(); GLFW.glfwPollEvents();
//grab actual framebuffer //grab actual framebuffer
IntBuffer xBuffer = BufferUtils.createIntBuffer(1); IntBuffer xBuffer = BufferUtils.createIntBuffer(1);
@ -254,10 +245,11 @@ public class RenderingEngine {
//get title bar size //get title bar size
Globals.WINDOW_TITLE_BAR_HEIGHT = Globals.WINDOW_HEIGHT - bufferHeight; Globals.WINDOW_TITLE_BAR_HEIGHT = Globals.WINDOW_HEIGHT - bufferHeight;
// System.out.println(Globals.WINDOW_TITLE_BAR_HEIGHT);
Globals.WINDOW_WIDTH = bufferWidth; Globals.WINDOW_WIDTH = bufferWidth;
Globals.WINDOW_HEIGHT = bufferHeight; Globals.WINDOW_HEIGHT = bufferHeight;
if(bufferWidth == 0 || bufferHeight == 0){
throw new Error("Failed to get width or height! " + Globals.WINDOW_WIDTH + " " + Globals.WINDOW_HEIGHT);
}
// //
// Attach controls callbacks // Attach controls callbacks
@ -289,7 +281,7 @@ public class RenderingEngine {
imGuiPipeline = new ImGuiPipeline(Globals.window, glslVersion); imGuiPipeline = new ImGuiPipeline(Globals.window, glslVersion);
//This enables Z-buffering so that farther-back polygons are not drawn over nearer ones //This enables Z-buffering so that farther-back polygons are not drawn over nearer ones
glEnable(GL_DEPTH_TEST); openGLState.glDepthTest(true);
// Support for transparency // Support for transparency
openGLState.glBlend(true); openGLState.glBlend(true);
@ -300,6 +292,10 @@ public class RenderingEngine {
if(!Globals.userSettings.graphicsPerformanceEnableVSync()){ if(!Globals.userSettings.graphicsPerformanceEnableVSync()){
GLFW.glfwSwapInterval(0); GLFW.glfwSwapInterval(0);
} }
//clear screen
GL45.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL45.glClear(GL45.GL_COLOR_BUFFER_BIT | GL45.GL_DEPTH_BUFFER_BIT);
// //Hide the cursor and capture it // //Hide the cursor and capture it
// glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
@ -314,7 +310,6 @@ public class RenderingEngine {
//default framebuffer //default framebuffer
defaultFramebuffer = new Framebuffer(GL_DEFAULT_FRAMEBUFFER); defaultFramebuffer = new Framebuffer(GL_DEFAULT_FRAMEBUFFER);
defaultFramebuffer.bind(openGLState);
//generate framebuffers //generate framebuffers
Texture screenTextureColor = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); Texture screenTextureColor = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
@ -557,9 +552,9 @@ public class RenderingEngine {
//check and call events and swap the buffers //check and call events and swap the buffers
LoggerInterface.loggerRenderer.DEBUG_LOOP("GLFW Swap buffers"); LoggerInterface.loggerRenderer.DEBUG_LOOP("GLFW Swap buffers");
glfwSwapBuffers(Globals.window); GLFW.glfwSwapBuffers(Globals.window);
LoggerInterface.loggerRenderer.DEBUG_LOOP("GLFW Poll Events"); LoggerInterface.loggerRenderer.DEBUG_LOOP("GLFW Poll Events");
glfwPollEvents(); GLFW.glfwPollEvents();
LoggerInterface.loggerRenderer.DEBUG_LOOP("Check OpenGL Errors"); LoggerInterface.loggerRenderer.DEBUG_LOOP("Check OpenGL Errors");
checkError(); checkError();
} }
@ -668,9 +663,9 @@ public class RenderingEngine {
public static void recaptureIfNecessary(){ public static void recaptureIfNecessary(){
if(Globals.controlHandler.shouldRecapture()){ if(Globals.controlHandler.shouldRecapture()){
//Makes the window that was just created the current OS-level window context //Makes the window that was just created the current OS-level window context
glfwMakeContextCurrent(Globals.window); GLFW.glfwMakeContextCurrent(Globals.window);
// //Maximize it // //Maximize it
glfwMaximizeWindow(Globals.window); GLFW.glfwMaximizeWindow(Globals.window);
//grab focus //grab focus
GLFW.glfwFocusWindow(Globals.window); GLFW.glfwFocusWindow(Globals.window);
//apply mouse controls state //apply mouse controls state

View File

@ -13,9 +13,9 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL40; import org.lwjgl.opengl.GL40;
import org.lwjgl.opengl.GL45; import org.lwjgl.opengl.GL45;
import org.lwjgl.system.MemoryUtil;
import static org.lwjgl.opengl.GL11.GL_NONE; import static org.lwjgl.opengl.GL11.GL_NONE;
import static org.lwjgl.opengl.GL11.GL_TEXTURE; import static org.lwjgl.opengl.GL11.GL_TEXTURE;
@ -291,7 +291,7 @@ public class Framebuffer {
int type = GL40.GL_UNSIGNED_BYTE; int type = GL40.GL_UNSIGNED_BYTE;
bind(openGLState); this.bind(openGLState);
GL40.glReadBuffer(GL40.GL_COLOR_ATTACHMENT0); GL40.glReadBuffer(GL40.GL_COLOR_ATTACHMENT0);
if(this.framebufferPointer == 0){ if(this.framebufferPointer == 0){
//this is the default framebuffer, read from backbuffer because it is default //this is the default framebuffer, read from backbuffer because it is default
@ -303,11 +303,23 @@ public class Framebuffer {
} else { } else {
LoggerInterface.loggerRenderer.ERROR(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."));
} }
//error check
if(width < 1){
throw new Error("Invalid width! " + width);
}
if(height < 1){
throw new Error("Invalid height! " + height);
}
//get pixel data //get pixel data
try { try {
int bytesPerPixel = pixelFormatToBytes(pixelFormat,type); int bytesPerPixel = pixelFormatToBytes(pixelFormat,type);
int bufferSize = width * height * bytesPerPixel; int bufferSize = width * height * bytesPerPixel;
ByteBuffer buffer = MemoryUtil.memAlloc(bufferSize); ByteBuffer buffer = BufferUtils.createByteBuffer(bufferSize);
if(buffer == null || buffer.limit() < bufferSize){
throw new Error("Failed to create buffer!");
}
openGLState.glViewport(width, height); openGLState.glViewport(width, height);
GL40.glReadPixels(offsetX, offsetY, width, height, pixelFormat, type, buffer); GL40.glReadPixels(offsetX, offsetY, width, height, pixelFormat, type, buffer);
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
@ -326,8 +338,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);
} }
} }
//memory management
MemoryUtil.memFree(buffer);
} catch (OutOfMemoryError e){ } catch (OutOfMemoryError e){
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException(e.getMessage())); LoggerInterface.loggerRenderer.ERROR(new IllegalStateException(e.getMessage()));
} }

View File

@ -385,6 +385,12 @@ public class Texture {
* @param datatype The data type of a single component of a pixel (ie GL_BYTE, GL_UNSIGNED_INT, etc) * @param datatype The data type of a single component of a pixel (ie GL_BYTE, GL_UNSIGNED_INT, etc)
*/ */
public void glTexImage2D(OpenGLState openGLState, int width, int height, int format, int datatype){ public void glTexImage2D(OpenGLState openGLState, int width, int height, int format, int datatype){
if(width < 1){
throw new Error("Invalid texture width " + width);
}
if(height < 1){
throw new Error("Invalid texture height " + height);
}
//store provided values //store provided values
this.width = width; this.width = width;
this.height = height; this.height = height;
@ -420,6 +426,12 @@ public class Texture {
* @param datatype The data type of a single component of a pixel (ie GL_BYTE, GL_UNSIGNED_INT, etc) * @param datatype The data type of a single component of a pixel (ie GL_BYTE, GL_UNSIGNED_INT, etc)
*/ */
public void glTextureStorage2D(OpenGLState openGLState, int width, int height, int format, int datatype){ public void glTextureStorage2D(OpenGLState openGLState, int width, int height, int format, int datatype){
if(width < 1){
throw new Error("Invalid texture width " + width);
}
if(height < 1){
throw new Error("Invalid texture height " + height);
}
//store provided values //store provided values
this.width = width; this.width = width;
this.height = height; this.height = height;
@ -437,6 +449,12 @@ public class Texture {
* @param data The data to populate the image with * @param data The data to populate the image with
*/ */
public void glTexImage2D(OpenGLState openGLState, int width, int height, int format, int datatype, ByteBuffer data){ public void glTexImage2D(OpenGLState openGLState, int width, int height, int format, int datatype, ByteBuffer data){
if(width < 1){
throw new Error("Invalid texture width " + width);
}
if(height < 1){
throw new Error("Invalid texture height " + height);
}
//store provided values //store provided values
this.width = width; this.width = width;
this.height = height; this.height = height;
@ -461,6 +479,12 @@ public class Texture {
* @param data The data to populate the image with * @param data The data to populate the image with
*/ */
public void glTexImage2D(OpenGLState openGLState, int internalFormat, int width, int height, int format, int datatype, ByteBuffer data){ public void glTexImage2D(OpenGLState openGLState, int internalFormat, int width, int height, int format, int datatype, ByteBuffer data){
if(width < 1){
throw new Error("Invalid texture width " + width);
}
if(height < 1){
throw new Error("Invalid texture height " + height);
}
//store provided values //store provided values
this.width = width; this.width = width;
this.height = height; this.height = height;
@ -480,7 +504,7 @@ public class Texture {
* @return The width * @return The width
*/ */
public int getWidth(){ public int getWidth(){
if(pixelFormat == -1){ if(width == -1){
throw new IllegalStateException( throw new IllegalStateException(
"The width of the texture you are trying to query from has not been set yet." + "The width of the texture you are trying to query from has not been set yet." +
" The texture was likely constructed by passing the opengl texture pointer into the texture object." " The texture was likely constructed by passing the opengl texture pointer into the texture object."
@ -494,7 +518,7 @@ public class Texture {
* @return The height * @return The height
*/ */
public int getHeight(){ public int getHeight(){
if(pixelFormat == -1){ if(height == -1){
throw new IllegalStateException( throw new IllegalStateException(
"The height of the texture you are trying to query from has not been set yet." + "The height of the texture you are trying to query from has not been set yet." +
" The texture was likely constructed by passing the opengl texture pointer into the texture object." " The texture was likely constructed by passing the opengl texture pointer into the texture object."

View File

@ -0,0 +1,100 @@
package electrosphere.renderer.ui;
import static org.junit.jupiter.api.Assertions.*;
import java.io.File;
import org.junit.jupiter.api.extension.ExtendWith;
import static electrosphere.test.testutils.Assertions.*;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.menu.WindowUtils;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.test.annotations.IntegrationTest;
import electrosphere.test.template.extensions.StateCleanupCheckerExtension;
import electrosphere.test.testutils.EngineInit;
import electrosphere.test.testutils.TestEngineUtils;
import electrosphere.test.testutils.TestRenderingUtils;
/**
* Tests to verify the ui test template (we're testing our own testing framework woooooo)
*/
@ExtendWith(StateCleanupCheckerExtension.class)
public class UIExtensionTests {
@IntegrationTest
public void test_StartupShutdown_NoThrow(){
assertDoesNotThrow(() -> {
Globals.WINDOW_DECORATED = false;
Globals.WINDOW_FULLSCREEN = true;
Globals.RUN_AUDIO = false;
Globals.RUN_SCRIPTS = false;
Globals.WINDOW_WIDTH = 1920;
Globals.WINDOW_HEIGHT = 1080;
EngineInit.initGraphicalEngine();
TestEngineUtils.flush();
Main.shutdown();
});
}
@IntegrationTest
public void test_Screencapture_Match(){
Globals.WINDOW_DECORATED = false;
Globals.WINDOW_FULLSCREEN = true;
Globals.RUN_AUDIO = false;
Globals.RUN_SCRIPTS = false;
Globals.WINDOW_WIDTH = 1920;
Globals.WINDOW_HEIGHT = 1080;
EngineInit.initGraphicalEngine();
TestEngineUtils.flush();
TestEngineUtils.simulateFrames(3);
String canonicalName = this.getClass().getCanonicalName();
//check the render
assertEqualsRender("./test/java/renderer/ui/test_Screencapture_Match.png", () -> {
//on failure, save the failed render
String failureSavePath = "./.testcache/" + canonicalName + "-test_Screencapture_Match.png";
File saveFile = new File(failureSavePath);
System.err.println("[[ATTACHMENT|" + saveFile.getAbsolutePath() + "]]");
TestRenderingUtils.saveTestRender(failureSavePath);
});
Main.shutdown();
}
@IntegrationTest
public void test_Screencapture_Blank_Match(){
Globals.WINDOW_DECORATED = false;
Globals.WINDOW_FULLSCREEN = true;
Globals.RUN_AUDIO = false;
Globals.RUN_SCRIPTS = false;
Globals.WINDOW_WIDTH = 1920;
Globals.WINDOW_HEIGHT = 1080;
EngineInit.initGraphicalEngine();
TestEngineUtils.flush();
TestEngineUtils.simulateFrames(3);
WindowUtils.replaceMainMenuContents(Div.createDiv());
TestEngineUtils.flush();
TestEngineUtils.simulateFrames(2);
String canonicalName = this.getClass().getCanonicalName();
//check the render
assertEqualsRender("./test/java/renderer/ui/test_Screencapture_Blank.png", () -> {
//on failure, save the failed render
String failureSavePath = "./.testcache/" + canonicalName + "-test_Screencapture_Blank.png";
File saveFile = new File(failureSavePath);
System.err.println("[[ATTACHMENT|" + saveFile.getAbsolutePath() + "]]");
TestRenderingUtils.saveTestRender(failureSavePath);
});
Main.shutdown();
}
}

View File

@ -2,8 +2,6 @@ package electrosphere.renderer.ui.elements;
import electrosphere.test.annotations.IntegrationTest; import electrosphere.test.annotations.IntegrationTest;
import org.junit.jupiter.api.Disabled;
import electrosphere.menu.WindowUtils; import electrosphere.menu.WindowUtils;
import electrosphere.menu.mainmenu.MenuGeneratorsUITesting; import electrosphere.menu.mainmenu.MenuGeneratorsUITesting;
import electrosphere.test.template.UITestTemplate; import electrosphere.test.template.UITestTemplate;
@ -17,7 +15,6 @@ public class WindowTest extends UITestTemplate {
/** /**
* Tests creating a window * Tests creating a window
*/ */
@Disabled
@IntegrationTest @IntegrationTest
public void testCreateWindow(){ public void testCreateWindow(){
//create ui testing window //create ui testing window
@ -29,8 +26,8 @@ public class WindowTest extends UITestTemplate {
TestEngineUtils.simulateFrames(60); TestEngineUtils.simulateFrames(60);
// TestRenderingUtils.saveTestRender("./test/java/electrosphere/renderer/ui/elements/window.png"); // TestRenderingUtils.saveTestRender("./test/java/renderer/ui/elements/window.png");
this.checkRender("Basic", "./test/java/electrosphere/renderer/ui/elements/ui-test.png"); this.checkRender("Basic", "./test/java/renderer/ui/elements/ui-test.png");
} }
} }

View File

@ -5,10 +5,14 @@ import java.io.File;
import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import electrosphere.menu.WindowUtils;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.test.template.extensions.StateCleanupCheckerExtension; import electrosphere.test.template.extensions.StateCleanupCheckerExtension;
import electrosphere.test.template.extensions.UIExtension; import electrosphere.test.template.extensions.UIExtension;
import static electrosphere.test.testutils.Assertions.*; import static electrosphere.test.testutils.Assertions.*;
import electrosphere.test.testutils.TestEngineUtils;
import electrosphere.test.testutils.TestRenderingUtils; import electrosphere.test.testutils.TestRenderingUtils;
/** /**
@ -40,4 +44,13 @@ public class UITestTemplate {
}); });
} }
/**
* Sets up a blank view
*/
public void setupBlankView(){
WindowUtils.replaceMainMenuContents(Div.createDiv());
TestEngineUtils.flush();
TestEngineUtils.simulateFrames(2);
}
} }

View File

@ -19,6 +19,7 @@ public class StateCleanupCheckerExtension implements AfterEachCallback {
Globals.clientSceneWrapper, Globals.clientSceneWrapper,
Globals.clientScene, Globals.clientScene,
Globals.signalSystem, Globals.signalSystem,
Globals.threadManager,
Globals.renderingEngine, Globals.renderingEngine,
Globals.audioEngine, Globals.audioEngine,
Globals.javaPID, Globals.javaPID,
@ -35,6 +36,9 @@ public class StateCleanupCheckerExtension implements AfterEachCallback {
throw new Exception("Failed to cleanup state after test! " + object.toString()); throw new Exception("Failed to cleanup state after test! " + object.toString());
} }
} }
if(Globals.window != -1){
throw new Exception("Failed to cleanup global window pointer!");
}
} }
} }

View File

@ -7,6 +7,7 @@ import org.junit.jupiter.api.extension.ExtensionContext;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.Main; import electrosphere.engine.Main;
import electrosphere.test.testutils.EngineInit; import electrosphere.test.testutils.EngineInit;
import electrosphere.test.testutils.TestEngineUtils;
/** /**
* Spins up an tears down generic ui environment * Spins up an tears down generic ui environment
@ -18,9 +19,11 @@ public class UIExtension implements BeforeEachCallback, AfterEachCallback {
Globals.WINDOW_DECORATED = false; Globals.WINDOW_DECORATED = false;
Globals.WINDOW_FULLSCREEN = true; Globals.WINDOW_FULLSCREEN = true;
Globals.RUN_AUDIO = false; Globals.RUN_AUDIO = false;
Globals.RUN_SCRIPTS = false;
Globals.WINDOW_WIDTH = 1920; Globals.WINDOW_WIDTH = 1920;
Globals.WINDOW_HEIGHT = 1080; Globals.WINDOW_HEIGHT = 1080;
EngineInit.initGraphicalEngine(); EngineInit.initGraphicalEngine();
TestEngineUtils.flush();
} }
@Override @Override

View File

@ -10,6 +10,7 @@ import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.Main;
/** /**
* Custom assertion macros * Custom assertion macros
@ -35,6 +36,7 @@ public class Assertions {
try { try {
testData = ImageIO.read(new File(existingRenderPath)); testData = ImageIO.read(new File(existingRenderPath));
} catch (IOException e){ } catch (IOException e){
Main.shutdown();
fail("Failed to read existing image path " + existingRenderPath); fail("Failed to read existing image path " + existingRenderPath);
} }
BufferedImage screenshot = Globals.renderingEngine.defaultFramebuffer.getPixels(Globals.renderingEngine.getOpenGLState()); BufferedImage screenshot = Globals.renderingEngine.defaultFramebuffer.getPixels(Globals.renderingEngine.getOpenGLState());
@ -43,6 +45,7 @@ public class Assertions {
//width //width
if(testData.getWidth() != screenshot.getWidth()){ if(testData.getWidth() != screenshot.getWidth()){
onFailure.run(); onFailure.run();
Main.shutdown();
} }
assertEquals(testData.getWidth(), screenshot.getWidth()); assertEquals(testData.getWidth(), screenshot.getWidth());
@ -50,6 +53,7 @@ public class Assertions {
//height //height
if(testData.getHeight() != screenshot.getHeight()){ if(testData.getHeight() != screenshot.getHeight()){
onFailure.run(); onFailure.run();
Main.shutdown();
} }
assertEquals(testData.getHeight(), screenshot.getHeight()); assertEquals(testData.getHeight(), screenshot.getHeight());
@ -79,6 +83,7 @@ public class Assertions {
){ ){
onFailure.run(); onFailure.run();
Main.shutdown();
String failMessage = "Colors aren't approximately the same!\n" + String failMessage = "Colors aren't approximately the same!\n" +
"Color from disk: " + sourceRed + "," + sourceGreen + "," + sourceBlue + "," + sourceAlpha + "\n" + "Color from disk: " + sourceRed + "," + sourceGreen + "," + sourceBlue + "," + sourceAlpha + "\n" +
"Color from render: " + renderRed + "," + renderGreen + "," + renderBlue + "," + renderAlpha + "\n" "Color from render: " + renderRed + "," + renderGreen + "," + renderBlue + "," + renderAlpha + "\n"

View File

@ -114,6 +114,10 @@ public class TestEngineUtils {
} }
} }
if(frames == 0){
TestEngineUtils.simulateFrames(1);
}
while( while(
Globals.elementService.getSignalQueueCount() > 0 Globals.elementService.getSignalQueueCount() > 0
){ ){

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB