diff --git a/buildNumber.properties b/buildNumber.properties
index cbe49a67..f1df9a01 100644
--- a/buildNumber.properties
+++ b/buildNumber.properties
@@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file
-#Wed Sep 04 09:33:29 EDT 2024
-buildNumber=320
+#Sun Sep 08 21:41:56 EDT 2024
+buildNumber=325
diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md
index d1ede71e..8db04bec 100644
--- a/docs/src/progress/renderertodo.md
+++ b/docs/src/progress/renderertodo.md
@@ -693,6 +693,16 @@ Update human collidable data
(09/05/2024)
Fix AI tracking deleted entity
+(09/06/2024)
+work on debugging framebuffer bug
+
+(09/07/2024)
+par_shapes integration
+
+(09/08/2024)
+Directed graph datastructure
+Framebuffer + RenderingEngine tests
+
# TODO
diff --git a/pom.xml b/pom.xml
index b8683460..23653a4a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -125,6 +125,20 @@
${lwjgl.version}
${lwjgl.natives}
+
+
+
+
+ org.lwjgl
+ lwjgl-par
+ ${lwjgl.version}
+
+
+ org.lwjgl
+ lwjgl-par
+ ${lwjgl.version}
+ ${lwjgl.natives}
+
diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java
index 718189a5..7c1e0522 100644
--- a/src/main/java/electrosphere/engine/Globals.java
+++ b/src/main/java/electrosphere/engine/Globals.java
@@ -602,13 +602,9 @@ public class Globals {
//init fluid shader program
FluidChunkModelGeneration.fluidChunkShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/entities/fluid2/fluid2.vs", "/Shaders/entities/fluid2/fluid2.fs");
//init models
- assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere.glb");
- assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere.fbx");
- assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_1.fbx");
- assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_grey.fbx");
+ assetManager.registerModelToSpecificString(RenderUtils.createUnitsphere(), AssetDataStrings.UNITSPHERE);
+ assetManager.registerModelToSpecificString(RenderUtils.createUnitCylinder(), AssetDataStrings.UNITCYLINDER);
assetManager.addModelPathToQueue("Models/basic/geometry/SmallCube.fbx");
- assetManager.addModelPathToQueue("Models/basic/geometry/unitcylinder.fbx");
- assetManager.addModelPathToQueue("Models/basic/geometry/unitcylinder.glb");
assetManager.addModelPathToQueue("Models/basic/geometry/unitcapsule.glb");
assetManager.addModelPathToQueue("Models/basic/geometry/unitplane.fbx");
assetManager.addModelPathToQueue("Models/basic/geometry/unitcube.fbx");
@@ -673,6 +669,12 @@ public class Globals {
Globals.server = null;
Globals.serverSynchronizationManager = null;
Globals.javaPID = null;
+ Globals.RENDER_FLAG_RENDER_SHADOW_MAP = true;
+ Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = false;
+ Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = false;
+ Globals.RENDER_FLAG_RENDER_UI = false;
+ Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false;
+ Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
LoggerInterface.destroyLoggers();
}
diff --git a/src/main/java/electrosphere/engine/Main.java b/src/main/java/electrosphere/engine/Main.java
index aae16c1a..70c7149f 100644
--- a/src/main/java/electrosphere/engine/Main.java
+++ b/src/main/java/electrosphere/engine/Main.java
@@ -156,7 +156,7 @@ public class Main {
Globals.controlHandler.hintUpdateControlState(ControlsState.TITLE_MENU);
//start initial asset loading
- Globals.threadManager.start(ThreadLabel.ASSET_LOADING, new Thread(Globals.initialAssetLoadingThread));
+ Globals.threadManager.start(new LoadingThread(LoadingThreadType.INIT_ASSETS));
}
//Sets a hook that fires when the engine process stops
@@ -434,8 +434,6 @@ public class Main {
//
//Terminate the program.
if(Globals.renderingEngine != null){
- glfwTerminate();
- Globals.renderingEngine.clearGlobalState();
Globals.renderingEngine.destroy();
}
//used to signal threads to stop
diff --git a/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java b/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java
index 921e7003..97e9b5ac 100644
--- a/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java
+++ b/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java
@@ -8,4 +8,12 @@ public class AssetDataStrings {
public static final String ASSET_STRING_SKYBOX_BASIC = "skyboxBasic";
public static final String BITMAP_CHARACTER_MODEL = "bitmapCharacterModel";
public static final String LEAVES_MODEL = "leaves";
+
+ /**
+ * The basic geometry of the engine
+ */
+ public static final String UNITSPHERE = "unitSphere";
+ public static final String UNITCYLINDER = "unitCylinder";
+
+
}
diff --git a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java
index 383ab5f8..d74ced6b 100644
--- a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java
+++ b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java
@@ -11,6 +11,7 @@ import electrosphere.client.targeting.crosshair.Crosshair;
import electrosphere.client.terrain.cells.DrawCellManager;
import electrosphere.controls.ControlHandler;
import electrosphere.engine.Globals;
+import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.engine.threads.LabeledThread.ThreadLabel;
import electrosphere.entity.DrawableUtils;
@@ -244,7 +245,7 @@ public class ClientLoading {
//player's cursor
Globals.playerCursor = EntityCreationUtils.createClientSpatialEntity();
- EntityCreationUtils.makeEntityDrawable(Globals.playerCursor, "Models/basic/geometry/unitsphere_1.fbx");
+ EntityCreationUtils.makeEntityDrawable(Globals.playerCursor, AssetDataStrings.UNITSPHERE);
DrawableUtils.makeEntityTransparent(Globals.playerCursor);
EntityUtils.getScale(Globals.playerCursor).set(30f);
}
@@ -257,7 +258,7 @@ public class ClientLoading {
*/
static void initDrawCellManager(boolean blockForInit){
int iterations = 0;
- while(blockForInit && (Globals.clientWorldData == null || Globals.initialAssetLoadingThread.isLoading())){
+ while(blockForInit && (Globals.clientWorldData == null || InitialAssetLoading.atlasQueuedTexture == null || !InitialAssetLoading.atlasQueuedTexture.hasLoaded())){
try {
TimeUnit.MILLISECONDS.sleep(10);
iterations++;
@@ -267,7 +268,7 @@ public class ClientLoading {
if(iterations > MAX_DRAW_CELL_WAIT){
String message = "Draw cell took too long to init!\n" +
Globals.clientWorldData + "\n" +
- Globals.initialAssetLoadingThread.isLoading();
+ InitialAssetLoading.atlasQueuedTexture.hasLoaded();
throw new IllegalStateException(message);
}
}
diff --git a/src/main/java/electrosphere/engine/loadingthreads/InitialAssetLoading.java b/src/main/java/electrosphere/engine/loadingthreads/InitialAssetLoading.java
index e65871d1..dffff3ae 100644
--- a/src/main/java/electrosphere/engine/loadingthreads/InitialAssetLoading.java
+++ b/src/main/java/electrosphere/engine/loadingthreads/InitialAssetLoading.java
@@ -21,35 +21,27 @@ import electrosphere.util.FileUtils;
* - Texture Atlas for terrain
* - Icons for items
*/
-public class InitialAssetLoading implements Runnable {
-
- //tracks whether this thread is still doing work or not
- boolean loading = true;
+public class InitialAssetLoading {
+ /**
+ * The queued atlas texture
+ */
+ static QueuedTexture atlasQueuedTexture = null;
+
/**
* Loads basic data
*/
- public void LoadData(){
-
+ protected static void loadData(){
loadTextureAtlas();
LoggerInterface.loggerEngine.INFO("Finished loading texture atlas");
-
- loading = false;
- }
- /**
- * Gets whether the thread is still loading or not
- * @return true if loading, false otherwise
- */
- public boolean isLoading(){
- return loading;
}
/**
* Loads the texture atlas
*/
- private void loadTextureAtlas(){
+ private static void loadTextureAtlas(){
//terrain texture atlas
Globals.profiler.beginCpuSample("createVoxelTextureAtlas");
VoxelData data = Globals.gameConfigCurrent.getVoxelData();
@@ -78,7 +70,7 @@ public class InitialAssetLoading implements Runnable {
Globals.profiler.endCpuSample();
//queue to asset manager
- QueuedTexture atlasQueuedTexture = new QueuedTexture(image);
+ atlasQueuedTexture = new QueuedTexture(image);
Globals.assetManager.queuedAsset(atlasQueuedTexture);
@@ -97,10 +89,12 @@ public class InitialAssetLoading implements Runnable {
Globals.voxelTextureAtlas.setNormal(atlasQueuedTexture.getTexture());
}
- @Override
- public void run(){
- this.LoadData();
+ /**
+ * Gets the queued texture
+ */
+ protected static QueuedTexture getQueuedTexture(){
+ return atlasQueuedTexture;
}
-
+
}
diff --git a/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java b/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java
index 25a91c3d..5dae7f1d 100644
--- a/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java
+++ b/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java
@@ -65,6 +65,11 @@ public class LoadingThread extends Thread {
*/
LOAD_VIEWPORT,
+ /**
+ * Loads initial assets
+ */
+ INIT_ASSETS,
+
}
/**
@@ -152,6 +157,11 @@ public class LoadingThread extends Thread {
case LOAD_VIEWPORT: {
ViewportLoading.loadViewport(params);
} break;
+
+ //Load the initial assets
+ case INIT_ASSETS: {
+ InitialAssetLoading.loadData();
+ } break;
}
}
diff --git a/src/main/java/electrosphere/engine/profiler/Profiler.java b/src/main/java/electrosphere/engine/profiler/Profiler.java
index d74a289a..3d4822f2 100644
--- a/src/main/java/electrosphere/engine/profiler/Profiler.java
+++ b/src/main/java/electrosphere/engine/profiler/Profiler.java
@@ -10,7 +10,8 @@ import org.lwjgl.util.remotery.Remotery;
public class Profiler {
//controls whether to profile or not
- public static boolean PROFILE = true;
+ //!!WARNING!!: when this is turned on, testing can behave weirdly!! IE GET STUCK!
+ public static boolean PROFILE = false;
//pointer to the global instance
long pointer = -1;
diff --git a/src/main/java/electrosphere/engine/threads/ThreadManager.java b/src/main/java/electrosphere/engine/threads/ThreadManager.java
index 9f40ee37..4d643f33 100644
--- a/src/main/java/electrosphere/engine/threads/ThreadManager.java
+++ b/src/main/java/electrosphere/engine/threads/ThreadManager.java
@@ -111,8 +111,7 @@ public class ThreadManager {
if(thread.getThread().isAlive()){
String errorMessage = "Failed to interrupt thread! " + thread.getLabel();
System.err.println(errorMessage);
- new IllegalStateException().printStackTrace();
- System.exit(1);
+ throw new IllegalStateException();
}
} catch (InterruptedException e) {
CodeUtils.todo(e, "Think about how to handle this");
diff --git a/src/main/java/electrosphere/renderer/OpenGLState.java b/src/main/java/electrosphere/renderer/OpenGLState.java
index eacd4e36..8ff45a65 100644
--- a/src/main/java/electrosphere/renderer/OpenGLState.java
+++ b/src/main/java/electrosphere/renderer/OpenGLState.java
@@ -21,44 +21,62 @@ public class OpenGLState {
private static final boolean DISABLE_CACHING = false;
//the max texture allowed by the current environment
- int MAX_TEXTURE_WIDTH = 0;
+ int MAX_TEXTURE_WIDTH;
//the current viewport dimensions
- private Vector2i viewport = new Vector2i(0,0);
+ private Vector2i viewport;
//whether depth test is enabled or not
- boolean depthTest = false;
+ boolean depthTest;
//the current depth function
- int depthFunction = -1;
+ int depthFunction;
//whether to blend or nit
- boolean blendTest = false;
+ boolean blendTest;
//the current blend func
//map is (texture unit) -> [sfactor,dfactor]
- Map blendFuncMap = new HashMap();
+ Map blendFuncMap;
//the key that contains the value of glBlendFunc (which would affect all buffers)
static final int ALL_BUFFERS_KEY = -1;
//the currently active texture
- int activeTexture = 0;
+ int activeTexture;
//the currently bound framebuffer
- int framebufferType = 0;
- int framebufferPointer = 0;
+ int framebufferType;
+ int framebufferPointer;
//active shader
- ShaderProgram activeShader = null;
+ ShaderProgram activeShader;
//map of texture units and their corresponding texture pointers
- Map unitToPointerMap = new HashMap();
+ Map unitToPointerMap;
+ /**
+ * Initializes the opengl state
+ */
+ public void init(){
+ this.MAX_TEXTURE_WIDTH = 0;
+ this.viewport = new Vector2i(0,0);
+ this.depthTest = false;
+ this.depthFunction = -1;
+ this.blendTest = false;
+ this.blendFuncMap = new HashMap();
+ activeTexture = 0;
+ framebufferType = 0;
+ framebufferPointer = 0;
+ activeShader = null;
+ unitToPointerMap = new HashMap();
+ this.storeCurrentEnvironmentContraints();
+ }
+
/**
* Gets the constraints of the current environment (ie how large can the max texture be)
*/
- public void storeCurrentEnvironmentContraints(){
+ private void storeCurrentEnvironmentContraints(){
//the array used to store values fetched from opengl
int[] intFetchArray = new int[1];
@@ -67,6 +85,9 @@ public class OpenGLState {
GL40.glGetIntegerv(GL40.GL_MAX_TEXTURE_SIZE, intFetchArray);
MAX_TEXTURE_WIDTH = intFetchArray[0];
+ //get current framebuffer data
+ GL40.glGetIntegerv(GL40.GL_DRAW_FRAMEBUFFER_BINDING, intFetchArray);
+ this.framebufferPointer = intFetchArray[0];
}
@@ -153,6 +174,21 @@ public class OpenGLState {
}
}
+ /**
+ * Binds a texture to a given texture unit if the texture hasn't already been bound to that unit
+ * @param textureUnit The texture unit
+ * @param texturePointer The texture pointer
+ * @param textureType the type of texture (2d, 3d, etc)
+ */
+ public void glBindTextureUnitForce(int textureUnit, int texturePointer, int textureType){
+ unitToPointerMap.put(textureUnit,texturePointer);
+ this.activeTexture = textureUnit;
+ GL40.glActiveTexture(this.activeTexture);
+ Globals.renderingEngine.checkError();
+ GL40.glBindTexture(textureType,texturePointer);
+ Globals.renderingEngine.checkError();
+ }
+
/**
* Binds a framebuffer
* @param framebufferType the type of framebuffer (vanilla, renderbuffer, etc)
diff --git a/src/main/java/electrosphere/renderer/RenderUtils.java b/src/main/java/electrosphere/renderer/RenderUtils.java
index 5dbcbd70..98e6e020 100644
--- a/src/main/java/electrosphere/renderer/RenderUtils.java
+++ b/src/main/java/electrosphere/renderer/RenderUtils.java
@@ -20,6 +20,8 @@ import org.lwjgl.BufferUtils;
import static org.lwjgl.opengl.GL11.GL_FLOAT;
import org.lwjgl.opengl.GL40;
+import org.lwjgl.util.par.ParShapes;
+import org.lwjgl.util.par.ParShapesMesh;
/**
* Utilities to assist with rendering
@@ -339,6 +341,64 @@ public class RenderUtils {
return rVal;
}
+ /**
+ * Generates a unit sphere model
+ * @return The model
+ */
+ public static Model createUnitsphere(){
+ Model model = new Model();
+ Mesh sphereMesh = new Mesh("sphere");
+ sphereMesh.generateVAO();
+
+ //buffer coords
+ ParShapesMesh data = ParShapes.par_shapes_create_parametric_sphere(10, 5);
+ int numPoints = data.npoints();
+ FloatBuffer verts = data.points(numPoints * 3);
+ sphereMesh.bufferVertices(verts, 3);
+ FloatBuffer texCoords = data.tcoords(numPoints * 3);
+ sphereMesh.bufferTextureCoords(texCoords, 2);
+
+ //setup extra structures
+ Material mat = new Material();
+ mat.set_diffuse("Textures/color/transparent_teal.png");
+ sphereMesh.setMaterial(mat);
+ sphereMesh.setShader(ShaderProgram.smart_assemble_shader(false, true));
+ GL40.glBindVertexArray(0);
+ sphereMesh.setParent(model);
+ model.getMeshes().add(sphereMesh);
+
+ return model;
+ }
+
+ /**
+ * Creates a unit cylinder model
+ * @return The model
+ */
+ public static Model createUnitCylinder(){
+ Model model = new Model();
+ Mesh sphereMesh = new Mesh("cylinder");
+ sphereMesh.generateVAO();
+
+ //buffer coords
+ ParShapesMesh data = ParShapes.par_shapes_create_cylinder(10, 2);
+ int numPoints = data.npoints();
+ FloatBuffer verts = data.points(numPoints * 3);
+ sphereMesh.bufferVertices(verts, 3);
+ FloatBuffer texCoords = data.tcoords(numPoints * 2);
+ sphereMesh.bufferTextureCoords(texCoords, 2);
+
+ //setup extra structures
+ Material mat = new Material();
+ mat.set_diffuse("Textures/color/transparent_teal.png");
+ sphereMesh.setMaterial(mat);
+ sphereMesh.setShader(ShaderProgram.smart_assemble_shader(false, true));
+ GL40.glBindVertexArray(0);
+ sphereMesh.setParent(model);
+ model.getMeshes().add(sphereMesh);
+
+ return model;
+ }
+
@Deprecated
public static Model createBitmapDisplay(){
diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java
index 36d18a9a..2c1f3bf9 100644
--- a/src/main/java/electrosphere/renderer/RenderingEngine.java
+++ b/src/main/java/electrosphere/renderer/RenderingEngine.java
@@ -38,6 +38,10 @@ import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL30;
+import org.lwjgl.opengl.GL45;
+import org.lwjgl.opengl.GLCapabilities;
+import org.lwjgl.opengl.GLDebugMessageCallback;
+import org.lwjgl.system.MemoryStack;
import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface;
@@ -186,12 +190,18 @@ public class RenderingEngine {
//
//set error callback
- GLFW.glfwSetErrorCallback(GLFWErrorCallback.createThrow());
+ // GLFWErrorCallback
+ GLFW.glfwSetErrorCallback((int error, long descriptionPtr) -> {
+ String description = GLFWErrorCallback.getDescription(descriptionPtr);
+ System.err.println(description);
+ });
//Initializes opengl
boolean glfwInited = glfwInit();
if(!glfwInited){
- throw new IllegalStateException("Failed to initialize glfw!");
+ 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);
@@ -216,9 +226,13 @@ public class RenderingEngine {
}
// Errors for failure to create window (IE: No GUI mode on linux ?)
if (Globals.window == NULL) {
- LoggerInterface.loggerEngine.ERROR("Failed to make window.", new Exception("Renderer Creation Failure"));
+ String message = "Failed to create window!\n" +
+ "Error code: " + this.getGLFWErrorMessage(this.getGLFWError());
+ ;
+ LoggerInterface.loggerEngine.ERROR(new Exception(message));
glfwTerminate();
}
+
//set resize callback
GLFW.glfwSetWindowSizeCallback(Globals.window, (long window, int width, int height) -> {
Globals.WINDOW_HEIGHT = height;
@@ -228,6 +242,7 @@ public class RenderingEngine {
glfwMakeContextCurrent(Globals.window);
//Maximize it
glfwMaximizeWindow(Globals.window);
+ GLFW.glfwPollEvents();
//grab actual framebuffer
IntBuffer xBuffer = BufferUtils.createIntBuffer(1);
IntBuffer yBuffer = BufferUtils.createIntBuffer(1);
@@ -255,11 +270,20 @@ public class RenderingEngine {
//get title bar dimensions
// setTitleBarDimensions();
- //Creates the OpenGL capabilities for the program.
- GL.createCapabilities();
+ //Creates the OpenGL capabilities for the program.)
+ GLCapabilities glCapabilities = GL.createCapabilities();
+
+ GL45.glEnable(GL45.GL_DEBUG_OUTPUT);
+ //register error callback
+ GL45.glDebugMessageCallback((int source, int type, int id, int severity, int length, long messagePtr, long userParam) -> {
+ if(type == GL45.GL_DEBUG_TYPE_ERROR){
+ String message = GLDebugMessageCallback.getMessage(length, messagePtr);
+ System.err.println(message);
+ }
+ }, bufferHeight);
//get environment constraints
- openGLState.storeCurrentEnvironmentContraints();
+ openGLState.init();
//init imgui pipeline
imGuiPipeline = new ImGuiPipeline(Globals.window, glslVersion);
@@ -290,11 +314,20 @@ public class RenderingEngine {
//default framebuffer
defaultFramebuffer = new Framebuffer(GL_DEFAULT_FRAMEBUFFER);
+ defaultFramebuffer.bind(openGLState);
//generate framebuffers
- screenTextureColor = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
- screenTextureDepth = FramebufferUtils.generateScreenTextureDepth(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
- screenFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, screenTextureColor, screenTextureDepth);
+ Texture screenTextureColor = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
+ RenderingEngine.screenTextureColor = screenTextureColor;
+ Texture screenTextureDepth = FramebufferUtils.generateScreenTextureDepth(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
+ RenderingEngine.screenTextureDepth = screenTextureDepth;
+ try {
+ Framebuffer screenFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, screenTextureColor, screenTextureDepth);
+ RenderingEngine.screenFramebuffer = screenFramebuffer;
+ } catch (Exception e){
+ LoggerInterface.loggerRenderer.ERROR(e);
+ }
+
defaultFramebuffer.bind(openGLState);
glBindRenderbuffer(GL_RENDERBUFFER, GL_DEFAULT_RENDERBUFFER);
Globals.renderingEngine.checkError();
@@ -309,18 +342,28 @@ public class RenderingEngine {
//
lightDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/core/lightDepth/lightDepth.vs", "/Shaders/core/lightDepth/lightDepth.fs");
Globals.depthMapShaderProgramLoc = lightDepthShaderProgram.getShaderId();
- lightDepthBuffer = FramebufferUtils.generateDepthBuffer(openGLState);
- lightBufferDepthTexture = lightDepthBuffer.getDepthTexture();
+ try {
+ Framebuffer lightDepthBuffer = FramebufferUtils.generateDepthBuffer(openGLState);
+ RenderingEngine.lightDepthBuffer = lightDepthBuffer;
+ } catch(Exception e){
+ LoggerInterface.loggerRenderer.ERROR(e);
+ }
+ Texture lightBufferDepthTexture = lightDepthBuffer.getDepthTexture();
+ RenderingEngine.lightBufferDepthTexture = lightBufferDepthTexture;
// glEnable(GL_CULL_FACE); // enabled for shadow mapping
//
//create volume depth framebuffer/shader for volumetric rendering
//
- volumeDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/core/volumeBuffer/volumetric.vs", "/Shaders/core/volumeBuffer/volumetric.fs");
- volumeDepthBackfaceTexture = FramebufferUtils.generateDepthBufferTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
- volumeDepthBackfaceFramebuffer = FramebufferUtils.generateDepthBuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), volumeDepthBackfaceTexture);
- volumeDepthFrontfaceTexture = FramebufferUtils.generateDepthBufferTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
- volumeDepthFrontfaceFramebuffer = FramebufferUtils.generateDepthBuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), volumeDepthFrontfaceTexture);
+ try {
+ volumeDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/core/volumeBuffer/volumetric.vs", "/Shaders/core/volumeBuffer/volumetric.fs");
+ volumeDepthBackfaceTexture = FramebufferUtils.generateDepthBufferTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
+ volumeDepthBackfaceFramebuffer = FramebufferUtils.generateDepthBuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), volumeDepthBackfaceTexture);
+ volumeDepthFrontfaceTexture = FramebufferUtils.generateDepthBufferTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
+ volumeDepthFrontfaceFramebuffer = FramebufferUtils.generateDepthBuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), volumeDepthFrontfaceTexture);
+ } catch(Exception e){
+ LoggerInterface.loggerRenderer.ERROR(e);
+ }
//
//Game normals
@@ -330,20 +373,28 @@ public class RenderingEngine {
static Framebuffer gameImageNormalsFramebuffer;
static ShaderProgram renderNormalsShader;
*/
- gameImageNormalsTexture = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
- Texture gameImageNormalsDepthTexture = FramebufferUtils.generateScreenTextureDepth(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
- gameImageNormalsFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), gameImageNormalsTexture, gameImageNormalsDepthTexture);
- renderNormalsShader = ShaderProgram.loadSpecificShader("Shaders/core/anime/renderNormals.vs", "Shaders/core/anime/renderNormals.fs");
+ try {
+ gameImageNormalsTexture = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
+ Texture gameImageNormalsDepthTexture = FramebufferUtils.generateScreenTextureDepth(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
+ gameImageNormalsFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), gameImageNormalsTexture, gameImageNormalsDepthTexture);
+ renderNormalsShader = ShaderProgram.loadSpecificShader("Shaders/core/anime/renderNormals.vs", "Shaders/core/anime/renderNormals.fs");
+ } catch(Exception e){
+ LoggerInterface.loggerRenderer.ERROR(e);
+ }
//
//Transparency framebuffers
//
- transparencyAccumulatorClear = new float[]{0.0f, 0.0f, 0.0f, 0.0f};
- transparencyAccumulatorTexture = FramebufferUtils.generateOITAccumulatorTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
- transparencyRevealageClear = new float[]{1.0f, 1.0f, 1.0f, 1.0f};
- transparencyRevealageTexture = FramebufferUtils.generateOITRevealageTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
- transparencyBuffer = FramebufferUtils.generateOITFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), transparencyAccumulatorTexture, transparencyRevealageTexture, screenTextureDepth);
- oitCompositeProgram = ShaderProgram.loadSpecificShader("Shaders/core/oit/composite.vs", "Shaders/core/oit/composite.fs");
+ try {
+ transparencyAccumulatorClear = new float[]{0.0f, 0.0f, 0.0f, 0.0f};
+ transparencyAccumulatorTexture = FramebufferUtils.generateOITAccumulatorTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
+ transparencyRevealageClear = new float[]{1.0f, 1.0f, 1.0f, 1.0f};
+ transparencyRevealageTexture = FramebufferUtils.generateOITRevealageTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
+ transparencyBuffer = FramebufferUtils.generateOITFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), transparencyAccumulatorTexture, transparencyRevealageTexture, screenTextureDepth);
+ oitCompositeProgram = ShaderProgram.loadSpecificShader("Shaders/core/oit/composite.vs", "Shaders/core/oit/composite.fs");
+ } catch(Exception e){
+ LoggerInterface.loggerRenderer.ERROR(e);
+ }
//projection matrices
nearVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.1f, 100);
@@ -356,10 +407,14 @@ public class RenderingEngine {
static Framebuffer normalsOutlineFrambuffer;
static ShaderProgram normalsOutlineShader;
*/
- normalsOutlineTexture = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
- normalsOutlineFrambuffer = FramebufferUtils.generateScreenTextureFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), normalsOutlineTexture);
- // normalsOutlineShader = ShaderProgram.loadSpecificShader("Shaders/anime/outlineNormals.vs", "Shaders/anime/outlineNormals.fs");
- Globals.assetManager.addShaderToQueue("Shaders/core/anime/outlineNormals.vs", "Shaders/core/anime/outlineNormals.fs");
+ try {
+ normalsOutlineTexture = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
+ normalsOutlineFrambuffer = FramebufferUtils.generateScreenTextureFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), normalsOutlineTexture);
+ // normalsOutlineShader = ShaderProgram.loadSpecificShader("Shaders/anime/outlineNormals.vs", "Shaders/anime/outlineNormals.fs");
+ Globals.assetManager.addShaderToQueue("Shaders/core/anime/outlineNormals.vs", "Shaders/core/anime/outlineNormals.fs");
+ } catch(Exception e){
+ LoggerInterface.loggerRenderer.ERROR(e);
+ }
//
//Compositing shaders
@@ -409,15 +464,6 @@ public class RenderingEngine {
Globals.projectionMatrix.setPerspective(verticalFOV, Globals.aspectRatio, nearClip, Globals.userSettings.getGraphicsViewDistance());
Globals.viewMatrix.translation(new Vector3f(0.0f,0.0f,-3.0f));
}
-
- /**
- * Clears global, static state
- */
- public void clearGlobalState(){
- screenTextureColor = null;
- screenTextureDepth = null;
- screenFramebuffer = null;
- }
/**
@@ -637,7 +683,7 @@ public class RenderingEngine {
public boolean checkError(){
int error = this.getError();
if(error != GL11.GL_NO_ERROR){
- LoggerInterface.loggerRenderer.ERROR("checkError - " + getErrorInEnglish(error), new IllegalStateException("OpenGL Error"));
+ LoggerInterface.loggerRenderer.ERROR("checkError - " + getErrorInEnglish(error), new Exception("OpenGL Error"));
return true;
}
return false;
@@ -656,6 +702,34 @@ public class RenderingEngine {
return lastCode;
}
+ /**
+ * Gets the most recent GLFW Error
+ * @return The most recent GLFW error
+ */
+ public int getGLFWError(){
+ int lastCode = 0;
+ try (MemoryStack stack = MemoryStack.stackPush()){
+ lastCode = GLFW.glfwGetError(stack.callocPointer(1));
+ }
+ return lastCode;
+ }
+
+ /**
+ * Decodes the glfw error code
+ * @param code The code
+ * @return The decoded message
+ */
+ public String getGLFWErrorMessage(int code){
+ switch(code){
+ case GLFW.GLFW_INVALID_ENUM:
+ return "GLFW_INVALID_ENUM";
+ case GLFW.GLFW_INVALID_VALUE:
+ return "GLFW_INVALID_VALUE";
+ default:
+ return "Unhandled value!";
+ }
+ }
+
/**
* Checks if pipelines should run
* @return true if should render, false otherwise
@@ -671,7 +745,83 @@ public class RenderingEngine {
* Destroys the rendering engine
*/
public void destroy(){
+
+ //free framebuffers
+ if(screenFramebuffer != null){
+ screenFramebuffer.free();
+ }
+ if(screenRenderbuffer != null){
+ screenRenderbuffer.free();
+ }
+ if(gameImageNormalsFramebuffer != null){
+ gameImageNormalsFramebuffer.free();
+ }
+ if(lightDepthBuffer != null){
+ lightDepthBuffer.free();
+ }
+ if(transparencyBuffer != null){
+ transparencyBuffer.free();
+ }
+ if(volumeDepthBackfaceFramebuffer != null){
+ volumeDepthBackfaceFramebuffer.free();
+ }
+ if(volumeDepthFrontfaceFramebuffer != null){
+ volumeDepthFrontfaceFramebuffer.free();
+ }
+ if(normalsOutlineFrambuffer != null){
+ normalsOutlineFrambuffer.free();
+ }
+
+ //null out
+ screenFramebuffer = null;
+ screenRenderbuffer = null;
+ gameImageNormalsFramebuffer = null;
+ lightDepthBuffer = null;
+ transparencyBuffer = null;
+ volumeDepthBackfaceFramebuffer = null;
+ volumeDepthFrontfaceFramebuffer = null;
+ normalsOutlineFrambuffer = null;
+
+
+ //free textures
+ if(screenTextureColor != null){
+ screenTextureColor.free();
+ }
+ if(screenTextureDepth != null){
+ screenTextureDepth.free();
+ }
+ if(gameImageNormalsTexture != null){
+ gameImageNormalsTexture.free();
+ }
+ if(lightBufferDepthTexture != null){
+ lightBufferDepthTexture.free();
+ }
+ if(transparencyRevealageTexture != null){
+ transparencyRevealageTexture.free();
+ }
+ if(volumeDepthBackfaceTexture != null){
+ volumeDepthBackfaceTexture.free();
+ }
+ if(volumeDepthFrontfaceTexture != null){
+ volumeDepthFrontfaceTexture.free();
+ }
+ if(normalsOutlineTexture != null){
+ normalsOutlineTexture.free();
+ }
+ //null out
+ screenTextureColor = null;
+ screenTextureDepth = null;
+ gameImageNormalsTexture = null;
+ lightBufferDepthTexture = null;
+ transparencyRevealageTexture = null;
+ volumeDepthBackfaceTexture = null;
+ volumeDepthFrontfaceTexture = null;
+ normalsOutlineTexture = null;
+
+ //end glfw
+ GLFW.glfwDestroyWindow(Globals.window);
+ GLFW.glfwTerminate();
}
/**
diff --git a/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java b/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java
index 371b4d1d..22f1f560 100644
--- a/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java
+++ b/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java
@@ -14,8 +14,12 @@ import java.util.Map;
import java.util.concurrent.TimeUnit;
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;
+import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
import static org.lwjgl.opengl.GL45.glCheckNamedFramebufferStatus;
/**
@@ -91,29 +95,47 @@ public class Framebuffer {
* Checks if the framebuffer compiled correctly
* @return true if compiled correctly, false otherwise
*/
- public boolean isComplete(){
- return glCheckNamedFramebufferStatus(framebufferPointer,GL40.GL_FRAMEBUFFER) == GL40.GL_FRAMEBUFFER_COMPLETE;
+ public boolean isComplete(OpenGLState openGLState){
+ if(this.framebufferPointer == DEFAULT_FRAMEBUFFER_POINTER){
+ throw new Error("Pointer is the default framebuffer!");
+ }
+ return glCheckNamedFramebufferStatus(this.framebufferPointer,GL40.GL_FRAMEBUFFER) == GL40.GL_FRAMEBUFFER_COMPLETE;
}
- /**
- * Checks if the framebuffer has an error
- * @return true if error, false otherwise
- */
- public boolean isError(){
- return glCheckNamedFramebufferStatus(framebufferPointer,GL40.GL_FRAMEBUFFER) == 0;
- }
/**
* Checks the status of the framebuffer
+ * @param openGLState The opengl state
+ * @throws Exception
*/
- public void checkStatus(){
- if(this.isError()){
- LoggerInterface.loggerRenderer.WARNING("Framebuffer [glError] - " + RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError()));
- LoggerInterface.loggerRenderer.WARNING("Framebuffer [status] - " + this.getStatus());
- } else if(!this.isComplete()){
- LoggerInterface.loggerRenderer.WARNING("Framebuffer [glError] - " + RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError()));
- LoggerInterface.loggerRenderer.WARNING("Framebuffer [status] - " + this.getStatus());
- LoggerInterface.loggerRenderer.ERROR("Failed to build framebuffer", new IllegalStateException("Framebuffer failed to build."));
+ public void shouldBeComplete(OpenGLState openGLState) throws Exception{
+ if(!this.isComplete(openGLState)){
+ int colorAttach0 = GL45.glGetFramebufferAttachmentParameteri(GL_FRAMEBUFFER, GL45.GL_COLOR_ATTACHMENT0, GL45.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ String attach0Type = "";
+ switch(colorAttach0){
+ case GL_NONE: {
+ attach0Type = "GL_NONE";
+ } break;
+ case GL_TEXTURE: {
+ attach0Type = " GL_TEXTURE";
+ } break;
+ }
+ this.texture.bind(openGLState);
+ int[] storage = new int[1];
+ int width = 0;
+ int height = 0;
+ GL45.glGetTexLevelParameteriv(GL45.GL_TEXTURE_2D, 0, GL45.GL_TEXTURE_WIDTH, storage);
+ width = storage[0];
+ GL45.glGetTexLevelParameteriv(GL45.GL_TEXTURE_2D, 0, GL45.GL_TEXTURE_HEIGHT, storage);
+ height = storage[0];
+ String message = "Framebuffer failed to build.\n" +
+ "Framebuffer [status] - " + this.getStatus() + "\n" +
+ "Texture: " + this.texture + "\n" +
+ "attach0Type: " + attach0Type + "\n" +
+ "attach0 Dims: " + width + "," + height + "\n" +
+ "Depth: " + this.depthTexture + "\n"
+ ;
+ throw new Exception(message);
}
}
@@ -136,7 +158,7 @@ public class Framebuffer {
* Blocks the thread until the framebuffer has compiled
*/
public void blockUntilCompiled(){
- while(glCheckNamedFramebufferStatus(framebufferPointer,GL40.GL_FRAMEBUFFER) != GL40.GL_FRAMEBUFFER_UNDEFINED){
+ while(glCheckNamedFramebufferStatus(this.framebufferPointer,GL40.GL_FRAMEBUFFER) != GL40.GL_FRAMEBUFFER_UNDEFINED){
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException ex) {
@@ -150,7 +172,7 @@ public class Framebuffer {
* @return The status
*/
public String getStatus(){
- switch(glCheckNamedFramebufferStatus(framebufferPointer,GL40.GL_FRAMEBUFFER)){
+ switch(glCheckNamedFramebufferStatus(this.framebufferPointer,GL40.GL_FRAMEBUFFER)){
case GL40.GL_FRAMEBUFFER_UNDEFINED: {
return "The specified framebuffer is the default read or draw framebuffer, but the default framebuffer does not exist.";
}
@@ -220,6 +242,15 @@ public class Framebuffer {
openGLState.glBindFramebuffer(GL40.GL_FRAMEBUFFER, this.framebufferPointer);
GL40.glFramebufferTexture2D(GL40.GL_FRAMEBUFFER, GL40.GL_COLOR_ATTACHMENT0 + attachmentNum, GL40.GL_TEXTURE_2D, texture.getTexturePointer(), 0);
Globals.renderingEngine.checkError();
+ // check the attachment slot
+ int colorAttach0 = GL45.glGetFramebufferAttachmentParameteri(GL40.GL_FRAMEBUFFER, GL45.GL_COLOR_ATTACHMENT0 + attachmentNum, GL45.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ switch(colorAttach0){
+ case GL_NONE: {
+ throw new Error("Failed to attach!");
+ }
+ case GL_TEXTURE: {
+ } break;
+ }
Globals.renderingEngine.defaultFramebuffer.bind(openGLState);
}
diff --git a/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java b/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java
index 5f7fd18c..5899a8ac 100644
--- a/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java
+++ b/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java
@@ -9,6 +9,7 @@ import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL40;
+import org.lwjgl.opengl.GL45;
import static org.lwjgl.opengl.GL11.GL_DEPTH_COMPONENT;
import static org.lwjgl.opengl.GL11.GL_FLOAT;
@@ -46,6 +47,7 @@ public class FramebufferUtils {
public static Texture generateScreenTextureColor(OpenGLState openGLState, int width, int height){
Texture texture = new Texture();
+ texture.bind(openGLState);
texture.glTexImage2D(openGLState, width, height, GL_RGB, GL_UNSIGNED_BYTE);
texture.setMinFilter(openGLState, GL_LINEAR);
texture.setMagFilter(openGLState, GL_LINEAR);
@@ -64,7 +66,8 @@ public class FramebufferUtils {
public static Texture generateScreenTextureColorAlpha(OpenGLState openGLState, int width, int height){
Texture texture = new Texture();
- texture.glTexImage2D(openGLState, width, height, GL_RGBA, GL_UNSIGNED_BYTE);
+ texture.bind(openGLState);
+ texture.glTexImage2D(openGLState, width, height, GL_RGBA, GL45.GL_UNSIGNED_INT_8_8_8_8);
texture.setMinFilter(openGLState, GL_LINEAR);
texture.setMagFilter(openGLState, GL_LINEAR);
//these make sure the texture actually clamps to the borders of the quad
@@ -74,7 +77,7 @@ public class FramebufferUtils {
//guarantees that the texture object has actually been created (calling gen buffers does not guarantee object creation)
texture.bind(openGLState);
- openGLState.glBindTexture(GL40.GL_TEXTURE_2D, Texture.DEFAULT_TEXTURE);
+ openGLState.glBindTextureUnitForce(GL45.GL_TEXTURE0, Texture.DEFAULT_TEXTURE, GL40.GL_TEXTURE_2D);
texture.checkStatus(openGLState);
return texture;
@@ -82,6 +85,7 @@ public class FramebufferUtils {
public static Texture generateScreenTextureDepth(OpenGLState openGLState, int width, int height){
Texture texture = new Texture();
+ texture.bind(openGLState);
texture.glTexImage2D(openGLState, width, height, GL_DEPTH_COMPONENT, GL_FLOAT);
texture.setMinFilter(openGLState, GL_LINEAR);
@@ -93,36 +97,37 @@ public class FramebufferUtils {
//guarantees that the texture object has actually been created (calling gen buffers does not guarantee object creation)
texture.bind(openGLState);
- openGLState.glBindTexture(GL40.GL_TEXTURE_2D, Texture.DEFAULT_TEXTURE);
+ openGLState.glBindTextureUnitForce(GL45.GL_TEXTURE0, Texture.DEFAULT_TEXTURE, GL40.GL_TEXTURE_2D);
texture.checkStatus(openGLState);
return texture;
}
- public static Framebuffer generateScreenTextureFramebuffer(OpenGLState openGLState, int width, int height, Texture colorTexture, Texture depthTexture){
+ public static Framebuffer generateScreenTextureFramebuffer(OpenGLState openGLState, int width, int height, Texture colorTexture, Texture depthTexture) throws Exception {
Framebuffer buffer = new Framebuffer();
//bind texture to fbo
buffer.setMipMapLevel(0);
buffer.attachTexture(openGLState,colorTexture);
buffer.setDepthAttachment(openGLState,depthTexture);
+ buffer.bind(openGLState);
//check make sure compiled
- buffer.checkStatus();
+ buffer.shouldBeComplete(openGLState);
Globals.renderingEngine.defaultFramebuffer.bind(openGLState);
return buffer;
}
- public static Framebuffer generateScreenTextureFramebuffer(OpenGLState openGLState, int width, int height, Texture colorTexture){
+ public static Framebuffer generateScreenTextureFramebuffer(OpenGLState openGLState, int width, int height, Texture colorTexture) throws Exception {
Framebuffer buffer = new Framebuffer();
//bind texture to fbo
buffer.setMipMapLevel(0);
buffer.attachTexture(openGLState,colorTexture);
//check make sure compiled
- buffer.checkStatus();
+ buffer.shouldBeComplete(openGLState);
return buffer;
}
- public static Framebuffer generateScreensizeTextureFramebuffer(OpenGLState openGLState){
+ public static Framebuffer generateScreensizeTextureFramebuffer(OpenGLState openGLState) throws Exception {
Framebuffer buffer = new Framebuffer();
buffer.bind(openGLState);
//texture
@@ -147,12 +152,12 @@ public class FramebufferUtils {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);
Globals.renderingEngine.checkError();
//check make sure compiled
- buffer.checkStatus();
+ buffer.shouldBeComplete(openGLState);
Globals.renderingEngine.defaultFramebuffer.bind(openGLState);
return buffer;
}
- public static Framebuffer generateTextureFramebuffer(OpenGLState openGLState, int width, int height){
+ public static Framebuffer generateTextureFramebuffer(OpenGLState openGLState, int width, int height) throws Exception {
Framebuffer buffer = new Framebuffer();
buffer.bind(openGLState);
//texture
@@ -178,7 +183,7 @@ public class FramebufferUtils {
GL40.glFramebufferRenderbuffer(GL40.GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);
Globals.renderingEngine.checkError();
//check make sure compiled
- buffer.checkStatus();
+ buffer.shouldBeComplete(openGLState);
//re-bind default buffer
Globals.renderingEngine.defaultFramebuffer.bind(openGLState);
return buffer;
@@ -197,7 +202,7 @@ public class FramebufferUtils {
}
- public static Framebuffer generateDepthBuffer(OpenGLState openGLState){
+ public static Framebuffer generateDepthBuffer(OpenGLState openGLState) throws Exception {
Framebuffer buffer = new Framebuffer();
buffer.bind(openGLState);
@@ -223,7 +228,7 @@ public class FramebufferUtils {
//check make sure compiled
- buffer.checkStatus();
+ buffer.shouldBeComplete(openGLState);
Globals.renderingEngine.defaultFramebuffer.bind(openGLState);
return buffer;
}
@@ -241,7 +246,7 @@ public class FramebufferUtils {
return texture;
}
- public static Framebuffer generateDepthBuffer(OpenGLState openGLState, int width, int height, Texture texture){
+ public static Framebuffer generateDepthBuffer(OpenGLState openGLState, int width, int height, Texture texture) throws Exception {
Framebuffer buffer = new Framebuffer();
buffer.bind(openGLState);
@@ -257,7 +262,7 @@ public class FramebufferUtils {
//check make sure compiled
- buffer.checkStatus();
+ buffer.shouldBeComplete(openGLState);
Globals.renderingEngine.defaultFramebuffer.bind(openGLState);
return buffer;
}
@@ -280,7 +285,7 @@ public class FramebufferUtils {
return texture;
}
- public static Framebuffer generateOITFramebuffer(OpenGLState openGLState, int width, int height, Texture accumulatorTex, Texture revealageTex, Texture depthTexture){
+ public static Framebuffer generateOITFramebuffer(OpenGLState openGLState, int width, int height, Texture accumulatorTex, Texture revealageTex, Texture depthTexture) throws Exception {
Framebuffer buffer = new Framebuffer();
buffer.bind(openGLState);
@@ -301,7 +306,7 @@ public class FramebufferUtils {
Globals.renderingEngine.checkError();
//check make sure compiled
- buffer.checkStatus();
+ buffer.shouldBeComplete(openGLState);
Globals.renderingEngine.defaultFramebuffer.bind(openGLState);
return buffer;
}
diff --git a/src/main/java/electrosphere/renderer/pipelines/debug/DebugBonesPipeline.java b/src/main/java/electrosphere/renderer/pipelines/debug/DebugBonesPipeline.java
index c699d208..0ea79ff9 100644
--- a/src/main/java/electrosphere/renderer/pipelines/debug/DebugBonesPipeline.java
+++ b/src/main/java/electrosphere/renderer/pipelines/debug/DebugBonesPipeline.java
@@ -7,6 +7,7 @@ import org.joml.Vector3f;
import org.lwjgl.opengl.GL40;
import electrosphere.engine.Globals;
+import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.camera.CameraEntityUtils;
@@ -68,7 +69,7 @@ public class DebugBonesPipeline implements RenderPipeline {
//Get target data
//
Actor targetActor = EntityUtils.getActor(targetEntity);
- Model boneModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitcylinder.fbx");
+ Model boneModel = Globals.assetManager.fetchModel(AssetDataStrings.UNITCYLINDER);
boneModel.getMaterials().get(0).set_diffuse(Globals.textureDiffuseDefault);
for(Bone bone : targetActor.getBoneValues()){
Vector3d bonePos = MathBones.getBoneWorldPosition(targetEntity, bone.boneID);
diff --git a/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java
index 37947f84..c0ab8724 100644
--- a/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java
+++ b/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java
@@ -13,6 +13,7 @@ import org.ode4j.ode.DSphere;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
+import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
@@ -78,7 +79,7 @@ public class DebugContentPipeline implements RenderPipeline {
if(geom instanceof DSphere){
DSphere sphereView = (DSphere)geom;
HitboxState shapeStatus = hitboxState.getShapeStatus(geom);
- if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere.glb")) != null){
+ if((hitboxModel = Globals.assetManager.fetchModel(AssetDataStrings.UNITSPHERE)) != null){
//set color based on collision status, type, etc
Texture texture = Globals.assetManager.fetchTexture(getHitboxColor(shapeStatus,shapeStatus.getHitboxData()));
if(texture != null){
@@ -133,7 +134,7 @@ public class DebugContentPipeline implements RenderPipeline {
if(geom instanceof DSphere){
DSphere sphereView = (DSphere)geom;
HitboxState shapeStatus = hitboxState.getShapeStatus(geom);
- if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere.glb")) != null){
+ if((hitboxModel = Globals.assetManager.fetchModel(AssetDataStrings.UNITSPHERE)) != null){
//set color based on collision status, type, etc
Texture texture = Globals.assetManager.fetchTexture(getHitboxColor(shapeStatus,shapeStatus.getHitboxData()));
if(texture != null){
diff --git a/src/main/java/electrosphere/renderer/texture/Texture.java b/src/main/java/electrosphere/renderer/texture/Texture.java
index df0c659f..92f943a3 100644
--- a/src/main/java/electrosphere/renderer/texture/Texture.java
+++ b/src/main/java/electrosphere/renderer/texture/Texture.java
@@ -390,13 +390,27 @@ public class Texture {
this.height = height;
this.pixelFormat = format;
this.datatype = datatype;
+ int internalFormat = format;
+ if(internalFormat == GL45.GL_DEPTH_COMPONENT){
+ internalFormat = GL45.GL_DEPTH_COMPONENT24;
+ }
//static values going into call
int level = 0;
int border = 0; //this must be 0 according to docs
openGLState.glBindTexture(GL_TEXTURE_2D,texturePointer);
Globals.renderingEngine.checkError();
- GL40.glTexImage2D(GL_TEXTURE_2D, level, format, width, height, border, format, datatype, MemoryUtil.NULL);
+ GL40.glTexImage2D(GL_TEXTURE_2D, level, internalFormat, width, height, border, format, datatype, MemoryUtil.NULL);
Globals.renderingEngine.checkError();
+ int[] storage = new int[1];
+ int discoveredWidth = 0;
+ int discoveredHeight = 0;
+ GL45.glGetTexLevelParameteriv(GL45.GL_TEXTURE_2D, 0, GL45.GL_TEXTURE_WIDTH, storage);
+ discoveredWidth = storage[0];
+ GL45.glGetTexLevelParameteriv(GL45.GL_TEXTURE_2D, 0, GL45.GL_TEXTURE_HEIGHT, storage);
+ discoveredHeight = storage[0];
+ if(width != discoveredWidth || height != discoveredHeight){
+ throw new Error("Found dims aren't the same! " + width + "," + height + " vs " + discoveredWidth + "," + discoveredHeight);
+ }
}
/**
@@ -528,6 +542,13 @@ public class Texture {
}
}
+ /**
+ * Frees the texture
+ */
+ public void free(){
+ GL40.glDeleteTextures(this.texturePointer);
+ }
+
@Override
public String toString(){
String rVal = "" +
diff --git a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java
index 9a5f023f..ec8630ff 100644
--- a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java
+++ b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java
@@ -58,7 +58,11 @@ public class ActorPanel extends StandardElement implements DrawableElement, Drag
public ActorPanel(OpenGLState openGLState, int x, int y, int width, int height, Actor actor){
super();
- elementBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
+ try {
+ elementBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
+ } catch(Exception e){
+ LoggerInterface.loggerRenderer.ERROR(e);
+ }
customMat.setTexturePointer(elementBuffer.getTexture().getTexturePointer());
this.actor = actor;
this.internalPositionX = x;
diff --git a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java
index e35cdb3c..a4ac508f 100644
--- a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java
+++ b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java
@@ -37,7 +37,11 @@ public class ScrollableContainer extends StandardContainerElement implements Dra
public ScrollableContainer(OpenGLState openGLState, int positionX, int positionY, int width, int height){
super();
- widgetBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
+ try {
+ widgetBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
+ } catch(Exception e){
+ LoggerInterface.loggerRenderer.ERROR(e);
+ }
// widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer();
customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer());
// customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer());
diff --git a/src/main/java/electrosphere/renderer/ui/elements/Window.java b/src/main/java/electrosphere/renderer/ui/elements/Window.java
index fc7f89df..daf54db8 100644
--- a/src/main/java/electrosphere/renderer/ui/elements/Window.java
+++ b/src/main/java/electrosphere/renderer/ui/elements/Window.java
@@ -71,7 +71,11 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
* @param height
*/
public Window(OpenGLState openGLState, int positionX, int positionY, int width, int height, boolean showDecorations){
- widgetBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
+ try {
+ widgetBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
+ } catch(Exception e){
+ LoggerInterface.loggerRenderer.ERROR(e);
+ }
customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer());
float ndcWidth = (float)width/Globals.WINDOW_WIDTH;
float ndcHeight = (float)height/Globals.WINDOW_HEIGHT;
diff --git a/src/main/java/electrosphere/server/gen/DungeonGen.java b/src/main/java/electrosphere/server/gen/DungeonGen.java
new file mode 100644
index 00000000..80dd9c6c
--- /dev/null
+++ b/src/main/java/electrosphere/server/gen/DungeonGen.java
@@ -0,0 +1,10 @@
+package electrosphere.server.gen;
+
+/**
+ * Generates dungeons
+ */
+public class DungeonGen {
+
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/electrosphere/util/ds/DirectedGraph.java b/src/main/java/electrosphere/util/ds/DirectedGraph.java
new file mode 100644
index 00000000..4384d9bc
--- /dev/null
+++ b/src/main/java/electrosphere/util/ds/DirectedGraph.java
@@ -0,0 +1,161 @@
+package electrosphere.util.ds;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A directed graph
+ */
+public class DirectedGraph {
+
+ /**
+ * The list of nodes in the graph
+ */
+ List nodes;
+
+ /**
+ * Constructor
+ */
+ public DirectedGraph(){
+ this.nodes = new LinkedList();
+ }
+
+ /**
+ * Creates a node in the graph
+ * @param data The data in the node
+ * @return The node
+ */
+ public GraphNode createNode(Object data){
+ GraphNode rVal = new GraphNode();
+ this.nodes.add(rVal);
+ return rVal;
+ }
+
+ /**
+ * Adds direction as a neighbor of source. Does not create a connection from direction to source
+ * @param source The source node
+ * @param direction The destination node
+ */
+ public void pointNode(GraphNode source, GraphNode direction){
+ if(!source.containsNeighbor(direction)){
+ source.addNeighbor(direction);
+ }
+ }
+
+ /**
+ * Mutually connects two nodes
+ * @param node1 Node 1
+ * @param node2 Node 2
+ */
+ public void connectNodes(GraphNode node1, GraphNode node2){
+ if(!node1.containsNeighbor(node2)){
+ node1.addNeighbor(node2);
+ }
+ if(!node2.containsNeighbor(node1)){
+ node2.addNeighbor(node1);
+ }
+ }
+
+ /**
+ * Destroys a node
+ * @param node The node to destroy
+ */
+ public void destroyNode(GraphNode node){
+ for(GraphNode toEval : this.nodes){
+ if(toEval != node){
+ if(toEval.containsNeighbor(node)){
+ toEval.removeNeighbor(node);
+ }
+ }
+ }
+ this.nodes.remove(node);
+ }
+
+ /**
+ * Gets the nodes in the graph
+ * @return The list of all nodes in the graph
+ */
+ public List getNodes(){
+ return Collections.unmodifiableList(this.nodes);
+ }
+
+
+
+ /**
+ * A node in a graph
+ */
+ public static class GraphNode {
+
+ /**
+ * The data at the node
+ */
+ Object data;
+
+ /**
+ * The neighbors of this graph node
+ */
+ List neighbors;
+
+ /**
+ * Creates a graph node
+ * @param data The data to put in the node
+ */
+ public GraphNode(Object data){
+ this.data = data;
+ this.neighbors = new LinkedList();
+ }
+
+ /**
+ * Creates an empty graph node
+ */
+ public GraphNode(){
+ this.data = null;
+ this.neighbors = new LinkedList();
+ }
+
+ /**
+ * Gets the data at this node
+ * @return The data
+ */
+ public Object getData(){
+ return this.data;
+ }
+
+ /**
+ * Gets the neighbors of this node
+ * @return The list of neighbors
+ */
+ public List getNeighbors(){
+ return this.neighbors;
+ }
+
+ /**
+ * Adds a neighbor to this node
+ * @param neighbor The neighbor
+ */
+ public void addNeighbor(GraphNode neighbor){
+ this.neighbors.add(neighbor);
+ }
+
+ /**
+ * Removes a neighbor from this node
+ * @param neighbor THe neighbor
+ */
+ public void removeNeighbor(GraphNode neighbor){
+ this.neighbors.remove(neighbor);
+ }
+
+ /**
+ * Checks if this node contains a given node as a neighbor
+ * @param node The potential neighbor to check
+ * @return true if the node is a neighbor, false otherwise
+ */
+ public boolean containsNeighbor(GraphNode node){
+ return this.neighbors.contains(node);
+ }
+
+ }
+
+
+}
diff --git a/src/test/java/electrosphere/engine/StartupExtensionTests.java b/src/test/java/electrosphere/engine/StartupExtensionTests.java
new file mode 100644
index 00000000..fef796b5
--- /dev/null
+++ b/src/test/java/electrosphere/engine/StartupExtensionTests.java
@@ -0,0 +1,38 @@
+package electrosphere.engine;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import electrosphere.test.annotations.IntegrationTest;
+import electrosphere.test.template.extensions.EntityExtension;
+import electrosphere.test.template.extensions.StateCleanupCheckerExtension;
+
+/**
+ * Tests for startup extensions
+ */
+@ExtendWith(StateCleanupCheckerExtension.class)
+public class StartupExtensionTests {
+
+ @IntegrationTest
+ public void test_EntityExtension_Startup(){
+ assertDoesNotThrow(() -> {
+ EntityExtension ext = new EntityExtension();
+ ext.beforeEach(null);
+ ext.afterEach(null);
+ });
+ }
+
+ @IntegrationTest
+ public void test_EntityExtension_RepeatStartup(){
+ assertDoesNotThrow(() -> {
+ EntityExtension ext = new EntityExtension();
+ int someNumberOfTests = 3;
+ for(int i = 0; i < someNumberOfTests; i++){
+ ext.beforeEach(null);
+ ext.afterEach(null);
+ }
+ });
+ }
+
+}
diff --git a/src/test/java/electrosphere/renderer/RenderingEngineTests.java b/src/test/java/electrosphere/renderer/RenderingEngineTests.java
new file mode 100644
index 00000000..fa55bd58
--- /dev/null
+++ b/src/test/java/electrosphere/renderer/RenderingEngineTests.java
@@ -0,0 +1,30 @@
+package electrosphere.renderer;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import electrosphere.engine.Globals;
+import electrosphere.test.template.extensions.StateCleanupCheckerExtension;
+
+/**
+ * Tests for the core rendering engine
+ */
+@ExtendWith(StateCleanupCheckerExtension.class)
+public class RenderingEngineTests {
+
+ @Test
+ public void testRenderingEngineResetsAllState(){
+ assertDoesNotThrow(() -> {
+ for(int i = 0; i < 5; i++){
+ Globals.initGlobals();
+ Globals.renderingEngine = new RenderingEngine();
+ Globals.renderingEngine.createOpenglContext();
+ Globals.renderingEngine.destroy();
+ Globals.resetGlobals();
+ }
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/electrosphere/renderer/framebuffer/FramebufferUtilsTests.java b/src/test/java/electrosphere/renderer/framebuffer/FramebufferUtilsTests.java
new file mode 100644
index 00000000..f873d14e
--- /dev/null
+++ b/src/test/java/electrosphere/renderer/framebuffer/FramebufferUtilsTests.java
@@ -0,0 +1,59 @@
+package electrosphere.renderer.framebuffer;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import electrosphere.engine.Globals;
+import electrosphere.renderer.RenderingEngine;
+import electrosphere.renderer.texture.Texture;
+import electrosphere.test.template.extensions.StateCleanupCheckerExtension;
+
+/**
+ * Tests for framebuffer creation utilities
+ */
+@ExtendWith(StateCleanupCheckerExtension.class)
+public class FramebufferUtilsTests {
+
+ @Test
+ public void testCreateScreenFramebuffer(){
+ Globals.initGlobals();
+ Globals.renderingEngine = new RenderingEngine();
+ Globals.renderingEngine.createOpenglContext();
+ assertDoesNotThrow(() -> {
+ Texture screenTextureColor = FramebufferUtils.generateScreenTextureColorAlpha(Globals.renderingEngine.getOpenGLState(), Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
+ RenderingEngine.screenTextureColor = screenTextureColor;
+ Texture screenTextureDepth = FramebufferUtils.generateScreenTextureDepth(Globals.renderingEngine.getOpenGLState(), Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
+ RenderingEngine.screenTextureDepth = screenTextureDepth;
+ Framebuffer screenFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.renderingEngine.getOpenGLState(), Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, screenTextureColor, screenTextureDepth);
+ RenderingEngine.screenFramebuffer = screenFramebuffer;
+ });
+ Globals.renderingEngine.destroy();
+ Globals.resetGlobals();
+ }
+
+ @Test
+ public void testCreateScreenFramebufferRepeat(){
+ assertDoesNotThrow(() -> {
+ Globals.initGlobals();
+ Globals.renderingEngine = new RenderingEngine();
+ Globals.renderingEngine.createOpenglContext();
+ Texture screenTextureColor = FramebufferUtils.generateScreenTextureColorAlpha(Globals.renderingEngine.getOpenGLState(), Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
+ Texture screenTextureDepth = FramebufferUtils.generateScreenTextureDepth(Globals.renderingEngine.getOpenGLState(), Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
+ FramebufferUtils.generateScreenTextureFramebuffer(Globals.renderingEngine.getOpenGLState(), Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, screenTextureColor, screenTextureDepth);
+ Globals.renderingEngine.destroy();
+ Globals.resetGlobals();
+
+ Globals.initGlobals();
+ Globals.renderingEngine = new RenderingEngine();
+ Globals.renderingEngine.createOpenglContext();
+ screenTextureColor = FramebufferUtils.generateScreenTextureColorAlpha(Globals.renderingEngine.getOpenGLState(), Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
+ screenTextureDepth = FramebufferUtils.generateScreenTextureDepth(Globals.renderingEngine.getOpenGLState(), Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
+ FramebufferUtils.generateScreenTextureFramebuffer(Globals.renderingEngine.getOpenGLState(), Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, screenTextureColor, screenTextureDepth);
+ Globals.renderingEngine.destroy();
+ Globals.resetGlobals();
+ });
+ }
+
+}
diff --git a/src/test/java/electrosphere/test/testutils/EngineInit.java b/src/test/java/electrosphere/test/testutils/EngineInit.java
index ad3b5986..79d94c5c 100644
--- a/src/test/java/electrosphere/test/testutils/EngineInit.java
+++ b/src/test/java/electrosphere/test/testutils/EngineInit.java
@@ -10,8 +10,6 @@ import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.engine.loadingthreads.LoadingThread.LoadingThreadType;
import electrosphere.engine.profiler.Profiler;
import electrosphere.net.NetUtils;
-import electrosphere.renderer.ui.elementtypes.DrawableElement;
-import electrosphere.renderer.ui.elementtypes.Element;
public class EngineInit {
@@ -85,28 +83,6 @@ public class EngineInit {
LoadingThread loadingThread = new LoadingThread(LoadingThreadType.LOAD_VIEWPORT);
Globals.threadManager.start(loadingThread);
- //
- //wait for client to be fully init'd
- int frames = 0;
- while(Globals.threadManager.isLoading()){
- TestEngineUtils.simulateFrames(1);
- try {
- TimeUnit.MILLISECONDS.sleep(1);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- frames++;
- if(frames > MAX_FRAMES_TO_WAIT){
- String errorMessage = "Failed to setup connected test scene!\n" +
- "Still running threads are:\n"
- ;
- for(LoadingThread thread : Globals.threadManager.getLoadingThreads()){
- errorMessage = errorMessage + thread.getType() + "\n";
- }
- Assertions.fail("Failed to startup");
- }
- }
-
TestEngineUtils.flush();
}
diff --git a/src/test/java/electrosphere/test/testutils/TestEngineUtils.java b/src/test/java/electrosphere/test/testutils/TestEngineUtils.java
index 018f27c6..6eb2f4f7 100644
--- a/src/test/java/electrosphere/test/testutils/TestEngineUtils.java
+++ b/src/test/java/electrosphere/test/testutils/TestEngineUtils.java
@@ -2,10 +2,15 @@ package electrosphere.test.testutils;
import static org.junit.jupiter.api.Assertions.*;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.Assertions;
+
import java.util.function.Supplier;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
+import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.entity.Entity;
/**
@@ -87,6 +92,28 @@ public class TestEngineUtils {
* Flushes any signals that haven't been processed yet
*/
public static void flush(){
+ //
+ //wait for client to be fully init'd
+ int frames = 0;
+ while(Globals.threadManager.isLoading()){
+ TestEngineUtils.simulateFrames(1);
+ try {
+ TimeUnit.MILLISECONDS.sleep(1);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ frames++;
+ if(frames > EngineInit.MAX_FRAMES_TO_WAIT){
+ String errorMessage = "Failed to setup connected test scene!\n" +
+ "Still running threads are:\n"
+ ;
+ for(LoadingThread thread : Globals.threadManager.getLoadingThreads()){
+ errorMessage = errorMessage + thread.getType() + "\n";
+ }
+ Assertions.fail("Failed to startup");
+ }
+ }
+
while(
Globals.elementService.getSignalQueueCount() > 0
){
diff --git a/src/test/java/electrosphere/util/ds/DirectedGraphUnitTests.java b/src/test/java/electrosphere/util/ds/DirectedGraphUnitTests.java
new file mode 100644
index 00000000..d552af3c
--- /dev/null
+++ b/src/test/java/electrosphere/util/ds/DirectedGraphUnitTests.java
@@ -0,0 +1,115 @@
+package electrosphere.util.ds;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import electrosphere.test.annotations.FastTest;
+import electrosphere.test.annotations.UnitTest;
+import electrosphere.util.ds.DirectedGraph.GraphNode;
+
+/**
+ * Unit tests for the directed graph implementation
+ */
+public class DirectedGraphUnitTests {
+
+
+ //
+ //Graph-specific tests
+ //
+
+ @UnitTest
+ @FastTest
+ public void testCreateGraph(){
+ DirectedGraph graph = new DirectedGraph();
+ assertNotNull(graph);
+ }
+
+ @UnitTest
+ @FastTest
+ public void testCreateEntry(){
+ DirectedGraph graph = new DirectedGraph();
+ GraphNode node = graph.createNode(null);
+ assertNotNull(node);
+ }
+
+ @UnitTest
+ @FastTest
+ public void testContainsEntryNotNull(){
+ DirectedGraph graph = new DirectedGraph();
+ graph.createNode(null);
+ assertNotNull(graph.getNodes());
+ }
+
+ @UnitTest
+ @FastTest
+ public void testContainsEntryHasEntry(){
+ DirectedGraph graph = new DirectedGraph();
+ graph.createNode(null);
+ assertEquals(1,graph.getNodes().size());
+ }
+
+ @UnitTest
+ @FastTest
+ public void testDeleteNode(){
+ DirectedGraph graph = new DirectedGraph();
+ GraphNode node = graph.createNode(null);
+ graph.destroyNode(node);
+ assertEquals(0,graph.getNodes().size());
+ }
+
+
+ //
+ //Node-specific tests
+ //
+
+ @UnitTest
+ @FastTest
+ public void testCreateNode(){
+ GraphNode node = new GraphNode();
+ assertNotNull(node);
+ }
+
+ @UnitTest
+ @FastTest
+ public void testNodeGetData(){
+ GraphNode node = new GraphNode("some data");
+ assertEquals("some data", node.getData());
+ }
+
+ @UnitTest
+ @FastTest
+ public void testAddNeighbor(){
+ GraphNode node = new GraphNode();
+ GraphNode neighbor = new GraphNode();
+ node.addNeighbor(neighbor);
+ assertEquals(neighbor, node.getNeighbors().get(0));
+ }
+
+ @UnitTest
+ @FastTest
+ public void testRemoveNeighbor(){
+ GraphNode node = new GraphNode();
+ GraphNode neighbor = new GraphNode();
+ node.addNeighbor(neighbor);
+ node.removeNeighbor(neighbor);
+ assertEquals(0, node.getNeighbors().size());
+ }
+
+ @UnitTest
+ @FastTest
+ public void testGetNeighbors(){
+ GraphNode node = new GraphNode();
+ GraphNode neighbor = new GraphNode();
+ node.addNeighbor(neighbor);
+ assertEquals(1, node.getNeighbors().size());
+ }
+
+ @UnitTest
+ @FastTest
+ public void testContainsNeighbor(){
+ GraphNode node = new GraphNode();
+ GraphNode neighbor = new GraphNode();
+ node.addNeighbor(neighbor);
+ assertEquals(true, node.containsNeighbor(neighbor));
+ }
+
+}