Merge pull request 'framebufferBugHunt' (#3) from framebufferBugHunt into master
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
Fix opengl state caching framebuffer in junit context, integrate par_shapes, work on directed graph implementation
This commit is contained in:
commit
be229ffeed
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
14
pom.xml
14
pom.xml
@ -125,6 +125,20 @@
|
||||
<version>${lwjgl.version}</version>
|
||||
<classifier>${lwjgl.natives}</classifier>
|
||||
</dependency>
|
||||
|
||||
<!--par_shapes-->
|
||||
<!--License: MIT-->
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-par</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-par</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
<classifier>${lwjgl.natives}</classifier>
|
||||
</dependency>
|
||||
|
||||
<!--JOML-->
|
||||
<!--License: MIT-->
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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";
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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<Integer,int[]> blendFuncMap = new HashMap<Integer,int[]>();
|
||||
Map<Integer,int[]> 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<Integer,Integer> unitToPointerMap = new HashMap<Integer,Integer>();
|
||||
Map<Integer,Integer> 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<Integer,int[]>();
|
||||
activeTexture = 0;
|
||||
framebufferType = 0;
|
||||
framebufferPointer = 0;
|
||||
activeShader = null;
|
||||
unitToPointerMap = new HashMap<Integer,Integer>();
|
||||
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)
|
||||
|
||||
@ -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(){
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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){
|
||||
|
||||
@ -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 = "" +
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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;
|
||||
|
||||
10
src/main/java/electrosphere/server/gen/DungeonGen.java
Normal file
10
src/main/java/electrosphere/server/gen/DungeonGen.java
Normal file
@ -0,0 +1,10 @@
|
||||
package electrosphere.server.gen;
|
||||
|
||||
/**
|
||||
* Generates dungeons
|
||||
*/
|
||||
public class DungeonGen {
|
||||
|
||||
|
||||
|
||||
}
|
||||
161
src/main/java/electrosphere/util/ds/DirectedGraph.java
Normal file
161
src/main/java/electrosphere/util/ds/DirectedGraph.java
Normal file
@ -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<GraphNode> nodes;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DirectedGraph(){
|
||||
this.nodes = new LinkedList<GraphNode>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<GraphNode> 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<GraphNode> 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<GraphNode>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty graph node
|
||||
*/
|
||||
public GraphNode(){
|
||||
this.data = null;
|
||||
this.neighbors = new LinkedList<GraphNode>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<GraphNode> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
){
|
||||
|
||||
115
src/test/java/electrosphere/util/ds/DirectedGraphUnitTests.java
Normal file
115
src/test/java/electrosphere/util/ds/DirectedGraphUnitTests.java
Normal file
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user