From 9196568a20b7438c20e22e8fd8c62bb0a110028d Mon Sep 17 00:00:00 2001 From: austin Date: Sun, 10 Mar 2024 11:11:39 -0400 Subject: [PATCH] Break up rendering engine into pipelines flow --- .vscode/launch.json | 4 +- buildNumber.properties | 4 +- docs/src/progress/renderertodo.md | 10 +- .../electrosphere/renderer/OpenGLState.java | 164 +++ .../renderer/RenderingEngine.java | 1176 ++--------------- .../electrosphere/renderer/actor/Actor.java | 9 +- .../actor/instance/InstanceManager.java | 7 +- .../renderer/debug/DebugRendering.java | 8 +- .../renderer/model/Material.java | 20 +- .../electrosphere/renderer/model/Mesh.java | 68 +- .../electrosphere/renderer/model/Model.java | 9 +- .../renderer/pipelines/CompositePipeline.java | 69 + .../pipelines/DebugContentPipeline.java | 207 +++ .../pipelines/MainContentNoOITPipeline.java | 80 ++ .../pipelines/MainContentPipeline.java | 218 +++ .../pipelines/NormalsForOutlinePipeline.java | 88 ++ .../pipelines/PostProcessingPipeline.java | 45 + .../renderer/pipelines/RenderPipeline.java | 17 + .../pipelines/RenderScreenPipeline.java | 76 ++ .../renderer/pipelines/ShadowMapPipeline.java | 110 ++ .../renderer/pipelines/UIPipeline.java | 78 ++ .../pipelines/VolumeBufferPipeline.java | 194 +++ .../renderer/shader/ShaderProgram.java | 62 +- .../renderer/texture/Texture.java | 15 +- .../renderer/ui/elements/ActorPanel.java | 6 +- 25 files changed, 1578 insertions(+), 1166 deletions(-) create mode 100644 src/main/java/electrosphere/renderer/OpenGLState.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/RenderPipeline.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/UIPipeline.java create mode 100644 src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java diff --git a/.vscode/launch.json b/.vscode/launch.json index ff51c075..98bf68df 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,7 +15,7 @@ "name": "Launch Main", "request": "launch", "mainClass": "electrosphere.engine.Main", - "vmArgs": "-Xmx1G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", + "vmArgs": "-Xmx2G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", "projectName": "Renderer" }, { @@ -26,7 +26,7 @@ "env": { "ALSOFT_LOGLEVEL": 4, }, - "vmArgs": "-Xmx1G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", + "vmArgs": "-Xmx2G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", "projectName": "Renderer" }, { diff --git a/buildNumber.properties b/buildNumber.properties index 7ccc6532..58fecef4 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sat Mar 09 19:55:08 EST 2024 -buildNumber=35 +#Sun Mar 10 11:10:27 EDT 2024 +buildNumber=45 diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index d3d3e787..0833017e 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -139,6 +139,11 @@ Timekeeping class that defaults to gltf time and falls back to systemCurrentTime Methods for sleeping physics bodies if nothing nearby them is dynamic (ie trees if there are no moving creatures near them) - SAP2 space from ode4j specifically (ended up using BVH space instead) +Overhaul mesh class + - remove unused stuff + - private constructor + (this is going to require changing a lot of dependencies) + @@ -152,11 +157,6 @@ De-dupe render calls via doing mutations in render pipeline status and dont call Clean up main method/class -Overhaul mesh class - - remove unused stuff - - private constructor - (this is going to require changing a lot of dependencies) - Build a lod system - Could potentially be held at actor level - Link different models based on LOD level diff --git a/src/main/java/electrosphere/renderer/OpenGLState.java b/src/main/java/electrosphere/renderer/OpenGLState.java new file mode 100644 index 00000000..f75872d2 --- /dev/null +++ b/src/main/java/electrosphere/renderer/OpenGLState.java @@ -0,0 +1,164 @@ +package electrosphere.renderer; + +import java.util.HashMap; +import java.util.Map; + +import org.joml.Vector2i; +import org.lwjgl.opengl.GL40; + +import electrosphere.renderer.shader.ShaderProgram; + +/** + * Encapsulates the state of opengl. + * The main function of this class is to sit between any consuming classes and opengl. + * It can then deduplicate calls based on the state that is already set. + */ +public class OpenGLState { + + //the current viewport dimensions + private Vector2i viewport = new Vector2i(0,0); + + //whether depth test is enabled or not + boolean depthTest = false; + + //the current depth function + int depthFunction = -1; + + //the currently bound texture + int boundTexturePointer = 0; + int boundTextureType = 0; + + //the currently active texture + int activeTexture = 0; + + //the currently bound framebuffer + int framebufferType = 0; + int framebufferPointer = 0; + + //active shader + ShaderProgram activeShader = null; + + //map of texture units and their corresponding texture pointers + Map unitToPointerMap = new HashMap(); + + /** + * Sets the viewport + * @param x the width + * @param y the height + */ + public void glViewport(int x, int y){ + if(x != viewport.x || y != viewport.y){ + viewport.x = x; + viewport.y = y; + GL40.glViewport(0, 0, viewport.x, viewport.y); + } + } + + /** + * Sets the depth test + * @param depthTest the depth test state + */ + public void glDepthTest(boolean depthTest){ + // if(this.depthTest != depthTest){ + this.depthTest = depthTest; + if(this.depthTest){ + GL40.glEnable(GL40.GL_DEPTH_TEST); + } else { + GL40.glDisable(GL40.GL_DEPTH_TEST); + } + // } + } + + /** + * Sets the depth function + * @param depthFunction The depth function + */ + public void glDepthFunc(int depthFunction){ + if(this.depthFunction != depthFunction){ + this.depthFunction = depthFunction; + GL40.glDepthFunc(this.depthFunction); + } + } + + /** + * Sets the active texture + * @param texture The active texture + */ + public void glActiveTexture(int texture){ + if(this.activeTexture != texture){ + this.activeTexture = texture; + GL40.glActiveTexture(this.activeTexture); + } + } + + /** + * Binds a texture + * @param textureType The type of texture + * @param textureValue The texture pointer + */ + public void glBindTexture(int textureType, int texturePointer){ + if(this.boundTexturePointer != texturePointer || this.boundTextureType != textureType){ + this.boundTextureType = textureType; + this.boundTexturePointer = texturePointer; + GL40.glBindTexture(this.boundTextureType,this.boundTexturePointer); + } + } + + /** + * 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 glBindTextureUnit(int textureUnit, int texturePointer, int textureType){ + if(!unitToPointerMap.containsKey(textureUnit) || unitToPointerMap.get(textureUnit)!=texturePointer){ + unitToPointerMap.put(textureUnit,texturePointer); + GL40.glActiveTexture(textureUnit); + GL40.glBindTexture(textureType,texturePointer); + } + } + + /** + * Binds a framebuffer + * @param framebufferType the type of framebuffer (vanilla, renderbuffer, etc) + * @param framebufferPointer the pointer to the framebuffer + */ + public void glBindFramebuffer(int framebufferType, int framebufferPointer){ + if(this.framebufferType != framebufferType || this.framebufferPointer != framebufferPointer){ + this.framebufferType = framebufferType; + this.framebufferPointer = framebufferPointer; + GL40.glBindFramebuffer(this.framebufferType,this.framebufferPointer); + } + } + + /** + * Sets the currently active shader program for the renderer + * @param renderPipelineState The render pipeline state object + * @param program The shader program to bind + */ + public void setActiveShader(RenderPipelineState renderPipelineState, ShaderProgram program){ + if(program != activeShader){ + activeShader = program; + GL40.glUseProgram(activeShader.getShaderId()); + renderPipelineState.setCurrentShaderPointer(activeShader.getShaderId()); + } + } + + /** + * Gets the active shader program + * @return The active shader + */ + public ShaderProgram getActiveShader(){ + return activeShader; + } + + /** + * Checks whether the provided shader program is the active shader program + * @param program The program to check + * @return true if the provided program is the active program, false otherwise + */ + public boolean isCurrentShader(ShaderProgram program){ + return this.activeShader == program; + } + +} diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index 9da747b1..6b808b0c 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -73,6 +73,7 @@ import org.joml.Vector3d; import org.joml.Vector3f; import org.lwjgl.BufferUtils; import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.GLFWWindowSizeCallbackI; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; @@ -100,6 +101,16 @@ import electrosphere.renderer.framebuffer.FramebufferUtils; import electrosphere.renderer.framebuffer.Renderbuffer; import electrosphere.renderer.light.LightManager; import electrosphere.renderer.model.Model; +import electrosphere.renderer.pipelines.CompositePipeline; +import electrosphere.renderer.pipelines.DebugContentPipeline; +import electrosphere.renderer.pipelines.MainContentNoOITPipeline; +import electrosphere.renderer.pipelines.MainContentPipeline; +import electrosphere.renderer.pipelines.NormalsForOutlinePipeline; +import electrosphere.renderer.pipelines.PostProcessingPipeline; +import electrosphere.renderer.pipelines.RenderScreenPipeline; +import electrosphere.renderer.pipelines.ShadowMapPipeline; +import electrosphere.renderer.pipelines.UIPipeline; +import electrosphere.renderer.pipelines.VolumeBufferPipeline; import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.DrawableElement; @@ -122,13 +133,13 @@ public class RenderingEngine { public static final int GL_DEFAULT_FRAMEBUFFER = 0; public static final int GL_DEFAULT_RENDERBUFFER = 0; - static Texture screenTextureColor; - static Texture screenTextureDepth; - static Framebuffer screenFramebuffer; - static Renderbuffer screenRenderbuffer; - static int screenTextureVAO; - static ShaderProgram screenTextureShaders; - static ShaderProgram drawChannel; + public static Texture screenTextureColor; + public static Texture screenTextureDepth; + public static Framebuffer screenFramebuffer; + public static Renderbuffer screenRenderbuffer; + public static int screenTextureVAO; + public static ShaderProgram screenTextureShaders; + public static ShaderProgram drawChannel; @@ -153,42 +164,42 @@ public class RenderingEngine { //depth framebuffer/shader for shadow mapping - static ShaderProgram lightDepthShaderProgram; - static Framebuffer lightDepthBuffer; + public static ShaderProgram lightDepthShaderProgram; + public static Framebuffer lightDepthBuffer; //framebuffers for transparent textures - static float[] transparencyAccumulatorClear; - static Texture transparencyAccumulatorTexture; - static float[] transparencyRevealageClear; - static Texture transparencyRevealageTexture; - static Framebuffer transparencyBuffer; - static ShaderProgram oitCompositeProgram; + public static float[] transparencyAccumulatorClear; + public static Texture transparencyAccumulatorTexture; + public static float[] transparencyRevealageClear; + public static Texture transparencyRevealageTexture; + public static Framebuffer transparencyBuffer; + public static ShaderProgram oitCompositeProgram; /* render normals */ - static Texture gameImageNormalsTexture; - static Framebuffer gameImageNormalsFramebuffer; - static ShaderProgram renderNormalsShader; + public static Texture gameImageNormalsTexture; + public static Framebuffer gameImageNormalsFramebuffer; + public static ShaderProgram renderNormalsShader; /* Perspective volumetrics */ - static Matrix4f nearVolumeProjectionMatrix = new Matrix4f(); - static Matrix4f midVolumeProjectionMatrix = new Matrix4f(); - static Matrix4f farVolumeProjectionMatrix = new Matrix4f(); - static ShaderProgram volumeDepthShaderProgram; - static Framebuffer volumeDepthBackfaceFramebuffer; - static Texture volumeDepthBackfaceTexture; - static Framebuffer volumeDepthFrontfaceFramebuffer; - static Texture volumeDepthFrontfaceTexture; - static float volumeDepthLinearCoef = 0.1f; - static float volumeDepthQuadCoef = 0.01f; + public static Matrix4f nearVolumeProjectionMatrix = new Matrix4f(); + public static Matrix4f midVolumeProjectionMatrix = new Matrix4f(); + public static Matrix4f farVolumeProjectionMatrix = new Matrix4f(); + public static ShaderProgram volumeDepthShaderProgram; + public static Framebuffer volumeDepthBackfaceFramebuffer; + public static Texture volumeDepthBackfaceTexture; + public static Framebuffer volumeDepthFrontfaceFramebuffer; + public static Texture volumeDepthFrontfaceTexture; + public static float volumeDepthLinearCoef = 0.1f; + public static float volumeDepthQuadCoef = 0.01f; /* Necessary static variables for drawing */ - static Matrix4d modelTransformMatrix = new Matrix4d(); + public static Matrix4d modelTransformMatrix = new Matrix4d(); /* Vertical volumetrics @@ -202,14 +213,14 @@ public class RenderingEngine { /* Post processing effects (ie kernels) textures, framebuffers, shaders */ - static Texture normalsOutlineTexture; - static Framebuffer normalsOutlineFrambuffer; - static ShaderProgram normalsOutlineShader; + public static Texture normalsOutlineTexture; + public static Framebuffer normalsOutlineFrambuffer; + public static ShaderProgram normalsOutlineShader; /* compositing functions */ - static ShaderProgram compositeAnimeOutline; + public static ShaderProgram compositeAnimeOutline; // public static boolean renderHitboxes = false; @@ -217,9 +228,7 @@ public class RenderingEngine { LightManager lightManager; - ShaderProgram activeProgram; - - static int outputFramebuffer = 0; + public static int outputFramebuffer = 0; //used in calculating projection matrix static float aspectRatio = 1.0f; @@ -227,6 +236,21 @@ public class RenderingEngine { //the current state of the rendering pipeline static RenderPipelineState renderPipelineState = new RenderPipelineState(); + + //the opengl state + static OpenGLState openGLState = new OpenGLState(); + + //render pipelines + MainContentPipeline mainContentPipeline = new MainContentPipeline(); + MainContentNoOITPipeline mainContentNoOITPipeline = new MainContentNoOITPipeline(); + DebugContentPipeline debugContentPipeline = new DebugContentPipeline(); + ShadowMapPipeline shadowMapPipeline = new ShadowMapPipeline(); + VolumeBufferPipeline volumeBufferPipeline = new VolumeBufferPipeline(); + NormalsForOutlinePipeline normalsForOutlinePipeline = new NormalsForOutlinePipeline(); + PostProcessingPipeline postProcessingPipeline = new PostProcessingPipeline(); + CompositePipeline compositePipeline = new CompositePipeline(); + UIPipeline uiPipeline = new UIPipeline(); + RenderScreenPipeline renderScreenPipeline = new RenderScreenPipeline(); public void createOpenglContext(){ @@ -253,13 +277,14 @@ public class RenderingEngine { glfwTerminate(); } //set resize callback -// GLFW.glfwSetWindowSizeCallback​(Globals.window, new GLFWWindowSizeCallbackI(){ -// @Override -// public void invoke(long window, int width, int height){ -// Globals.WINDOW_HEIGHT = height; -// Globals.WINDOW_WIDTH = width; -// } -// }); + GLFWWindowSizeCallbackI windowSizeCallback = new GLFWWindowSizeCallbackI(){ + @Override + public void invoke(long window, int width, int height){ + Globals.WINDOW_HEIGHT = height; + Globals.WINDOW_WIDTH = width; + } + }; + GLFW.glfwSetWindowSizeCallback(Globals.window, windowSizeCallback); //Makes the window that was just created the current OS-level window context glfwMakeContextCurrent(Globals.window); //Maximize it @@ -438,25 +463,6 @@ public class RenderingEngine { Globals.viewMatrix.translation(new Vector3f(0.0f,0.0f,-3.0f)); } - static float calculateAngle(Vector3f origin, Vector3f target){ - float rVal = (float)Math.atan2(target.z - origin.z, target.x - origin.x); - if(rVal < 0){ - rVal = rVal + (float)(Math.PI * 2); - } - return rVal; - } - - static float calculateDist(Vector3f origin, Vector3f target){ - return origin.distance(target); - } - - /** - * Updates the frustum box of the render pipeline - */ - void updateFrustumBox(){ - renderPipelineState.updateFrustumIntersection(Globals.projectionMatrix, Globals.viewMatrix); - } - /** * Main function to draw the screen @@ -468,39 +474,31 @@ public class RenderingEngine { updateFrustumBox(); } - // - //first pass: generate depth map - // + //generate depth map if(Globals.RENDER_FLAG_RENDER_SHADOW_MAP){ - renderShadowMapContent(); + shadowMapPipeline.render(openGLState, renderPipelineState); } - /* - render volume buffer - */ + //render volume buffer if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){ - updateVolumeBuffer(); + volumeBufferPipeline.render(openGLState, renderPipelineState); } - /* - Update light buffer - */ + //Update light buffer lightManager.updateData(); - /* - Render content to the game framebuffer - */ + //Render content to the game framebuffer if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){ if(Globals.userSettings.getGraphicsPerformanceOIT()){ - renderGameContent(); + mainContentPipeline.render(openGLState, renderPipelineState); } else { - renderGameContentNoOIT(); + mainContentNoOITPipeline.render(openGLState, renderPipelineState); } - renderDebugContent(); - renderNormalsForOutline(); - applyKernelsAndPostprocessing(); - compositeGameImage(); + debugContentPipeline.render(openGLState, renderPipelineState); + normalsForOutlinePipeline.render(openGLState, renderPipelineState); + postProcessingPipeline.render(openGLState, renderPipelineState); + compositePipeline.render(openGLState, renderPipelineState); } @@ -512,37 +510,15 @@ public class RenderingEngine { glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); - /* - Render the game framebuffer texture to a quad - */ + //Render the game framebuffer texture to a quad if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER){ - renderScreenFramebuffer(); + renderScreenPipeline.render(openGLState, renderPipelineState); } - /* - Render black background - */ - if(Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND){ - renderBlackBackground(); - } + //render ui + uiPipeline.render(openGLState, renderPipelineState); - /* - Render white background - */ - if(Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND){ - renderWhiteBackground(); - } - - /* - Render any ui elements - */ - if(Globals.RENDER_FLAG_RENDER_UI){ - renderUI(); - } - - /* - Render boundaries of ui elements - */ + //Render boundaries of ui elements if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){ DebugRendering.drawUIBoundsWireframe(); } @@ -569,980 +545,12 @@ public class RenderingEngine { glfwSwapBuffers(Globals.window); glfwPollEvents(); } - - - static void renderShadowMapContent(){ - - Matrix4d modelTransformMatrix = new Matrix4d(); - - //set the viewport to shadow map size - glViewport(0, 0, 4096, 4096); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_ALWAYS); - - Globals.renderingEngine.setActiveShader(renderPipelineState, lightDepthShaderProgram); - - lightDepthBuffer.bind(); - glClear(GL_DEPTH_BUFFER_BIT); - glActiveTexture(GL_TEXTURE0); - float eyeX = -1.0f; - float eyeY = 10.0f; - float eyeZ = -5.5f; - float nearPlane = 0.01f; - float eyeDist = (float)Math.sqrt(eyeX * eyeX + eyeY * eyeY + eyeZ * eyeZ); - float farPlane = eyeDist + 10.0f; - float sidesMagnitude = (float)Math.sqrt(eyeDist); - //set matrices for light render - Matrix4f lightProjection = new Matrix4f().setOrtho(-sidesMagnitude, sidesMagnitude, -sidesMagnitude, sidesMagnitude, nearPlane, farPlane);//glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); - Matrix4f lightView = new Matrix4f().setLookAt( - new Vector3f(eyeX, eyeY, eyeZ), - new Vector3f( 0.0f, 0.0f, 0.0f), - new Vector3f( 0.0f, 1.0f, 0.0f) - ); - Globals.lightDepthMatrix = new Matrix4f(lightProjection).mul(lightView); - - glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16])); - - // glCullFace(GL_FRONT); - - // - // Set render pipeline state - // - renderPipelineState.setUseMeshShader(false); - renderPipelineState.setBufferStandardUniforms(true); - renderPipelineState.setBufferNonStandardUniforms(true); - renderPipelineState.setUseMaterial(false); - renderPipelineState.setUseShadowMap(false); - renderPipelineState.setUseBones(true); - renderPipelineState.setUseLight(false); - - // - // D R A W A L L E N T I T I E S - // - Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); - modelTransformMatrix = new Matrix4d(); - for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && - currentEntity.containsKey(EntityDataStrings.DRAW_CAST_SHADOW) - ){ - //fetch actor - Actor currentActor = EntityUtils.getActor(currentEntity); - //calculate camera-modified vector3f - Vector3f cameraCenter = CameraEntityUtils.getCameraCenter(Globals.playerCamera); - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(cameraCenter); - //calculate and apply model transform - modelTransformMatrix = modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); - modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); - currentActor.applyModelMatrix(modelTransformMatrix); - //draw - currentActor.draw(renderPipelineState); - } - } - - - - //reset texture - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); - //bind default framebuffer - glBindFramebuffer(GL_FRAMEBUFFER,0); - //reset the viewport to screen size - glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); - //resume culling backface -// glCullFace(GL_BACK); - } - - - static void renderGameContent(){ - - Matrix4d modelTransformMatrix = new Matrix4d(); - - //bind screen fbo - screenFramebuffer.bind(); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - glDepthMask(true); - glViewport(0, 0, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); - - /// - /// R E N D E R I N G S T U F F - /// - //Sets the background color. - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - // - // Set render pipeline state - // - renderPipelineState.setSelectedShader(SelectedShaderEnum.PRIMARY); - renderPipelineState.setUseMeshShader(true); - renderPipelineState.setBufferStandardUniforms(true); - renderPipelineState.setBufferNonStandardUniforms(false); - renderPipelineState.setUseMaterial(true); - renderPipelineState.setUseShadowMap(true); - renderPipelineState.setUseBones(true); - renderPipelineState.setUseLight(true); - - - // - // Pass One: Solids - // - - // - // D R A W A L L E N T I T I E S - // - Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); - for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && - currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null - ){ - //fetch actor - Actor currentActor = EntityUtils.getActor(currentEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - //calculate and apply model transform - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); - modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); - currentActor.applyModelMatrix(modelTransformMatrix); - //draw - currentActor.draw(renderPipelineState); - } - } - for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) != null && - currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null - ){ - //fetch actor - InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity); - //if the shader attribute for model matrix exists, calculate the model matrix and apply - if(InstancedActor.getInstanceModelAttribute(currentEntity) != null){ - ShaderAttribute modelAttribute = InstancedActor.getInstanceModelAttribute(currentEntity); - //calculate model matrix - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - Quaterniond rotation = EntityUtils.getRotation(currentEntity); - // modelTransformMatrix.identity(); - modelTransformMatrix.identity().translationRotateScale( - cameraModifiedPosition, - new Quaternionf((float)rotation.x,(float)rotation.y,(float)rotation.z,(float)rotation.w), - new Vector3f(EntityUtils.getScale(currentEntity)) - ); - //set actor value - currentActor.setAttribute(modelAttribute, new Matrix4f(modelTransformMatrix)); - //draw - currentActor.draw(renderPipelineState, new Vector3d(cameraModifiedPosition)); - } else { - currentActor.draw(renderPipelineState); - } - } - } - //draw all instanced models - Globals.clientInstanceManager.draw(renderPipelineState); - - // - // Pass Two: Transparency Accumulator + Revealage - // - // glDisable(GL_DEPTH_TEST); - glDepthMask(false); - glEnable(GL_BLEND); - glBlendFunci(0, GL_ONE, GL_ONE); - glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - glBlendEquation(GL_FUNC_ADD); - - transparencyBuffer.bind(); - glClearBufferfv(GL_COLOR,0,transparencyAccumulatorClear); - glClearBufferfv(GL_COLOR,1,transparencyRevealageClear); - - // - // Set render pipeline state - // - renderPipelineState.setUseMeshShader(true); - renderPipelineState.setSelectedShader(SelectedShaderEnum.OIT); - glDepthFunc(GL_LEQUAL); - - // - //!!!WARNING!!! - //Comments on function: - //If you're going "gee wilikers I don't know why the back planes of my transparent-labeled aren't showing through the transparency", this is for you - //The transparent pass receives the depth buffer of the opaque pass and IS DEPTH MASK CULLED - //This means if you draw the transparent object in the depth pass, it will not draw in the transparent pass as it is culled - // - //!!!WARNING!!! - //TLDR OF ABOVE: DO NOT DRAW TRANSPARENT OBJECTS IN OPAQUE PASS - // - - - for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && - currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null - ){ - //fetch actor - Actor currentActor = EntityUtils.getActor(currentEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - //calculate and apply model transform - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); - modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); - currentActor.applyModelMatrix(modelTransformMatrix); - //draw - currentActor.draw(renderPipelineState); - } - } - for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) != null && - currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null - ){ - //fetch actor - InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity); - //if the shader attribute for model matrix exists, calculate the model matrix and apply - if(InstancedActor.getInstanceModelAttribute(currentEntity) != null){ - ShaderAttribute modelAttribute = InstancedActor.getInstanceModelAttribute(currentEntity); - //calculate model matrix - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - Quaterniond rotation = EntityUtils.getRotation(currentEntity); - // modelTransformMatrix.identity(); - modelTransformMatrix.identity().translationRotateScale( - cameraModifiedPosition, - new Quaternionf((float)rotation.x,(float)rotation.y,(float)rotation.z,(float)rotation.w), - new Vector3f(EntityUtils.getScale(currentEntity)) - ); - //set actor value - currentActor.setAttribute(modelAttribute, new Matrix4f(modelTransformMatrix)); - //draw - currentActor.draw(renderPipelineState, new Vector3d(cameraModifiedPosition)); - } else { - currentActor.draw(renderPipelineState); - } - } - } - //draw all instanced models - Globals.clientInstanceManager.draw(renderPipelineState); - - - // - // Set render pipeline state - // - renderPipelineState.setSelectedShader(SelectedShaderEnum.PRIMARY); - - - -// glBindVertexArray(0); - } - - static void renderGameContentNoOIT(){ - - //bind screen fbo - screenFramebuffer.bind(); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - glDepthMask(true); - glViewport(0, 0, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); - - glEnable(GL_BLEND); - glBlendFunci(0, GL_ONE, GL_ONE); - glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - glBlendEquation(GL_FUNC_ADD); - - /// - /// R E N D E R I N G S T U F F - /// - //Sets the background color. - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - // - // Set render pipeline state - // - renderPipelineState.setUseMeshShader(true); - renderPipelineState.setBufferStandardUniforms(true); - renderPipelineState.setBufferNonStandardUniforms(false); - renderPipelineState.setUseMaterial(true); - renderPipelineState.setUseShadowMap(true); - renderPipelineState.setUseBones(true); - renderPipelineState.setUseLight(true); - - // - // D R A W A L L E N T I T I E S - // - Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); - for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) - ){ - //fetch actor - Actor currentActor = EntityUtils.getActor(currentEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - //calculate and apply model transform - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); - modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); - currentActor.applyModelMatrix(modelTransformMatrix); - //draw - currentActor.draw(renderPipelineState); - } - } - } - - static void renderDebugContent(){ - - //bind screen fbo - screenFramebuffer.bind(); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - glDepthMask(true); - glViewport(0, 0, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); - - /// - /// R E N D E R I N G S T U F F - /// - //Sets the background color. - - - // - // Set render pipeline state - // - renderPipelineState.setUseMeshShader(true); - renderPipelineState.setBufferStandardUniforms(true); - renderPipelineState.setBufferNonStandardUniforms(false); - renderPipelineState.setUseMaterial(true); - renderPipelineState.setUseShadowMap(true); - renderPipelineState.setUseBones(true); - renderPipelineState.setUseLight(true); - - Matrix4d modelTransformMatrix = new Matrix4d(); - - if(Globals.userSettings.graphicsDebugDrawCollisionSpheres()){ - for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){ - if((boolean)currentHitbox.getData(EntityDataStrings.DATA_STRING_DRAW)){ - Model hitboxModel; - HitboxData data = HitboxUtils.getHitboxData(currentHitbox); - if(data.isActive()){ - if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){ - if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere.fbx")) != null){ - Vector3d position = EntityUtils.getPosition(currentHitbox); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere - modelTransformMatrix.scale(data.getRadius() * 2); - hitboxModel.setModelMatrix(modelTransformMatrix); - hitboxModel.draw(renderPipelineState); - } - } else if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){ - if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere_1.fbx")) != null){ - Vector3d position = EntityUtils.getPosition(currentHitbox); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere - modelTransformMatrix.scale(data.getRadius() * 2); - hitboxModel.setModelMatrix(modelTransformMatrix); - hitboxModel.draw(renderPipelineState); - } - } - } else { - if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere_grey.fbx")) != null){ - Vector3d position = EntityUtils.getPosition(currentHitbox); - modelTransformMatrix.identity(); - modelTransformMatrix.translate(new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera))); - // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere - modelTransformMatrix.scale(data.getRadius() * 2); - hitboxModel.setModelMatrix(modelTransformMatrix); - hitboxModel.draw(renderPipelineState); - } - } - } - } - } - - if(Globals.userSettings.graphicsDebugDrawPhysicsObjects()){ - Model physicsGraphicsModel; - for(Collidable collidable : Globals.clientSceneWrapper.getCollisionEngine().getCollidables()){ - Entity physicsEntity = collidable.getParent(); - if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE) != null){ - CollidableTemplate template = (CollidableTemplate)physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE); - switch(template.getType()){ - case "CYLINDER": - if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcylinder.fbx")) != null){ - Vector3d position = EntityUtils.getPosition(physicsEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(physicsEntity)); - // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere - modelTransformMatrix.scale(template.getDimension1(),template.getDimension2() * 0.5,template.getDimension3()); - physicsGraphicsModel.setModelMatrix(modelTransformMatrix); - physicsGraphicsModel.draw(renderPipelineState); - } - break; - case "CUBE": - if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){ - Vector3d position = EntityUtils.getPosition(physicsEntity); - // Vector3f scale = EntityUtils.getScale(physicsEntity); - Quaterniond rotation = EntityUtils.getRotation(physicsEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(rotation); - // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere - modelTransformMatrix.scale(template.getDimension1(),template.getDimension2(),template.getDimension3()); - physicsGraphicsModel.setModelMatrix(modelTransformMatrix); - physicsGraphicsModel.draw(renderPipelineState); - } - break; - } - } - } - for(Collidable collidable : Globals.clientSceneWrapper.getCollisionEngine().getCollidables()){ - Entity physicsEntity = collidable.getParent(); - if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){ - if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE)){ - if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitplane.fbx")) != null){ - Vector3d position = EntityUtils.getPosition(physicsEntity); - Vector3f scale = EntityUtils.getScale(physicsEntity); - Quaterniond rotation = EntityUtils.getRotation(physicsEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(rotation); - // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere - modelTransformMatrix.scale(new Vector3d(scale)); - physicsGraphicsModel.setModelMatrix(modelTransformMatrix); - physicsGraphicsModel.draw(renderPipelineState); - } - } else if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE)){ - if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){ - Vector3d position = EntityUtils.getPosition(physicsEntity); - Vector3f scale = EntityUtils.getScale(physicsEntity); - Quaterniond rotation = EntityUtils.getRotation(physicsEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(rotation); - // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere - modelTransformMatrix.scale(new Vector3d(scale)); - physicsGraphicsModel.setModelMatrix(modelTransformMatrix); - physicsGraphicsModel.draw(renderPipelineState); - } - } - } - } - } - - if(Globals.userSettings.graphicsDebugDrawNavmesh()){ - Model shapeGraphicsModel; - for(NavMesh mesh : Globals.navMeshManager.getMeshes()){ - for(NavShape shape : mesh.getNodes()){ - if(shape instanceof NavCube){ - if((shapeGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){ - NavCube cube = (NavCube)shape; - Vector3d position = new Vector3d(cube.getMinPoint()).add(cube.getMaxPoint()).mul(0.5); - Vector3f scale = new Vector3f((float)(cube.getMaxPoint().x-cube.getMinPoint().x)/2,(float)(cube.getMaxPoint().y-cube.getMinPoint().y)/2,(float)(cube.getMaxPoint().z-cube.getMinPoint().z)/2); - Quaternionf rotation = new Quaternionf(); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(rotation); - // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere - modelTransformMatrix.scale(new Vector3d(scale)); - shapeGraphicsModel.setModelMatrix(modelTransformMatrix); - shapeGraphicsModel.draw(renderPipelineState); - } - } - } - } - } - } - - static void renderNormalsForOutline(){ - - /* - gameImageNormalsTexture; - static Framebuffer gameImageNormalsFramebuffer; - static ShaderProgram renderNormalsShader; - */ - - //bind screen fbo - gameImageNormalsFramebuffer.bind(); - glEnable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDepthFunc(GL_LESS); - glDepthMask(true); - - glViewport(0, 0, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); - - /// - /// R E N D E R I N G S T U F F - /// - //Sets the background color. - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - - // - // Set render pipeline state - // - renderPipelineState.setUseMeshShader(false); - renderPipelineState.setBufferStandardUniforms(true); - renderPipelineState.setBufferNonStandardUniforms(false); - renderPipelineState.setUseMaterial(true); - renderPipelineState.setUseShadowMap(true); - renderPipelineState.setUseBones(true); - renderPipelineState.setUseLight(true); - - - - Matrix4d modelTransformMatrix = new Matrix4d(); - - Globals.renderingEngine.setActiveShader(renderPipelineState, renderNormalsShader); - - Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); - for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && - currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null && - currentEntity.getData(EntityDataStrings.DRAW_OUTLINE) != null - ){ - //fetch actor - Actor currentActor = EntityUtils.getActor(currentEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - //calculate and apply model transform - modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); - modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); - currentActor.applyModelMatrix(modelTransformMatrix); - //draw - currentActor.draw(renderPipelineState); - } - } - } - - static void applyKernelsAndPostprocessing(){ - // - // Outline normals - // - - normalsOutlineFrambuffer.bind(); - ShaderProgram program = Globals.assetManager.fetchShader("Shaders/anime/outlineNormals.vs", null, "Shaders/anime/outlineNormals.fs"); - if(program != null){ - Globals.renderingEngine.setActiveShader(renderPipelineState, program); - - glBindVertexArray(screenTextureVAO); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, gameImageNormalsTexture.getTexturePointer()); - - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - } - } - - static void compositeGameImage(){ - // - //Setup to render screen textures & bind screen framebuffer - // - glDepthFunc(GL_ALWAYS); - // glDepthMask(false); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - screenFramebuffer.bind(); - - glBindVertexArray(screenTextureVAO); - - - // - //Draw anime outline - // - Globals.renderingEngine.setActiveShader(renderPipelineState, compositeAnimeOutline); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, normalsOutlineTexture.getTexturePointer()); - - glDrawArrays(GL_TRIANGLES, 0, 6); - - // - //Composite transparency on top of solids - // - Globals.renderingEngine.setActiveShader(renderPipelineState, oitCompositeProgram); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, transparencyAccumulatorTexture.getTexturePointer()); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, transparencyRevealageTexture.getTexturePointer()); - - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - - - - } - - static void renderScreenFramebuffer(){ - // - //unbind texture channels - // - //What does this mean? - //essentially there are two channels we're using to draw mesh textures - //we have to glBindTexture to pointer 0 for BOTH channels, otherwise - //the leftover texture gets used to draw the screen framebuffer quad - //which doesnt work - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); - - glDisable(GL_DEPTH_TEST); - glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); - - - - //render full screen quad -// glBlitFramebuffer(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, 0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, -// GL_COLOR_BUFFER_BIT, GL_NEAREST); - Globals.renderingEngine.setActiveShader(renderPipelineState, screenTextureShaders); - glBindVertexArray(screenTextureVAO); - //aaa - switch(outputFramebuffer){ - case 0: - glBindTexture(GL_TEXTURE_2D, screenFramebuffer.getTexturePointer()); - break; - case 1: - glBindTexture(GL_TEXTURE_2D, lightDepthBuffer.getTexturePointer()); - break; - case 2: - glBindTexture(GL_TEXTURE_2D, volumeDepthBackfaceTexture.getTexturePointer()); - break; - case 3: - glBindTexture(GL_TEXTURE_2D, volumeDepthFrontfaceTexture.getTexturePointer()); - break; - case 4: - glBindTexture(GL_TEXTURE_2D, transparencyAccumulatorTexture.getTexturePointer()); - break; - case 5: - glBindTexture(GL_TEXTURE_2D, gameImageNormalsTexture.getTexturePointer()); - break; - case 6: - glBindTexture(GL_TEXTURE_2D, normalsOutlineTexture.getTexturePointer()); - break; - case 7: - Globals.renderingEngine.setActiveShader(renderPipelineState, drawChannel); - glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "channel"),4); - glBindTexture(GL_TEXTURE_2D, screenTextureDepth.getTexturePointer()); - break; - } - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - } - - - static void renderUI(){ - // - // Set render pipeline state - // - renderPipelineState.setUseMeshShader(true); - renderPipelineState.setBufferStandardUniforms(false); - renderPipelineState.setBufferNonStandardUniforms(true); - renderPipelineState.setUseMaterial(true); - renderPipelineState.setUseShadowMap(false); - renderPipelineState.setUseBones(false); - renderPipelineState.setUseLight(false); - - glDisable(GL_DEPTH_TEST); - for(Element currentElement : Globals.elementManager.getWindowList()){ - if(currentElement instanceof DrawableElement){ - DrawableElement drawable = (DrawableElement) currentElement; - if(drawable.getVisible()){ - drawable.draw(GL_DEFAULT_FRAMEBUFFER, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); - } - } - } - -// for(Entity currentEntity : Globals.entityManager.getUIElements()){ -// Actor uiActor = EntityUtils.getEntityActor(currentEntity); -// if(currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_UI_ELEMENT_FONT)){ -// modelTransformMatrix.identity(); -// modelTransformMatrix.translate(EntityUtils.getEntityPosition(currentEntity)); -// uiActor.applyModelMatrix(modelTransformMatrix); -// } -// uiActor.drawUI(); -// } - } - - static void updateVolumeBuffer(){ - Matrix4d modelTransformMatrix = new Matrix4d(); - - //set the viewport to shadow map size - glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - glDepthMask(true); - - //stop rendering front faces - GL15.glEnable(GL15.GL_CULL_FACE); - GL15.glCullFace(GL15.GL_FRONT); - - Globals.renderingEngine.setActiveShader(renderPipelineState, volumeDepthShaderProgram); - - volumeDepthBackfaceFramebuffer.bind(); - glClear(GL_DEPTH_BUFFER_BIT); - glActiveTexture(GL_TEXTURE0); -// glBindTexture(GL_TEXTURE_2D, woodTexture); -// renderScene(simpleDepthShader); - - glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "view"), false, Globals.viewMatrix.get(new float[16])); - // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, Globals.projectionMatrix.get(new float[16])); - - - - GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "linearCoef"), volumeDepthLinearCoef); - GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "quadCoef"), volumeDepthQuadCoef); - - GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "near"), 0.1f); - GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "far"), 100f); - -// glCullFace(GL_FRONT); - - // - // Set render pipeline state - // - renderPipelineState.setUseMeshShader(false); - renderPipelineState.setBufferStandardUniforms(false); - renderPipelineState.setBufferNonStandardUniforms(true); - renderPipelineState.setUseMaterial(false); - renderPipelineState.setUseShadowMap(false); - renderPipelineState.setUseBones(true); - renderPipelineState.setUseLight(false); - - - // - // D R A W A L L E N T I T I E S - // - Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); - for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && - currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC) - ){ - //fetch actor - Actor currentActor = EntityUtils.getActor(currentEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - //set projection matrix - // if(cameraModifiedPosition.length() > 2f){ - // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, farVolumeProjectionMatrix.get(new float[16])); - // } else if(cameraModifiedPosition.length() > 0.5f){ - // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, midVolumeProjectionMatrix.get(new float[16])); - // } else { - glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "projection"), false, nearVolumeProjectionMatrix.get(new float[16])); - // } - // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, Globals.projectionMatrix.get(new float[16])); - //calculate and apply model transform - modelTransformMatrix = modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); - modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); - currentActor.applyModelMatrix(modelTransformMatrix); - //draw -// if(!currentEntity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) && !currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE)){ - currentActor.draw(renderPipelineState); -// System.out.println(currentActor.modelPath); -// } - } - } - - // - //Draw front faces of all non-volumetrics - // - cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); - for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && - !currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC) - ){ - //fetch actor - Actor currentActor = EntityUtils.getActor(currentEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - //set projection matrix - glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "projection"), false, nearVolumeProjectionMatrix.get(new float[16])); - modelTransformMatrix = modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); - modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); - currentActor.applyModelMatrix(modelTransformMatrix); - currentActor.draw(renderPipelineState); - } - } - - - - //stop rendering front faces - GL15.glEnable(GL15.GL_CULL_FACE); - GL15.glCullFace(GL15.GL_BACK); - - Globals.renderingEngine.setActiveShader(renderPipelineState, volumeDepthShaderProgram); - - volumeDepthFrontfaceFramebuffer.bind(); - glClear(GL_DEPTH_BUFFER_BIT); - glActiveTexture(GL_TEXTURE0); -// glBindTexture(GL_TEXTURE_2D, woodTexture); -// renderScene(simpleDepthShader); - - // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "view"), false, Globals.viewMatrix.get(new float[16])); - // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, Globals.projectionMatrix.get(new float[16])); - - - - // GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "linearCoef"), volumeDepthLinearCoef); - // GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "quadCoef"), volumeDepthQuadCoef); - -// glCullFace(GL_FRONT); - - // - // D R A W A L L E N T I T I E S - // - for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && - currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC) - ){ - //fetch actor - Actor currentActor = EntityUtils.getActor(currentEntity); - //calculate camera-modified vector3f - Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); - //calculate and apply model transform - modelTransformMatrix = modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); - modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); - currentActor.applyModelMatrix(modelTransformMatrix); - //draw -// if(!currentEntity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) && !currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE)){ - currentActor.draw(renderPipelineState); -// System.out.println(currentActor.modelPath); -// } - } - } - - GL15.glCullFace(GL15.GL_BACK); - //now cull back faces - - //reset texture - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); - //bind default framebuffer - glBindFramebuffer(GL_FRAMEBUFFER,0); - //resume culling backface - GL15.glDisable(GL15.GL_CULL_FACE); - } - - static void renderBlackBackground(){ - //render full screen quad - glUseProgram(screenTextureShaders.getShaderId()); - glDisable(GL_DEPTH_TEST); - glBindVertexArray(screenTextureVAO); - Texture blackTexture = Globals.assetManager.fetchTexture(Globals.blackTexture); - if(blackTexture != null){ - blackTexture.bind(); - } -// glBindTexture(GL_TEXTURE_2D, screenFramebuffer.getTexture()); - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - } - - static void renderWhiteBackground(){ - //render full screen quad - glUseProgram(screenTextureShaders.getShaderId()); - glDisable(GL_DEPTH_TEST); - glBindVertexArray(screenTextureVAO); - Texture blackTexture = Globals.assetManager.fetchTexture(Globals.offWhiteTexture); - if(blackTexture != null){ - blackTexture.bind(); - } -// glBindTexture(GL_TEXTURE_2D, screenFramebuffer.getTexture()); - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - } - /** - * Sets the currently active shader program for the renderer - * @param renderPipelineState The render pipeline state object - * @param program The shader program to bind + * Updates the frustum box of the render pipeline */ - public void setActiveShader(RenderPipelineState renderPipelineState, ShaderProgram program){ - glUseProgram(program.getShaderId()); - activeProgram = program; - renderPipelineState.setCurrentShaderPointer(program.getShaderId()); - } - - public ShaderProgram getActiveShader(){ - return activeProgram; + void updateFrustumBox(){ + renderPipelineState.updateFrustumIntersection(Globals.projectionMatrix, Globals.viewMatrix); } public void bindFramebuffer(int framebufferPointer){ @@ -1624,6 +632,14 @@ public class RenderingEngine { return renderPipelineState; } + /** + * Gets the current opengl state + * @return + */ + public OpenGLState getOpenGLState(){ + return openGLState; + } + /** * Tries to recapture the screen */ diff --git a/src/main/java/electrosphere/renderer/actor/Actor.java b/src/main/java/electrosphere/renderer/actor/Actor.java index e1127644..c0dd927a 100644 --- a/src/main/java/electrosphere/renderer/actor/Actor.java +++ b/src/main/java/electrosphere/renderer/actor/Actor.java @@ -1,6 +1,7 @@ package electrosphere.renderer.actor; import electrosphere.engine.Globals; +import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.model.Bone; import electrosphere.renderer.model.Model; @@ -196,7 +197,7 @@ public class Actor { * Draws an actor * @param renderPipelineState The render pipeline state to draw within */ - public void draw(RenderPipelineState renderPipelineState){ + public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState){ Model model = Globals.assetManager.fetchModel(modelPath); boolean hasDrawn = false; if(model != null && isWithinFrustumBox(renderPipelineState,model)){ @@ -223,13 +224,13 @@ public class Actor { if(textureOverride != null){ Texture overrideTextureObject = Globals.assetManager.fetchTexture(textureOverride); if(overrideTextureObject != null){ - overrideTextureObject.bind(); + overrideTextureObject.bind(openGLState); hasDrawn = true; - model.draw(renderPipelineState); + model.draw(renderPipelineState,openGLState); } } if(!hasDrawn){ - model.draw(renderPipelineState); + model.draw(renderPipelineState,openGLState); } model.getShaderMask().clear(); model.setTextureMask(null); diff --git a/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java b/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java index ee27ace4..e813d31b 100644 --- a/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java +++ b/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java @@ -7,6 +7,7 @@ import java.util.Map; import electrosphere.engine.Globals; +import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.buffer.ShaderAttribute; import electrosphere.renderer.buffer.HomogenousUniformBuffer.HomogenousBufferTypes; @@ -69,7 +70,7 @@ public class InstanceManager { /** * Draws all models that are queued in this instance manager */ - public void draw(RenderPipelineState renderPipelineState){ + public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState){ renderPipelineState.setInstanced(true); renderPipelineState.setUseMeshShader(false); for(String modelPath : modelsToDraw){ @@ -84,8 +85,8 @@ public class InstanceManager { ShaderProgram shader = Globals.assetManager.fetchShader(data.vertexShaderPath, null, data.fragmentShaderPath); Model model = Globals.assetManager.fetchModel(modelPath); if(model != null && shader != null){ - Globals.renderingEngine.setActiveShader(renderPipelineState, shader); - model.draw(renderPipelineState); + openGLState.setActiveShader(renderPipelineState, shader); + model.draw(renderPipelineState,openGLState); } data.flip(); diff --git a/src/main/java/electrosphere/renderer/debug/DebugRendering.java b/src/main/java/electrosphere/renderer/debug/DebugRendering.java index 589566f6..fb1015be 100644 --- a/src/main/java/electrosphere/renderer/debug/DebugRendering.java +++ b/src/main/java/electrosphere/renderer/debug/DebugRendering.java @@ -61,7 +61,7 @@ public class DebugRendering { } if(elementDrawDebugProgram != null && planeModel != null){ Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); - Globals.renderingEngine.setActiveShader(Globals.renderingEngine.getRenderPipelineState(), elementDrawDebugProgram); + Globals.renderingEngine.getOpenGLState().setActiveShader(Globals.renderingEngine.getRenderPipelineState(), elementDrawDebugProgram); planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "color", color); @@ -70,7 +70,7 @@ public class DebugRendering { // Globals.renderingEngine.setActiveShader(Globals.assetManager.fetchShader("Shaders/plane/plane.vs", null, "Shaders/plane/plane.fs")); // } //drawUI sets shader so overriding window bound shader - planeModel.draw(Globals.renderingEngine.getRenderPipelineState()); + planeModel.draw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState()); } } } @@ -85,7 +85,7 @@ public class DebugRendering { } if(windowDrawDebugProgram != null && planeModel != null){ Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); - Globals.renderingEngine.setActiveShader(Globals.renderingEngine.getRenderPipelineState(), windowDrawDebugProgram); + Globals.renderingEngine.getOpenGLState().setActiveShader(Globals.renderingEngine.getRenderPipelineState(), windowDrawDebugProgram); planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "color", color); @@ -94,7 +94,7 @@ public class DebugRendering { // Globals.renderingEngine.setActiveShader(Globals.assetManager.fetchShader("Shaders/plane/plane.vs", null, "Shaders/plane/plane.fs")); // } //drawUI sets shader so overriding window bound shader - planeModel.draw(Globals.renderingEngine.getRenderPipelineState()); + planeModel.draw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState()); } } } diff --git a/src/main/java/electrosphere/renderer/model/Material.java b/src/main/java/electrosphere/renderer/model/Material.java index 4e85e33f..c6fc3d6c 100644 --- a/src/main/java/electrosphere/renderer/model/Material.java +++ b/src/main/java/electrosphere/renderer/model/Material.java @@ -1,6 +1,7 @@ package electrosphere.renderer.model; import electrosphere.engine.Globals; +import electrosphere.renderer.OpenGLState; import electrosphere.renderer.texture.Texture; import org.lwjgl.assimp.AIMaterial; import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; @@ -68,32 +69,31 @@ public class Material { /** * Applies the material */ - public void apply_material(){ + public void apply_material(OpenGLState openGLState){ //Controls whether the texturePointer should be resolved by looking up the diffuse in asset manager or using the texture pointer already set in this material if(usesFetch){ Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse); if(diffuseTexture != null){ - diffuseTexture.bind(0); - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "material.diffuse"), 0); + diffuseTexture.bind(openGLState,0); + glUniform1i(glGetUniformLocation(Globals.renderingEngine.getOpenGLState().getActiveShader().getShaderId(), "material.diffuse"), 0); } Texture specularTexture = Globals.assetManager.fetchTexture(specular); if(specularTexture != null){ - specularTexture.bind(1); - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "material.specular"), 1); + specularTexture.bind(openGLState,1); + glUniform1i(glGetUniformLocation(Globals.renderingEngine.getOpenGLState().getActiveShader().getShaderId(), "material.specular"), 1); } } else { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texturePointer); + openGLState.glBindTextureUnit(GL_TEXTURE0, texturePointer, GL_TEXTURE_2D); } } - public void apply_material(int diffuse_channel, int specular_channel){ + public void apply_material(OpenGLState openGLState, int diffuse_channel, int specular_channel){ Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse); if(diffuseTexture != null){ - diffuseTexture.bind(diffuse_channel); + diffuseTexture.bind(openGLState,diffuse_channel); } Texture specularTexture = Globals.assetManager.fetchTexture(specular); if(specularTexture != null){ - specularTexture.bind(specular_channel); + specularTexture.bind(openGLState,specular_channel); } } diff --git a/src/main/java/electrosphere/renderer/model/Mesh.java b/src/main/java/electrosphere/renderer/model/Mesh.java index 3b459fa9..b599c33b 100644 --- a/src/main/java/electrosphere/renderer/model/Mesh.java +++ b/src/main/java/electrosphere/renderer/model/Mesh.java @@ -2,6 +2,7 @@ package electrosphere.renderer.model; import electrosphere.engine.Globals; import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum; import electrosphere.renderer.actor.ActorTextureMask; @@ -273,20 +274,20 @@ public class Mesh { uniforms.put(key, o); } - void bufferAllUniforms(){ + void bufferAllUniforms(OpenGLState openGLState){ for(String key : uniforms.keySet()){ Object currentUniformRaw = uniforms.get(key); if(currentUniformRaw instanceof Matrix4f){ Matrix4f currentUniform = (Matrix4f)currentUniformRaw; - glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), key), false, currentUniform.get(new float[16])); + glUniformMatrix4fv(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), key), false, currentUniform.get(new float[16])); } if(currentUniformRaw instanceof Vector3f){ Vector3f currentUniform = (Vector3f)currentUniformRaw; - glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), key), currentUniform.get(BufferUtils.createFloatBuffer(3))); + glUniform3fv(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), key), currentUniform.get(BufferUtils.createFloatBuffer(3))); } if(currentUniformRaw instanceof Integer){ int currentInform = (Integer)currentUniformRaw; - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), key), currentInform); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), key), currentInform); } } } @@ -313,7 +314,7 @@ public class Mesh { * Draws the mesh * @param renderPipelineState The state of the render pipeline */ - public void complexDraw(RenderPipelineState renderPipelineState){ + public void complexDraw(RenderPipelineState renderPipelineState, OpenGLState openGLState){ if(renderPipelineState.getUseMeshShader()){ ShaderProgram selectedProgram = null; @@ -328,7 +329,7 @@ public class Mesh { if(selectedProgram == null){ selectedProgram = shader; } - Globals.renderingEngine.setActiveShader(renderPipelineState, selectedProgram); + openGLState.setActiveShader(renderPipelineState, selectedProgram); } if(renderPipelineState.getUseLight()){ @@ -338,20 +339,20 @@ public class Mesh { //don't buffer as the light manager hasn't initialized } else { LightManager lightManager = Globals.renderingEngine.getLightManager(); - lightManager.bindBuffer(Globals.renderingEngine.getActiveShader().getShaderId()); + lightManager.bindBuffer(openGLState.getActiveShader().getShaderId()); } } if(renderPipelineState.getUseMaterial() && textureMask == null){ if(material == null){ - Globals.materialDefault.apply_material(0,1); - GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "hasTransparency"), 0); + Globals.materialDefault.apply_material(openGLState,0,1); + GL20.glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasTransparency"), 0); } else { - material.apply_material(); + material.apply_material(openGLState); if(material.hasTransparency){ - GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "hasTransparency"), 1); + GL20.glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasTransparency"), 1); } else { - GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "hasTransparency"), 0); + GL20.glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasTransparency"), 0); } } } @@ -373,9 +374,9 @@ public class Mesh { for(Texture texture : textureMask.getTextures()){ // System.out.println(texture.getPath() + " => groundTextures[" + i + "]" + "=>" + (i)); if(texture != null){ - texture.bind(5+i); + texture.bind(openGLState,5+i); } - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), textureMask.getUniformNames().get(i)),5+i); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), textureMask.getUniformNames().get(i)),5+i); i++; } // for(int j = i; j < 10; j++){ @@ -385,9 +386,9 @@ public class Mesh { } if(renderPipelineState.getUseShadowMap()){ - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, Globals.shadowMapTextureLoc); - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "shadowMap"), 3); + openGLState.glActiveTexture(GL_TEXTURE3); + openGLState.glBindTexture(GL_TEXTURE_2D, Globals.shadowMapTextureLoc); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "shadowMap"), 3); } @@ -396,10 +397,10 @@ public class Mesh { //Handle bones // if(bones != null && !bones.isEmpty()){ - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "hasBones"), 1); - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "numBones"), bones.size()); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasBones"), 1); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "numBones"), bones.size()); Iterator boneIterator = boneIdList.iterator(); - float bufferarray[] = new float[16]; + // float bufferarray[] = new float[16]; int incrementer = 0; while (boneIterator.hasNext()){ String boneName = boneIterator.next(); @@ -407,41 +408,42 @@ public class Mesh { String currentUniform = "bones[" + incrementer + "]"; if(currentBone != null){ Matrix4d currentMat = new Matrix4d(currentBone.final_transform); - currentMat.get(bufferarray); + // currentMat.get(bufferarray); // if(boneName.equals("Torso")){ // System.out.println("Found torso bone"); // System.out.println(currentUniform); // System.out.println(currentMat); // } - GL45.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), currentUniform), false, bufferarray); + openGLState.getActiveShader().setUniform(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), currentUniform), currentMat); + // GL45.glUniformMatrix4fv(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), currentUniform), false, bufferarray); } else { // System.out.println("Bonename: " + boneName); // System.exit(1); - GL45.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), currentUniform), false, new float[16]); + GL45.glUniformMatrix4fv(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), currentUniform), false, new float[16]); } incrementer++; } } else { - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "hasBones"), 0); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasBones"), 0); } } else { - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "hasBones"), 0); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasBones"), 0); } if(renderPipelineState.getBufferStandardUniforms()){ //buffer model/view/proj matrices - GL45.glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexModelLoc, false, parent.getModelMatrix().get(new float[16])); - glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexViewLoc, false, Globals.viewMatrix.get(new float[16])); - glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16])); - glUniform3fv(Globals.renderingEngine.getActiveShader().shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3))); - glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16])); - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "frame"), (int)Globals.timekeeper.getNumberOfRenderFramesElapsed()); - glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().getShaderId(), "time"), (float)Globals.timekeeper.getCurrentRendererTime()); + GL45.glUniformMatrix4fv(openGLState.getActiveShader().shaderVertexModelLoc, false, parent.getModelMatrix().get(new float[16])); + glUniformMatrix4fv(openGLState.getActiveShader().shaderVertexViewLoc, false, Globals.viewMatrix.get(new float[16])); + glUniformMatrix4fv(openGLState.getActiveShader().shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16])); + glUniform3fv(openGLState.getActiveShader().shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3))); + glUniformMatrix4fv(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16])); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "frame"), (int)Globals.timekeeper.getNumberOfRenderFramesElapsed()); + glUniform1f(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "time"), (float)Globals.timekeeper.getCurrentRendererTime()); } if(renderPipelineState.getBufferNonStandardUniforms()){ - bufferAllUniforms(); + bufferAllUniforms(openGLState); } if(renderPipelineState.getInstanced()){ diff --git a/src/main/java/electrosphere/renderer/model/Model.java b/src/main/java/electrosphere/renderer/model/Model.java index 3ab21215..b2cf671a 100644 --- a/src/main/java/electrosphere/renderer/model/Model.java +++ b/src/main/java/electrosphere/renderer/model/Model.java @@ -1,5 +1,6 @@ package electrosphere.renderer.model; +import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.actor.ActorBoneRotator; import electrosphere.renderer.actor.ActorMeshMask; @@ -204,7 +205,7 @@ public class Model { * Draws the model * @param renderPipelineState the render pipeline state */ - public void draw(RenderPipelineState renderPipelineState){ + public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState){ Iterator mesh_Iterator = meshes.iterator(); while(mesh_Iterator.hasNext()){ Mesh currentMesh = mesh_Iterator.next(); @@ -218,7 +219,7 @@ public class Model { currentMesh.setTextureMask(textureMap.get(currentMesh.getMeshName())); } //draw - currentMesh.complexDraw(renderPipelineState); + currentMesh.complexDraw(renderPipelineState, openGLState); //reset texture mask currentMesh.setTextureMask(null); //reset shader @@ -232,7 +233,7 @@ public class Model { ShaderProgram original = toDraw.getShader(); ShaderProgram shader = getCorrectShader(shaderMask, toDraw, toDraw.getShader()); toDraw.setShader(shader); - toDraw.complexDraw(renderPipelineState); + toDraw.complexDraw(renderPipelineState, openGLState); toDraw.setShader(original); } } @@ -377,7 +378,7 @@ public class Model { */ public void drawUI(){ for(Mesh m : meshes){ - m.complexDraw(Globals.renderingEngine.getRenderPipelineState()); + m.complexDraw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState()); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java b/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java new file mode 100644 index 00000000..33ae9423 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java @@ -0,0 +1,69 @@ +package electrosphere.renderer.pipelines; + +import org.lwjgl.opengl.GL40; + +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; + +public class CompositePipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + // + //Setup to render screen textures & bind screen framebuffer + // + openGLState.glDepthFunc(GL40.GL_ALWAYS); + // glDepthMask(false); + GL40.glEnable(GL40.GL_BLEND); + GL40.glBlendFunc(GL40.GL_SRC_ALPHA, GL40.GL_ONE_MINUS_SRC_ALPHA); + + RenderingEngine.screenFramebuffer.bind(); + + GL40.glBindVertexArray(RenderingEngine.screenTextureVAO); + + + // + //Draw anime outline + // + openGLState.setActiveShader(renderPipelineState, RenderingEngine.compositeAnimeOutline); + + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE1); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE2); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE3); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.normalsOutlineTexture.getTexturePointer()); + + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + + // + //Composite transparency on top of solids + // + openGLState.setActiveShader(renderPipelineState, RenderingEngine.oitCompositeProgram); + + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE1); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE2); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE3); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyAccumulatorTexture.getTexturePointer()); + openGLState.glActiveTexture(GL40.GL_TEXTURE1); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyRevealageTexture.getTexturePointer()); + + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + GL40.glBindVertexArray(0); + + + + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java new file mode 100644 index 00000000..9483e291 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java @@ -0,0 +1,207 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Matrix4d; +import org.joml.Quaterniond; +import org.joml.Quaternionf; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +import electrosphere.collision.collidable.Collidable; +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.entity.types.hitbox.HitboxData; +import electrosphere.entity.types.hitbox.HitboxUtils; +import electrosphere.game.data.collidable.CollidableTemplate; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.model.Model; +import electrosphere.server.pathfinding.navmesh.NavCube; +import electrosphere.server.pathfinding.navmesh.NavMesh; +import electrosphere.server.pathfinding.navmesh.NavShape; + +public class DebugContentPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + //bind screen fbo + RenderingEngine.screenFramebuffer.bind(); + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + openGLState.glViewport(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); + + /// + /// R E N D E R I N G S T U F F + /// + //Sets the background color. + + + // + // Set render pipeline state + // + renderPipelineState.setUseMeshShader(true); + renderPipelineState.setBufferStandardUniforms(true); + renderPipelineState.setBufferNonStandardUniforms(false); + renderPipelineState.setUseMaterial(true); + renderPipelineState.setUseShadowMap(true); + renderPipelineState.setUseBones(true); + renderPipelineState.setUseLight(true); + + Matrix4d modelTransformMatrix = new Matrix4d(); + + if(Globals.userSettings.graphicsDebugDrawCollisionSpheres()){ + for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){ + if((boolean)currentHitbox.getData(EntityDataStrings.DATA_STRING_DRAW)){ + Model hitboxModel; + HitboxData data = HitboxUtils.getHitboxData(currentHitbox); + if(data.isActive()){ + if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){ + if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere.fbx")) != null){ + Vector3d position = EntityUtils.getPosition(currentHitbox); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere + modelTransformMatrix.scale(data.getRadius() * 2); + hitboxModel.setModelMatrix(modelTransformMatrix); + hitboxModel.draw(renderPipelineState,openGLState); + } + } else if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){ + if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere_1.fbx")) != null){ + Vector3d position = EntityUtils.getPosition(currentHitbox); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere + modelTransformMatrix.scale(data.getRadius() * 2); + hitboxModel.setModelMatrix(modelTransformMatrix); + hitboxModel.draw(renderPipelineState,openGLState); + } + } + } else { + if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere_grey.fbx")) != null){ + Vector3d position = EntityUtils.getPosition(currentHitbox); + modelTransformMatrix.identity(); + modelTransformMatrix.translate(new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera))); + // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere + modelTransformMatrix.scale(data.getRadius() * 2); + hitboxModel.setModelMatrix(modelTransformMatrix); + hitboxModel.draw(renderPipelineState,openGLState); + } + } + } + } + } + + if(Globals.userSettings.graphicsDebugDrawPhysicsObjects()){ + Model physicsGraphicsModel; + for(Collidable collidable : Globals.clientSceneWrapper.getCollisionEngine().getCollidables()){ + Entity physicsEntity = collidable.getParent(); + if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE) != null){ + CollidableTemplate template = (CollidableTemplate)physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE); + switch(template.getType()){ + case "CYLINDER": + if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcylinder.fbx")) != null){ + Vector3d position = EntityUtils.getPosition(physicsEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(physicsEntity)); + // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere + modelTransformMatrix.scale(template.getDimension1(),template.getDimension2() * 0.5,template.getDimension3()); + physicsGraphicsModel.setModelMatrix(modelTransformMatrix); + physicsGraphicsModel.draw(renderPipelineState,openGLState); + } + break; + case "CUBE": + if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){ + Vector3d position = EntityUtils.getPosition(physicsEntity); + // Vector3f scale = EntityUtils.getScale(physicsEntity); + Quaterniond rotation = EntityUtils.getRotation(physicsEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(rotation); + // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere + modelTransformMatrix.scale(template.getDimension1(),template.getDimension2(),template.getDimension3()); + physicsGraphicsModel.setModelMatrix(modelTransformMatrix); + physicsGraphicsModel.draw(renderPipelineState,openGLState); + } + break; + } + } + } + for(Collidable collidable : Globals.clientSceneWrapper.getCollisionEngine().getCollidables()){ + Entity physicsEntity = collidable.getParent(); + if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){ + if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE)){ + if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitplane.fbx")) != null){ + Vector3d position = EntityUtils.getPosition(physicsEntity); + Vector3f scale = EntityUtils.getScale(physicsEntity); + Quaterniond rotation = EntityUtils.getRotation(physicsEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(rotation); + // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere + modelTransformMatrix.scale(new Vector3d(scale)); + physicsGraphicsModel.setModelMatrix(modelTransformMatrix); + physicsGraphicsModel.draw(renderPipelineState,openGLState); + } + } else if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE)){ + if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){ + Vector3d position = EntityUtils.getPosition(physicsEntity); + Vector3f scale = EntityUtils.getScale(physicsEntity); + Quaterniond rotation = EntityUtils.getRotation(physicsEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(rotation); + // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere + modelTransformMatrix.scale(new Vector3d(scale)); + physicsGraphicsModel.setModelMatrix(modelTransformMatrix); + physicsGraphicsModel.draw(renderPipelineState,openGLState); + } + } + } + } + } + + if(Globals.userSettings.graphicsDebugDrawNavmesh()){ + Model shapeGraphicsModel; + for(NavMesh mesh : Globals.navMeshManager.getMeshes()){ + for(NavShape shape : mesh.getNodes()){ + if(shape instanceof NavCube){ + if((shapeGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){ + NavCube cube = (NavCube)shape; + Vector3d position = new Vector3d(cube.getMinPoint()).add(cube.getMaxPoint()).mul(0.5); + Vector3f scale = new Vector3f((float)(cube.getMaxPoint().x-cube.getMinPoint().x)/2,(float)(cube.getMaxPoint().y-cube.getMinPoint().y)/2,(float)(cube.getMaxPoint().z-cube.getMinPoint().z)/2); + Quaternionf rotation = new Quaternionf(); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(rotation); + // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere + modelTransformMatrix.scale(new Vector3d(scale)); + shapeGraphicsModel.setModelMatrix(modelTransformMatrix); + shapeGraphicsModel.draw(renderPipelineState,openGLState); + } + } + } + } + } + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java b/src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java new file mode 100644 index 00000000..b8f63421 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java @@ -0,0 +1,80 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityTags; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.actor.Actor; + +/** + * The main content render pipeline without oit passes + */ +public class MainContentNoOITPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + //bind screen fbo + RenderingEngine.screenFramebuffer.bind(); + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + openGLState.glViewport(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); + + GL40.glEnable(GL40.GL_BLEND); + GL40.glBlendFunci(0, GL40.GL_ONE, GL40.GL_ONE); + GL40.glBlendFunci(1, GL40.GL_ZERO, GL40.GL_ONE_MINUS_SRC_COLOR); + GL40.glBlendEquation(GL40.GL_FUNC_ADD); + + /// + /// R E N D E R I N G S T U F F + /// + //Sets the background color. + GL40.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + GL40.glClear(GL40.GL_COLOR_BUFFER_BIT | GL40.GL_DEPTH_BUFFER_BIT); + + + // + // Set render pipeline state + // + renderPipelineState.setUseMeshShader(true); + renderPipelineState.setBufferStandardUniforms(true); + renderPipelineState.setBufferNonStandardUniforms(false); + renderPipelineState.setUseMaterial(true); + renderPipelineState.setUseShadowMap(true); + renderPipelineState.setUseBones(true); + renderPipelineState.setUseLight(true); + + // + // D R A W A L L E N T I T I E S + // + for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) + ){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + //calculate and apply model transform + RenderingEngine.modelTransformMatrix.identity(); + RenderingEngine.modelTransformMatrix.translate(cameraModifiedPosition); + RenderingEngine.modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + RenderingEngine.modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); + currentActor.applyModelMatrix(RenderingEngine.modelTransformMatrix); + //draw + currentActor.draw(renderPipelineState,openGLState); + } + } + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java new file mode 100644 index 00000000..db561da6 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java @@ -0,0 +1,218 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Matrix4d; +import org.joml.Matrix4f; +import org.joml.Quaterniond; +import org.joml.Quaternionf; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityTags; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum; +import electrosphere.renderer.actor.Actor; +import electrosphere.renderer.actor.instance.InstancedActor; +import electrosphere.renderer.buffer.ShaderAttribute; + +/** + * The main render pipeline with OIT pass + */ +public class MainContentPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + + Matrix4d modelTransformMatrix = new Matrix4d(); + + //bind screen fbo + RenderingEngine.screenFramebuffer.bind(); + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + openGLState.glViewport(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); + + /// + /// R E N D E R I N G S T U F F + /// + //Sets the background color. + GL40.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + GL40.glClear(GL40.GL_COLOR_BUFFER_BIT | GL40.GL_DEPTH_BUFFER_BIT); + + + // + // Set render pipeline state + // + renderPipelineState.setSelectedShader(SelectedShaderEnum.PRIMARY); + renderPipelineState.setUseMeshShader(true); + renderPipelineState.setBufferStandardUniforms(true); + renderPipelineState.setBufferNonStandardUniforms(false); + renderPipelineState.setUseMaterial(true); + renderPipelineState.setUseShadowMap(true); + renderPipelineState.setUseBones(true); + renderPipelineState.setUseLight(true); + + + // + // Pass One: Solids + // + + // + // D R A W A L L E N T I T I E S + // + for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && + currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null + ){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + //calculate and apply model transform + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); + currentActor.applyModelMatrix(modelTransformMatrix); + //draw + currentActor.draw(renderPipelineState,openGLState); + } + } + for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) != null && + currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null + ){ + //fetch actor + InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity); + //if the shader attribute for model matrix exists, calculate the model matrix and apply + if(InstancedActor.getInstanceModelAttribute(currentEntity) != null){ + ShaderAttribute modelAttribute = InstancedActor.getInstanceModelAttribute(currentEntity); + //calculate model matrix + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + Quaterniond rotation = EntityUtils.getRotation(currentEntity); + // modelTransformMatrix.identity(); + modelTransformMatrix.identity().translationRotateScale( + cameraModifiedPosition, + new Quaternionf((float)rotation.x,(float)rotation.y,(float)rotation.z,(float)rotation.w), + new Vector3f(EntityUtils.getScale(currentEntity)) + ); + //set actor value + currentActor.setAttribute(modelAttribute, new Matrix4f(modelTransformMatrix)); + //draw + currentActor.draw(renderPipelineState, new Vector3d(cameraModifiedPosition)); + } else { + currentActor.draw(renderPipelineState); + } + } + } + //draw all instanced models + Globals.clientInstanceManager.draw(renderPipelineState,openGLState); + + // + // Pass Two: Transparency Accumulator + Revealage + // + // glDisable(GL_DEPTH_TEST); + GL40.glDepthMask(false); + GL40.glEnable(GL40.GL_BLEND); + GL40.glBlendFunci(0, GL40.GL_ONE, GL40.GL_ONE); + GL40.glBlendFunci(1, GL40.GL_ZERO, GL40.GL_ONE_MINUS_SRC_COLOR); + GL40.glBlendEquation(GL40.GL_FUNC_ADD); + + RenderingEngine.transparencyBuffer.bind(); + GL40.glClearBufferfv(GL40.GL_COLOR,0,RenderingEngine.transparencyAccumulatorClear); + GL40.glClearBufferfv(GL40.GL_COLOR,1,RenderingEngine.transparencyRevealageClear); + + // + // Set render pipeline state + // + renderPipelineState.setUseMeshShader(true); + renderPipelineState.setSelectedShader(SelectedShaderEnum.OIT); + openGLState.glDepthFunc(GL40.GL_LEQUAL); + + // + //!!!WARNING!!! + //Comments on function: + //If you're going "gee wilikers I don't know why the back planes of my transparent-labeled aren't showing through the transparency", this is for you + //The transparent pass receives the depth buffer of the opaque pass and IS DEPTH MASK CULLED + //This means if you draw the transparent object in the depth pass, it will not draw in the transparent pass as it is culled + // + //!!!WARNING!!! + //TLDR OF ABOVE: DO NOT DRAW TRANSPARENT OBJECTS IN OPAQUE PASS + // + + + for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && + currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null + ){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + //calculate and apply model transform + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); + currentActor.applyModelMatrix(modelTransformMatrix); + //draw + currentActor.draw(renderPipelineState,openGLState); + } + } + for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) != null && + currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null + ){ + //fetch actor + InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity); + //if the shader attribute for model matrix exists, calculate the model matrix and apply + if(InstancedActor.getInstanceModelAttribute(currentEntity) != null){ + ShaderAttribute modelAttribute = InstancedActor.getInstanceModelAttribute(currentEntity); + //calculate model matrix + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + Quaterniond rotation = EntityUtils.getRotation(currentEntity); + // modelTransformMatrix.identity(); + modelTransformMatrix.identity().translationRotateScale( + cameraModifiedPosition, + new Quaternionf((float)rotation.x,(float)rotation.y,(float)rotation.z,(float)rotation.w), + new Vector3f(EntityUtils.getScale(currentEntity)) + ); + //set actor value + currentActor.setAttribute(modelAttribute, new Matrix4f(modelTransformMatrix)); + //draw + currentActor.draw(renderPipelineState, new Vector3d(cameraModifiedPosition)); + } else { + currentActor.draw(renderPipelineState); + } + } + } + //draw all instanced models + Globals.clientInstanceManager.draw(renderPipelineState,openGLState); + + + // + // Set render pipeline state + // + renderPipelineState.setSelectedShader(SelectedShaderEnum.PRIMARY); + + + +// glBindVertexArray(0); + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java b/src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java new file mode 100644 index 00000000..177dffcf --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java @@ -0,0 +1,88 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Matrix4d; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityTags; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.actor.Actor; + +public class NormalsForOutlinePipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + /* + gameImageNormalsTexture; + static Framebuffer gameImageNormalsFramebuffer; + static ShaderProgram renderNormalsShader; + */ + + //bind screen fbo + RenderingEngine.gameImageNormalsFramebuffer.bind(); + openGLState.glDepthTest(true); + GL40.glDisable(GL40.GL_BLEND); + GL40.glBlendFunc(GL40.GL_SRC_ALPHA, GL40.GL_ONE_MINUS_SRC_ALPHA); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + + openGLState.glViewport(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); + + /// + /// R E N D E R I N G S T U F F + /// + //Sets the background color. + GL40.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + GL40.glClear(GL40.GL_COLOR_BUFFER_BIT | GL40.GL_DEPTH_BUFFER_BIT); + + + + // + // Set render pipeline state + // + renderPipelineState.setUseMeshShader(false); + renderPipelineState.setBufferStandardUniforms(true); + renderPipelineState.setBufferNonStandardUniforms(false); + renderPipelineState.setUseMaterial(true); + renderPipelineState.setUseShadowMap(true); + renderPipelineState.setUseBones(true); + renderPipelineState.setUseLight(true); + + + + Matrix4d modelTransformMatrix = new Matrix4d(); + + openGLState.setActiveShader(renderPipelineState, RenderingEngine.renderNormalsShader); + + for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && + currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null && + currentEntity.getData(EntityDataStrings.DRAW_OUTLINE) != null + ){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + //calculate and apply model transform + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); + currentActor.applyModelMatrix(modelTransformMatrix); + //draw + currentActor.draw(renderPipelineState,openGLState); + } + } + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java b/src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java new file mode 100644 index 00000000..bfb44292 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java @@ -0,0 +1,45 @@ +package electrosphere.renderer.pipelines; + +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.shader.ShaderProgram; + +/** + * Post processing pipeline + */ +public class PostProcessingPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + // + // Outline normals + // + + RenderingEngine.normalsOutlineFrambuffer.bind(); + ShaderProgram program = Globals.assetManager.fetchShader("Shaders/anime/outlineNormals.vs", null, "Shaders/anime/outlineNormals.fs"); + if(program != null){ + openGLState.setActiveShader(renderPipelineState, program); + + GL40.glBindVertexArray(RenderingEngine.screenTextureVAO); + + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE1); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE2); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE3); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.gameImageNormalsTexture.getTexturePointer()); + + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + GL40.glBindVertexArray(0); + } + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/RenderPipeline.java b/src/main/java/electrosphere/renderer/pipelines/RenderPipeline.java new file mode 100644 index 00000000..acd5db18 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/RenderPipeline.java @@ -0,0 +1,17 @@ +package electrosphere.renderer.pipelines; + +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; + +/** + * A render pipeline + */ +public interface RenderPipeline { + + /** + * Executes the pipeline + * @param renderPipelineState the current state of the rendering engine + */ + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState); + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java b/src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java new file mode 100644 index 00000000..d547b473 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java @@ -0,0 +1,76 @@ +package electrosphere.renderer.pipelines; + +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; + +/** + * Renders the screen + */ +public class RenderScreenPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + // + //unbind texture channels + // + //What does this mean? + //essentially there are two channels we're using to draw mesh textures + //we have to glBindTexture to pointer 0 for BOTH channels, otherwise + //the leftover texture gets used to draw the screen framebuffer quad + //which doesnt work + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE1); + GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE2); + GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE3); + GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + + openGLState.glDepthTest(false); + openGLState.glViewport(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + + + + //render full screen quad + openGLState.setActiveShader(renderPipelineState, RenderingEngine.screenTextureShaders); + GL40.glBindVertexArray(RenderingEngine.screenTextureVAO); + //aaa + switch(RenderingEngine.outputFramebuffer){ + case 0: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.screenFramebuffer.getTexturePointer()); + break; + case 1: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.lightDepthBuffer.getTexturePointer()); + break; + case 2: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.volumeDepthBackfaceTexture.getTexturePointer()); + break; + case 3: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.volumeDepthFrontfaceTexture.getTexturePointer()); + break; + case 4: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyAccumulatorTexture.getTexturePointer()); + break; + case 5: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.gameImageNormalsTexture.getTexturePointer()); + break; + case 6: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.normalsOutlineTexture.getTexturePointer()); + break; + case 7: + openGLState.setActiveShader(renderPipelineState, RenderingEngine.drawChannel); + GL40.glUniform1f(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "channel"),4); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.screenTextureDepth.getTexturePointer()); + break; + } + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + GL40.glBindVertexArray(0); + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java b/src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java new file mode 100644 index 00000000..c677a36a --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java @@ -0,0 +1,110 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Matrix4d; +import org.joml.Matrix4f; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityTags; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.actor.Actor; + +/** + * Shadow map pipeline + */ +public class ShadowMapPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Matrix4d modelTransformMatrix = new Matrix4d(); + + //set the viewport to shadow map size + openGLState.glViewport(4096, 4096); + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_ALWAYS); + + openGLState.setActiveShader(renderPipelineState, RenderingEngine.lightDepthShaderProgram); + + RenderingEngine.lightDepthBuffer.bind(); + GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT); + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + + float eyeX = -1.0f; + float eyeY = 10.0f; + float eyeZ = -5.5f; + float nearPlane = 0.01f; + float eyeDist = (float)Math.sqrt(eyeX * eyeX + eyeY * eyeY + eyeZ * eyeZ); + float farPlane = eyeDist + 10.0f; + float sidesMagnitude = (float)Math.sqrt(eyeDist); + //set matrices for light render + Matrix4f lightProjection = new Matrix4f().setOrtho(-sidesMagnitude, sidesMagnitude, -sidesMagnitude, sidesMagnitude, nearPlane, farPlane);//glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); + Matrix4f lightView = new Matrix4f().setLookAt( + new Vector3f(eyeX, eyeY, eyeZ), + new Vector3f( 0.0f, 0.0f, 0.0f), + new Vector3f( 0.0f, 1.0f, 0.0f) + ); + Globals.lightDepthMatrix = new Matrix4f(lightProjection).mul(lightView); + + GL40.glUniformMatrix4fv(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16])); + + // glCullFace(GL_FRONT); + + // + // Set render pipeline state + // + renderPipelineState.setUseMeshShader(false); + renderPipelineState.setBufferStandardUniforms(true); + renderPipelineState.setBufferNonStandardUniforms(true); + renderPipelineState.setUseMaterial(false); + renderPipelineState.setUseShadowMap(false); + renderPipelineState.setUseBones(true); + renderPipelineState.setUseLight(false); + + // + // D R A W A L L E N T I T I E S + // + modelTransformMatrix = new Matrix4d(); + for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && + currentEntity.containsKey(EntityDataStrings.DRAW_CAST_SHADOW) + ){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + //calculate camera-modified vector3f + Vector3f cameraCenter = CameraEntityUtils.getCameraCenter(Globals.playerCamera); + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(cameraCenter); + //calculate and apply model transform + modelTransformMatrix = modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); + currentActor.applyModelMatrix(modelTransformMatrix); + //draw + currentActor.draw(renderPipelineState,openGLState); + } + } + + + + //reset texture + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + //bind default framebuffer + openGLState.glBindFramebuffer(GL40.GL_FRAMEBUFFER,0); + //reset the viewport to screen size + openGLState.glViewport(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + //resume culling backface +// glCullFace(GL_BACK); + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java b/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java new file mode 100644 index 00000000..24a47669 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java @@ -0,0 +1,78 @@ +package electrosphere.renderer.pipelines; + +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.texture.Texture; +import electrosphere.renderer.ui.DrawableElement; +import electrosphere.renderer.ui.Element; + +/** + * Main ui rendering pipeline + */ +public class UIPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + + // + //Black background + // + if(Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND){ + GL40.glUseProgram(RenderingEngine.screenTextureShaders.getShaderId()); + openGLState.glDepthTest(false); + GL40.glBindVertexArray(RenderingEngine.screenTextureVAO); + Texture blackTexture = Globals.assetManager.fetchTexture(Globals.blackTexture); + if(blackTexture != null){ + blackTexture.bind(openGLState); + } + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + GL40.glBindVertexArray(0); + } + + + // + //White background + // + if(Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND){ + GL40.glUseProgram(RenderingEngine.screenTextureShaders.getShaderId()); + openGLState.glDepthTest(false); + GL40.glBindVertexArray(RenderingEngine.screenTextureVAO); + Texture blackTexture = Globals.assetManager.fetchTexture(Globals.offWhiteTexture); + if(blackTexture != null){ + blackTexture.bind(openGLState); + } + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + GL40.glBindVertexArray(0); + } + + + // + // Set render pipeline state + // + if(Globals.RENDER_FLAG_RENDER_UI){ + renderPipelineState.setUseMeshShader(true); + renderPipelineState.setBufferStandardUniforms(false); + renderPipelineState.setBufferNonStandardUniforms(true); + renderPipelineState.setUseMaterial(true); + renderPipelineState.setUseShadowMap(false); + renderPipelineState.setUseBones(false); + renderPipelineState.setUseLight(false); + + openGLState.glDepthTest(false); + for(Element currentElement : Globals.elementManager.getWindowList()){ + if(currentElement instanceof DrawableElement){ + DrawableElement drawable = (DrawableElement) currentElement; + if(drawable.getVisible()){ + drawable.draw(RenderingEngine.GL_DEFAULT_FRAMEBUFFER, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + } + } + } + } + + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java b/src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java new file mode 100644 index 00000000..fa876d03 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java @@ -0,0 +1,194 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Matrix4d; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityTags; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.actor.Actor; + +/** + * Updates the volume buffer + */ +public class VolumeBufferPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Matrix4d modelTransformMatrix = new Matrix4d(); + + //set the viewport to shadow map size + openGLState.glViewport(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + + //stop rendering front faces + GL40.glEnable(GL40.GL_CULL_FACE); + GL40.glCullFace(GL40.GL_FRONT); + + openGLState.setActiveShader(renderPipelineState, RenderingEngine.volumeDepthShaderProgram); + + RenderingEngine.volumeDepthBackfaceFramebuffer.bind(); + GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT); + GL40.glActiveTexture(GL40.GL_TEXTURE0); +// glBindTexture(GL_TEXTURE_2D, woodTexture); +// renderScene(simpleDepthShader); + + GL40.glUniformMatrix4fv(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "view"), false, Globals.viewMatrix.get(new float[16])); + // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, Globals.projectionMatrix.get(new float[16])); + + + + GL40.glUniform1f(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "linearCoef"), RenderingEngine.volumeDepthLinearCoef); + GL40.glUniform1f(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "quadCoef"), RenderingEngine.volumeDepthQuadCoef); + + GL40.glUniform1f(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "near"), 0.1f); + GL40.glUniform1f(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "far"), 100f); + +// glCullFace(GL_FRONT); + + // + // Set render pipeline state + // + renderPipelineState.setUseMeshShader(false); + renderPipelineState.setBufferStandardUniforms(false); + renderPipelineState.setBufferNonStandardUniforms(true); + renderPipelineState.setUseMaterial(false); + renderPipelineState.setUseShadowMap(false); + renderPipelineState.setUseBones(true); + renderPipelineState.setUseLight(false); + + + // + // D R A W A L L E N T I T I E S + // + for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && + currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC) + ){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + //set projection matrix + // if(cameraModifiedPosition.length() > 2f){ + // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, farVolumeProjectionMatrix.get(new float[16])); + // } else if(cameraModifiedPosition.length() > 0.5f){ + // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, midVolumeProjectionMatrix.get(new float[16])); + // } else { + GL40.glUniformMatrix4fv(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "projection"), false, RenderingEngine.nearVolumeProjectionMatrix.get(new float[16])); + // } + // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, Globals.projectionMatrix.get(new float[16])); + //calculate and apply model transform + modelTransformMatrix = modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); + currentActor.applyModelMatrix(modelTransformMatrix); + //draw +// if(!currentEntity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) && !currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE)){ + currentActor.draw(renderPipelineState,openGLState); +// System.out.println(currentActor.modelPath); +// } + } + } + + // + //Draw front faces of all non-volumetrics + // + for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && + !currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC) + ){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + //set projection matrix + GL40.glUniformMatrix4fv(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "projection"), false, RenderingEngine.nearVolumeProjectionMatrix.get(new float[16])); + modelTransformMatrix = modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); + currentActor.applyModelMatrix(modelTransformMatrix); + currentActor.draw(renderPipelineState,openGLState); + } + } + + + + //stop rendering front faces + GL40.glEnable(GL40.GL_CULL_FACE); + GL40.glCullFace(GL40.GL_BACK); + + openGLState.setActiveShader(renderPipelineState, RenderingEngine.volumeDepthShaderProgram); + + RenderingEngine.volumeDepthFrontfaceFramebuffer.bind(); + GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT); + openGLState.glActiveTexture(GL40.GL_TEXTURE0); +// glBindTexture(GL_TEXTURE_2D, woodTexture); +// renderScene(simpleDepthShader); + + // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "view"), false, Globals.viewMatrix.get(new float[16])); + // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, Globals.projectionMatrix.get(new float[16])); + + + + // GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "linearCoef"), volumeDepthLinearCoef); + // GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "quadCoef"), volumeDepthQuadCoef); + +// glCullFace(GL_FRONT); + + // + // D R A W A L L E N T I T I E S + // + for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && + currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC) + ){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + //calculate and apply model transform + modelTransformMatrix = modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); + currentActor.applyModelMatrix(modelTransformMatrix); + //draw +// if(!currentEntity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) && !currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE)){ + currentActor.draw(renderPipelineState,openGLState); +// System.out.println(currentActor.modelPath); +// } + } + } + + GL40.glCullFace(GL40.GL_BACK); + //now cull back faces + + //reset texture + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + //bind default framebuffer + openGLState.glBindFramebuffer(GL40.GL_FRAMEBUFFER,0); + //resume culling backface + GL40.glDisable(GL40.GL_CULL_FACE); + } + +} diff --git a/src/main/java/electrosphere/renderer/shader/ShaderProgram.java b/src/main/java/electrosphere/renderer/shader/ShaderProgram.java index aba9aeff..cbb65ed6 100644 --- a/src/main/java/electrosphere/renderer/shader/ShaderProgram.java +++ b/src/main/java/electrosphere/renderer/shader/ShaderProgram.java @@ -22,12 +22,19 @@ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import javax.management.RuntimeErrorException; +import org.joml.Matrix4d; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL40; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; @@ -60,16 +67,18 @@ public class ShaderProgram { //Uniforms - //list of names of all uniforms in the shader - // public List uniformList; - //map - //string -> tuple - //tuple: a string describing the type of the data,the current value,location - //ie arrayVec3,[<1,0,0>,<2,0,0>],colors - // Mat4,[Matrix4f],modelMatrix - // public Map uniformMap; + public Map uniformMap = new HashMap(); + + //keeps track of programs that have already been compiled and returns them instead of recompiling from scratch + static Map alreadyCompiledMap = new HashMap(); public static ShaderProgram smart_assemble_shader(boolean ContainsBones, boolean apply_lighting){ + + //return shader if it has already been compiled + String shaderKey = ContainsBones + "-" + apply_lighting; + if(alreadyCompiledMap.containsKey(shaderKey)){ + return alreadyCompiledMap.get(shaderKey); + } String vertex_shader_path = ""; if(ContainsBones){ @@ -185,7 +194,7 @@ public class ShaderProgram { rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderId, "hasBones"); - + alreadyCompiledMap.put(shaderKey,rVal); return rVal; } @@ -198,6 +207,12 @@ public class ShaderProgram { * @return The int-pointer to the shader compiled */ public static ShaderProgram smartAssembleOITProgram(boolean ContainsBones, boolean apply_lighting){ + + //return shader if it has already been compiled + String shaderKey = "oit" + ContainsBones + "-" + apply_lighting; + if(alreadyCompiledMap.containsKey(shaderKey)){ + return alreadyCompiledMap.get(shaderKey); + } String vertex_shader_path = ""; if(ContainsBones){ @@ -313,7 +328,7 @@ public class ShaderProgram { rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderId, "hasBones"); - + alreadyCompiledMap.put(shaderKey,rVal); return rVal; } @@ -721,6 +736,33 @@ public class ShaderProgram { return rVal; } + /** + * Sets the value of a uniform on this shader + * @param uniformLocation the uniform location + * @param value the value + */ + public void setUniform(int uniformLocation, Object value){ + if(!uniformMap.containsKey(uniformLocation) || !uniformMap.get(uniformLocation).equals(value)){ + uniformMap.put(uniformLocation,value); + if(value instanceof Matrix4f){ + Matrix4f currentUniform = (Matrix4f)value; + GL40.glUniformMatrix4fv(uniformLocation, false, currentUniform.get(new float[16])); + } + if(value instanceof Matrix4d){ + Matrix4d currentUniform = (Matrix4d)value; + GL40.glUniformMatrix4fv(uniformLocation, false, currentUniform.get(new float[16])); + } + if(value instanceof Vector3f){ + Vector3f currentUniform = (Vector3f)value; + GL40.glUniform3fv(uniformLocation, currentUniform.get(BufferUtils.createFloatBuffer(3))); + } + if(value instanceof Integer){ + int currentInform = (Integer)value; + GL40.glUniform1i(uniformLocation, currentInform); + } + } + } + /** * Gets the id of the shader diff --git a/src/main/java/electrosphere/renderer/texture/Texture.java b/src/main/java/electrosphere/renderer/texture/Texture.java index 8bae4a3a..f7166ca3 100644 --- a/src/main/java/electrosphere/renderer/texture/Texture.java +++ b/src/main/java/electrosphere/renderer/texture/Texture.java @@ -7,6 +7,7 @@ package electrosphere.renderer.texture; import electrosphere.engine.Globals; import electrosphere.engine.Main; +import electrosphere.renderer.OpenGLState; import electrosphere.util.FileUtils; import java.awt.Color; import java.awt.image.BufferedImage; @@ -201,14 +202,16 @@ public class Texture { } } - public void bind(){ - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texturePointer); + public void bind(OpenGLState openGLState){ + // openGLState.glActiveTexture(GL_TEXTURE0); + // openGLState.glBindTexture(GL_TEXTURE_2D, texturePointer); + openGLState.glBindTextureUnit(GL_TEXTURE0,texturePointer,GL_TEXTURE_2D); } - public void bind(int attrib_val){ - glActiveTexture(GL_TEXTURE0 + attrib_val); - glBindTexture(GL_TEXTURE_2D, texturePointer); + public void bind(OpenGLState openGLState, int attrib_val){ + openGLState.glBindTextureUnit(GL_TEXTURE0 + attrib_val,texturePointer,GL_TEXTURE_2D); + // openGLState.glActiveTexture(GL_TEXTURE0 + attrib_val); + // openGLState.glBindTexture(GL_TEXTURE_2D, texturePointer); } public boolean isTransparent(){ diff --git a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java index 68c06b2f..ebe20260 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java @@ -120,7 +120,7 @@ public class ActorPanel implements DrawableElement, DraggableElement { actor.applyModelMatrix(modelMatrix); - actor.draw(Globals.renderingEngine.getRenderPipelineState()); + actor.draw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState()); RenderingEngine.setFOV(Globals.verticalFOV); RenderingEngine.setAspectRatio(Globals.aspectRatio); @@ -142,7 +142,7 @@ public class ActorPanel implements DrawableElement, DraggableElement { Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); - Globals.renderingEngine.setActiveShader( + Globals.renderingEngine.getOpenGLState().setActiveShader( Globals.renderingEngine.getRenderPipelineState(), Globals.assetManager.fetchShader("Shaders/ui/windowContent/windowContent.vs", null, "Shaders/ui/windowContent/windowContent.fs") ); @@ -173,7 +173,7 @@ public class ActorPanel implements DrawableElement, DraggableElement { planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); planeModel.getMeshes().get(0).setMaterial(customMat); - planeModel.draw(Globals.renderingEngine.getRenderPipelineState()); + planeModel.draw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState()); } else { LoggerInterface.loggerRenderer.ERROR("Actor Panel unable to find plane model!!", new Exception()); }