This commit is contained in:
parent
79e2fdf512
commit
a7c8571afa
@ -1,6 +1,6 @@
|
||||
@page humanprogress Human
|
||||
@page skeletonprogres Skeleton
|
||||
|
||||
Progress on the human creature
|
||||
Progress on the skeleton creature
|
||||
|
||||
## Third Person Model
|
||||
- [X] Meshed
|
||||
|
||||
@ -765,6 +765,7 @@ Fix movement packet timing bug
|
||||
Fix all items spawning above player head
|
||||
Fix items falling below terrain
|
||||
Fix gridded data cell manager saving attached items on realm save
|
||||
Fix render signals caching between frames (not reseting global flags per usual)
|
||||
|
||||
|
||||
# TODO
|
||||
|
||||
@ -240,8 +240,8 @@ public class Globals {
|
||||
//OpenGL - Other
|
||||
//
|
||||
|
||||
public static int WINDOW_WIDTH = 1920;
|
||||
public static int WINDOW_HEIGHT = 1080;
|
||||
public static int WINDOW_WIDTH;
|
||||
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_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();
|
||||
}
|
||||
//load user settings
|
||||
Globals.WINDOW_WIDTH = 1920;
|
||||
Globals.WINDOW_HEIGHT = 1080;
|
||||
UserSettings.loadUserSettings();
|
||||
//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
|
||||
textureMapDefault = TextureMap.construct("Textures/default_texture_map.json");
|
||||
//load model pretransforms
|
||||
@ -667,6 +679,7 @@ public class Globals {
|
||||
Globals.clientScene = null;
|
||||
Globals.audioEngine = null;
|
||||
Globals.renderingEngine = null;
|
||||
Globals.threadManager = null;
|
||||
Globals.signalSystem = null;
|
||||
Globals.serviceManager = null;
|
||||
Globals.clientConnection = null;
|
||||
@ -681,6 +694,7 @@ public class Globals {
|
||||
Globals.RENDER_FLAG_RENDER_UI = false;
|
||||
Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false;
|
||||
Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
|
||||
Globals.window = -1;
|
||||
LoggerInterface.destroyLoggers();
|
||||
}
|
||||
|
||||
|
||||
@ -17,18 +17,27 @@ import electrosphere.util.CodeUtils;
|
||||
public class ThreadManager {
|
||||
|
||||
//Threadsafes the manager
|
||||
Semaphore threadLock = new Semaphore(1);
|
||||
Semaphore threadLock;
|
||||
|
||||
//All threads that are actively running
|
||||
private List<LabeledThread> activeThreads = new LinkedList<LabeledThread>();
|
||||
private List<LabeledThread> activeThreads;
|
||||
|
||||
//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
|
||||
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
|
||||
|
||||
@ -20,7 +20,7 @@ import electrosphere.renderer.shader.ShaderProgram;
|
||||
public class OpenGLState {
|
||||
|
||||
//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
|
||||
int MAX_TEXTURE_WIDTH;
|
||||
@ -67,14 +67,18 @@ public class OpenGLState {
|
||||
*/
|
||||
public void init(){
|
||||
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;
|
||||
GL45.glDisable(GL45.GL_DEPTH_TEST);
|
||||
this.depthFunction = -1;
|
||||
this.blendTest = false;
|
||||
GL45.glDisable(GL45.GL_BLEND);
|
||||
this.blendFuncMap = new HashMap<Integer,int[]>();
|
||||
activeTexture = 0;
|
||||
framebufferType = 0;
|
||||
activeTexture = -1;
|
||||
framebufferType = GL45.GL_FRAMEBUFFER;
|
||||
framebufferPointer = 0;
|
||||
GL45.glBindFramebuffer(this.framebufferType, this.framebufferPointer);
|
||||
activeShader = null;
|
||||
this.unitToPointerMap = new HashMap<Integer,Integer>();
|
||||
this.indexBlockMap = new HashMap<Integer,UniformBlockBinding>();
|
||||
|
||||
@ -1,20 +1,6 @@
|
||||
package electrosphere.renderer;
|
||||
|
||||
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_DEPTH_TEST;
|
||||
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
|
||||
@ -190,47 +176,52 @@ public class RenderingEngine {
|
||||
|
||||
//
|
||||
//set error callback
|
||||
// GLFWErrorCallback
|
||||
//
|
||||
GLFW.glfwSetErrorCallback((int error, long descriptionPtr) -> {
|
||||
String description = GLFWErrorCallback.getDescription(descriptionPtr);
|
||||
System.err.println(description);
|
||||
});
|
||||
|
||||
//Initializes opengl
|
||||
boolean glfwInited = glfwInit();
|
||||
boolean glfwInited = GLFW.glfwInit();
|
||||
if(!glfwInited){
|
||||
String message = "Failed to initialize glfw!\n" +
|
||||
"Error code: " + this.getGLFWErrorMessage(this.getGLFWError());
|
||||
throw new IllegalStateException(message);
|
||||
}
|
||||
//Gives hints to glfw to control how opengl will be used
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glslVersion = "#version 430";
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 5);
|
||||
glslVersion = "#version 450";
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
|
||||
//headless option
|
||||
if(Globals.RUN_HIDDEN){
|
||||
glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
|
||||
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
|
||||
}
|
||||
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
|
||||
if(Globals.userSettings.displayFullscreen() || Globals.WINDOW_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 {
|
||||
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 ?)
|
||||
if (Globals.window == NULL) {
|
||||
String message = "Failed to create window!\n" +
|
||||
"Error code: " + this.getGLFWErrorMessage(this.getGLFWError());
|
||||
;
|
||||
LoggerInterface.loggerEngine.ERROR(new Exception(message));
|
||||
glfwTerminate();
|
||||
GLFW.glfwTerminate();
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
//set resize callback
|
||||
@ -239,9 +230,9 @@ public class RenderingEngine {
|
||||
Globals.WINDOW_WIDTH = width;
|
||||
});
|
||||
//Makes the window that was just created the current OS-level window context
|
||||
glfwMakeContextCurrent(Globals.window);
|
||||
GLFW.glfwMakeContextCurrent(Globals.window);
|
||||
//Maximize it
|
||||
glfwMaximizeWindow(Globals.window);
|
||||
GLFW.glfwMaximizeWindow(Globals.window);
|
||||
GLFW.glfwPollEvents();
|
||||
//grab actual framebuffer
|
||||
IntBuffer xBuffer = BufferUtils.createIntBuffer(1);
|
||||
@ -254,10 +245,11 @@ public class RenderingEngine {
|
||||
//get title bar size
|
||||
Globals.WINDOW_TITLE_BAR_HEIGHT = Globals.WINDOW_HEIGHT - bufferHeight;
|
||||
|
||||
// System.out.println(Globals.WINDOW_TITLE_BAR_HEIGHT);
|
||||
|
||||
Globals.WINDOW_WIDTH = bufferWidth;
|
||||
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
|
||||
@ -289,7 +281,7 @@ public class RenderingEngine {
|
||||
imGuiPipeline = new ImGuiPipeline(Globals.window, glslVersion);
|
||||
|
||||
//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
|
||||
openGLState.glBlend(true);
|
||||
@ -300,6 +292,10 @@ public class RenderingEngine {
|
||||
if(!Globals.userSettings.graphicsPerformanceEnableVSync()){
|
||||
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
|
||||
// glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
@ -314,7 +310,6 @@ public class RenderingEngine {
|
||||
|
||||
//default framebuffer
|
||||
defaultFramebuffer = new Framebuffer(GL_DEFAULT_FRAMEBUFFER);
|
||||
defaultFramebuffer.bind(openGLState);
|
||||
|
||||
//generate framebuffers
|
||||
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
|
||||
LoggerInterface.loggerRenderer.DEBUG_LOOP("GLFW Swap buffers");
|
||||
glfwSwapBuffers(Globals.window);
|
||||
GLFW.glfwSwapBuffers(Globals.window);
|
||||
LoggerInterface.loggerRenderer.DEBUG_LOOP("GLFW Poll Events");
|
||||
glfwPollEvents();
|
||||
GLFW.glfwPollEvents();
|
||||
LoggerInterface.loggerRenderer.DEBUG_LOOP("Check OpenGL Errors");
|
||||
checkError();
|
||||
}
|
||||
@ -668,9 +663,9 @@ public class RenderingEngine {
|
||||
public static void recaptureIfNecessary(){
|
||||
if(Globals.controlHandler.shouldRecapture()){
|
||||
//Makes the window that was just created the current OS-level window context
|
||||
glfwMakeContextCurrent(Globals.window);
|
||||
GLFW.glfwMakeContextCurrent(Globals.window);
|
||||
// //Maximize it
|
||||
glfwMaximizeWindow(Globals.window);
|
||||
GLFW.glfwMaximizeWindow(Globals.window);
|
||||
//grab focus
|
||||
GLFW.glfwFocusWindow(Globals.window);
|
||||
//apply mouse controls state
|
||||
|
||||
@ -13,9 +13,9 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL40;
|
||||
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_TEXTURE;
|
||||
@ -291,7 +291,7 @@ public class Framebuffer {
|
||||
int type = GL40.GL_UNSIGNED_BYTE;
|
||||
|
||||
|
||||
bind(openGLState);
|
||||
this.bind(openGLState);
|
||||
GL40.glReadBuffer(GL40.GL_COLOR_ATTACHMENT0);
|
||||
if(this.framebufferPointer == 0){
|
||||
//this is the default framebuffer, read from backbuffer because it is default
|
||||
@ -303,11 +303,23 @@ public class Framebuffer {
|
||||
} else {
|
||||
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
|
||||
try {
|
||||
int bytesPerPixel = pixelFormatToBytes(pixelFormat,type);
|
||||
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);
|
||||
GL40.glReadPixels(offsetX, offsetY, width, height, pixelFormat, type, buffer);
|
||||
Globals.renderingEngine.checkError();
|
||||
@ -326,8 +338,6 @@ public class Framebuffer {
|
||||
rVal.setRGB(x, height - (y + 1), (alpha << 24) | (red << 16) | (green << 8) | blue);
|
||||
}
|
||||
}
|
||||
//memory management
|
||||
MemoryUtil.memFree(buffer);
|
||||
} catch (OutOfMemoryError e){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException(e.getMessage()));
|
||||
}
|
||||
|
||||
@ -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)
|
||||
*/
|
||||
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
|
||||
this.width = width;
|
||||
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)
|
||||
*/
|
||||
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
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
@ -437,6 +449,12 @@ public class Texture {
|
||||
* @param data The data to populate the image with
|
||||
*/
|
||||
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
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
@ -461,6 +479,12 @@ public class Texture {
|
||||
* @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){
|
||||
if(width < 1){
|
||||
throw new Error("Invalid texture width " + width);
|
||||
}
|
||||
if(height < 1){
|
||||
throw new Error("Invalid texture height " + height);
|
||||
}
|
||||
//store provided values
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
@ -480,7 +504,7 @@ public class Texture {
|
||||
* @return The width
|
||||
*/
|
||||
public int getWidth(){
|
||||
if(pixelFormat == -1){
|
||||
if(width == -1){
|
||||
throw new IllegalStateException(
|
||||
"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."
|
||||
@ -494,7 +518,7 @@ public class Texture {
|
||||
* @return The height
|
||||
*/
|
||||
public int getHeight(){
|
||||
if(pixelFormat == -1){
|
||||
if(height == -1){
|
||||
throw new IllegalStateException(
|
||||
"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."
|
||||
|
||||
100
src/test/java/electrosphere/renderer/ui/UIExtensionTests.java
Normal file
100
src/test/java/electrosphere/renderer/ui/UIExtensionTests.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,8 +2,6 @@ package electrosphere.renderer.ui.elements;
|
||||
|
||||
import electrosphere.test.annotations.IntegrationTest;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
||||
import electrosphere.menu.WindowUtils;
|
||||
import electrosphere.menu.mainmenu.MenuGeneratorsUITesting;
|
||||
import electrosphere.test.template.UITestTemplate;
|
||||
@ -17,7 +15,6 @@ public class WindowTest extends UITestTemplate {
|
||||
/**
|
||||
* Tests creating a window
|
||||
*/
|
||||
@Disabled
|
||||
@IntegrationTest
|
||||
public void testCreateWindow(){
|
||||
//create ui testing window
|
||||
@ -29,8 +26,8 @@ public class WindowTest extends UITestTemplate {
|
||||
|
||||
TestEngineUtils.simulateFrames(60);
|
||||
|
||||
// TestRenderingUtils.saveTestRender("./test/java/electrosphere/renderer/ui/elements/window.png");
|
||||
this.checkRender("Basic", "./test/java/electrosphere/renderer/ui/elements/ui-test.png");
|
||||
// TestRenderingUtils.saveTestRender("./test/java/renderer/ui/elements/window.png");
|
||||
this.checkRender("Basic", "./test/java/renderer/ui/elements/ui-test.png");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,10 +5,14 @@ import java.io.File;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
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.UIExtension;
|
||||
|
||||
import static electrosphere.test.testutils.Assertions.*;
|
||||
|
||||
import electrosphere.test.testutils.TestEngineUtils;
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ public class StateCleanupCheckerExtension implements AfterEachCallback {
|
||||
Globals.clientSceneWrapper,
|
||||
Globals.clientScene,
|
||||
Globals.signalSystem,
|
||||
Globals.threadManager,
|
||||
Globals.renderingEngine,
|
||||
Globals.audioEngine,
|
||||
Globals.javaPID,
|
||||
@ -35,6 +36,9 @@ public class StateCleanupCheckerExtension implements AfterEachCallback {
|
||||
throw new Exception("Failed to cleanup state after test! " + object.toString());
|
||||
}
|
||||
}
|
||||
if(Globals.window != -1){
|
||||
throw new Exception("Failed to cleanup global window pointer!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.Main;
|
||||
import electrosphere.test.testutils.EngineInit;
|
||||
import electrosphere.test.testutils.TestEngineUtils;
|
||||
|
||||
/**
|
||||
* Spins up an tears down generic ui environment
|
||||
@ -18,9 +19,11 @@ public class UIExtension implements BeforeEachCallback, AfterEachCallback {
|
||||
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();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -10,6 +10,7 @@ import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.Main;
|
||||
|
||||
/**
|
||||
* Custom assertion macros
|
||||
@ -35,6 +36,7 @@ public class Assertions {
|
||||
try {
|
||||
testData = ImageIO.read(new File(existingRenderPath));
|
||||
} catch (IOException e){
|
||||
Main.shutdown();
|
||||
fail("Failed to read existing image path " + existingRenderPath);
|
||||
}
|
||||
BufferedImage screenshot = Globals.renderingEngine.defaultFramebuffer.getPixels(Globals.renderingEngine.getOpenGLState());
|
||||
@ -43,6 +45,7 @@ public class Assertions {
|
||||
//width
|
||||
if(testData.getWidth() != screenshot.getWidth()){
|
||||
onFailure.run();
|
||||
Main.shutdown();
|
||||
}
|
||||
assertEquals(testData.getWidth(), screenshot.getWidth());
|
||||
|
||||
@ -50,6 +53,7 @@ public class Assertions {
|
||||
//height
|
||||
if(testData.getHeight() != screenshot.getHeight()){
|
||||
onFailure.run();
|
||||
Main.shutdown();
|
||||
}
|
||||
assertEquals(testData.getHeight(), screenshot.getHeight());
|
||||
|
||||
@ -79,6 +83,7 @@ public class Assertions {
|
||||
){
|
||||
|
||||
onFailure.run();
|
||||
Main.shutdown();
|
||||
String failMessage = "Colors aren't approximately the same!\n" +
|
||||
"Color from disk: " + sourceRed + "," + sourceGreen + "," + sourceBlue + "," + sourceAlpha + "\n" +
|
||||
"Color from render: " + renderRed + "," + renderGreen + "," + renderBlue + "," + renderAlpha + "\n"
|
||||
|
||||
@ -114,6 +114,10 @@ public class TestEngineUtils {
|
||||
}
|
||||
}
|
||||
|
||||
if(frames == 0){
|
||||
TestEngineUtils.simulateFrames(1);
|
||||
}
|
||||
|
||||
while(
|
||||
Globals.elementService.getSignalQueueCount() > 0
|
||||
){
|
||||
|
||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
BIN
test/java/renderer/ui/test_Screencapture_Blank.png
Normal file
BIN
test/java/renderer/ui/test_Screencapture_Blank.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
BIN
test/java/renderer/ui/test_Screencapture_Match.png
Normal file
BIN
test/java/renderer/ui/test_Screencapture_Match.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
Loading…
Reference in New Issue
Block a user