package electrosphere.renderer; import static electrosphere.renderer.RenderUtils.createScreenTextureVAO; import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR; import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR; import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_CORE_PROFILE; import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_PROFILE; import static org.lwjgl.glfw.GLFW.glfwCreateWindow; import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor; import static org.lwjgl.glfw.GLFW.glfwInit; import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent; import static org.lwjgl.glfw.GLFW.glfwMaximizeWindow; import static org.lwjgl.glfw.GLFW.glfwPollEvents; import static org.lwjgl.glfw.GLFW.glfwSwapBuffers; import static org.lwjgl.glfw.GLFW.glfwTerminate; import static org.lwjgl.glfw.GLFW.glfwWindowHint; import static org.lwjgl.opengl.GL11.GL_ALWAYS; import static org.lwjgl.opengl.GL45.GL_LEQUAL; import static org.lwjgl.opengl.GL11.GL_BLEND; import static org.lwjgl.opengl.GL11.GL_COLOR; import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; import static org.lwjgl.opengl.GL11.GL_LESS; import static org.lwjgl.opengl.GL11.GL_ONE; import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_COLOR; import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; import static org.lwjgl.opengl.GL11.GL_TRIANGLES; import static org.lwjgl.opengl.GL11.GL_ZERO; import static org.lwjgl.opengl.GL11.glBindTexture; import static org.lwjgl.opengl.GL11.glBlendFunc; import static org.lwjgl.opengl.GL11.glClear; import static org.lwjgl.opengl.GL11.glClearColor; import static org.lwjgl.opengl.GL11.glDepthFunc; import static org.lwjgl.opengl.GL11.glDepthMask; import static org.lwjgl.opengl.GL11.glDisable; import static org.lwjgl.opengl.GL11.glDrawArrays; import static org.lwjgl.opengl.GL11.glEnable; import static org.lwjgl.opengl.GL11.glViewport; import static org.lwjgl.opengl.GL13.GL_TEXTURE0; import static org.lwjgl.opengl.GL13.GL_TEXTURE1; import static org.lwjgl.opengl.GL13.GL_TEXTURE2; import static org.lwjgl.opengl.GL13.GL_TEXTURE3; import static org.lwjgl.opengl.GL13.glActiveTexture; import static org.lwjgl.opengl.GL14.GL_FUNC_ADD; import static org.lwjgl.opengl.GL14.glBlendEquation; import static org.lwjgl.opengl.GL20.glGetUniformLocation; import static org.lwjgl.opengl.GL20.glUniform1f; import static org.lwjgl.opengl.GL20.glUniformMatrix4fv; import static org.lwjgl.opengl.GL20.glUseProgram; import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER; import static org.lwjgl.opengl.GL30.GL_RENDERBUFFER; import static org.lwjgl.opengl.GL30.glBindFramebuffer; import static org.lwjgl.opengl.GL30.glBindRenderbuffer; import static org.lwjgl.opengl.GL30.glBindVertexArray; import static org.lwjgl.opengl.GL30.glClearBufferfv; import static org.lwjgl.opengl.GL40.glBlendFunci; import static org.lwjgl.system.MemoryUtil.NULL; import java.nio.IntBuffer; import java.util.LinkedList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.joml.Matrix4d; import org.joml.Matrix4f; import org.joml.Quaterniond; import org.joml.Quaternionf; import org.joml.Sphered; 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; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import electrosphere.collision.collidable.Collidable; 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.entity.types.hitbox.HitboxData; import electrosphere.entity.types.hitbox.HitboxUtils; import electrosphere.game.data.collidable.CollidableTemplate; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.instance.InstancedActor; import electrosphere.renderer.buffer.ShaderAttribute; import electrosphere.renderer.debug.DebugRendering; import electrosphere.renderer.framebuffer.Framebuffer; 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; import electrosphere.renderer.ui.Element; import electrosphere.renderer.ui.imgui.ImGuiLinePlot; import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiLinePlot.ImGuiLinePlotDataset; import electrosphere.server.pathfinding.navmesh.NavCube; import electrosphere.server.pathfinding.navmesh.NavMesh; import electrosphere.server.pathfinding.navmesh.NavShape; import imgui.ImGui; import imgui.extension.implot.ImPlot; import imgui.gl3.ImGuiImplGl3; import imgui.glfw.ImGuiImplGlfw; import imgui.internal.ImGuiContext; public class RenderingEngine { public static final int GL_DEFAULT_FRAMEBUFFER = 0; public static final int GL_DEFAULT_RENDERBUFFER = 0; 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; // //imgui related // //imgui internal objects private static final ImGuiImplGlfw imGuiGlfw = new ImGuiImplGlfw(); private static final ImGuiImplGl3 imGuiGl13 = new ImGuiImplGl3(); //the version of glsl to init imgui with private static String glslVersion = null; //the context pointer for the core imgui objects private static ImGuiContext imGuiContext = null; //if set to true, will render imgui windows private static boolean imGuiShouldRender = true; //All imgui windows that should be displayed private static List imGuiWindows = new CopyOnWriteArrayList(); //depth framebuffer/shader for shadow mapping public static ShaderProgram lightDepthShaderProgram; public static Framebuffer lightDepthBuffer; //framebuffers for transparent textures 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 */ public static Texture gameImageNormalsTexture; public static Framebuffer gameImageNormalsFramebuffer; public static ShaderProgram renderNormalsShader; /* Perspective volumetrics */ 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 */ public static Matrix4d modelTransformMatrix = new Matrix4d(); /* Vertical volumetrics TODO: implement */ // static Texture volumeVerticalBackfaceTexture; // static Framebuffer volumeVerticalBackfaceBuffer; // static Texture volumeVerticalFrontfaceTexture; // static Framebuffer volumeVerticalFrontfaceBuffer; /* Post processing effects (ie kernels) textures, framebuffers, shaders */ public static Texture normalsOutlineTexture; public static Framebuffer normalsOutlineFrambuffer; public static ShaderProgram normalsOutlineShader; /* compositing functions */ public static ShaderProgram compositeAnimeOutline; // public static boolean renderHitboxes = false; // public static boolean renderPhysics = false; LightManager lightManager; public static int outputFramebuffer = 0; //used in calculating projection matrix static float aspectRatio = 1.0f; static float verticalFOV = 90.0f; //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(){ LoggerInterface.loggerRenderer.INFO("Create OpenGL Context"); //Initializes opengl glfwInit(); //Gives hints to glfw to control how opengl will be used glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); glslVersion = "#version 410"; glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); Allows you to make the background transparent // glfwWindowHint(GLFW_OPACITY, 23); //Creates the window reference object if(Globals.userSettings.displayFullscreen()){ //below line is for fullscreen Globals.window = glfwCreateWindow(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, "ORPG", glfwGetPrimaryMonitor(), NULL); } else { Globals.window = glfwCreateWindow(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, "ORPG", NULL, NULL); } // Errors for failure to create window (IE: No GUI mode on linux ?) if (Globals.window == NULL) { LoggerInterface.loggerEngine.ERROR("Failed to make window.", new Exception("Renderer Creation Failure")); glfwTerminate(); } //set resize callback 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 glfwMaximizeWindow(Globals.window); //grab actual framebuffer IntBuffer xBuffer = BufferUtils.createIntBuffer(1); IntBuffer yBuffer = BufferUtils.createIntBuffer(1); GLFW.glfwGetFramebufferSize(Globals.window, xBuffer, yBuffer); int bufferWidth = xBuffer.get(); int bufferHeight = yBuffer.get(); //get title bar size Globals.WINDOW_TITLE_BAR_HEIGHT = Globals.WINDOW_HEIGHT - bufferHeight; // System.out.println(Globals.WINDOW_TITLE_BAR_HEIGHT); Globals.WINDOW_WIDTH = bufferWidth; Globals.WINDOW_HEIGHT = bufferHeight; // // Attack controls callbacks // //set key callback GLFW.glfwSetKeyCallback(Globals.window, Globals.controlCallback); //set mouse callback GLFW.glfwSetMouseButtonCallback(Globals.window, Globals.mouseCallback); //get title bar dimensions // setTitleBarDimensions(); //Creates the OpenGL capabilities for the program. GL.createCapabilities(); //init imgui (must happen after gl.createCapabilities) imGuiContext = ImGui.createContext(); ImPlot.createContext(); imGuiGlfw.init(Globals.window,true); imGuiGl13.init(glslVersion); //This enables Z-buffering so that farther-back polygons are not drawn over nearer ones glEnable(GL_DEPTH_TEST); // Support for transparency glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //this disables vsync to make game run faster //https://stackoverflow.com/questions/55598376/glfwswapbuffers-is-slow if(!Globals.userSettings.graphicsPerformanceEnableVSync()){ GLFW.glfwSwapInterval(0); } // //Hide the cursor and capture it // glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //init screen rendering quadrant screenTextureVAO = createScreenTextureVAO(); // initScreenTextureShaderProgram(); screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/simple1/simple1.vs", "/Shaders/screentexture/simple1/simple1.fs"); // screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.vs", "/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.fs"); //generate framebuffers screenTextureColor = FramebufferUtils.generateScreenTextureColor(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); screenTextureDepth = FramebufferUtils.generateScreenTextureDepth(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); screenFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), screenTextureColor, screenTextureDepth); glBindFramebuffer(GL_FRAMEBUFFER, GL_DEFAULT_FRAMEBUFFER); glBindRenderbuffer(GL_RENDERBUFFER, GL_DEFAULT_RENDERBUFFER); // //Channel debug program // drawChannel = ShaderProgram.loadSpecificShader("/Shaders/screentexture/drawChannel/drawChannel.vs", "/Shaders/screentexture/drawChannel/drawChannel.fs"); // //create light depth framebuffer/shader for shadowmapping // lightDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/lightDepth/lightDepth.vs", "/Shaders/lightDepth/lightDepth.fs"); Globals.depthMapShaderProgramLoc = lightDepthShaderProgram.getShaderId(); lightDepthBuffer = FramebufferUtils.generateDepthBuffer(); Globals.shadowMapTextureLoc = lightDepthBuffer.getTexturePointer(); // glEnable(GL_CULL_FACE); // enabled for shadow mapping // //create volume depth framebuffer/shader for volumetric rendering // volumeDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/volumeBuffer/volumetric.vs", "/Shaders/volumeBuffer/volumetric.fs"); volumeDepthBackfaceTexture = FramebufferUtils.generateDepthBufferTexture(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); volumeDepthBackfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), volumeDepthBackfaceTexture); volumeDepthFrontfaceTexture = FramebufferUtils.generateDepthBufferTexture(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); volumeDepthFrontfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), volumeDepthFrontfaceTexture); // //Game normals // /* gameImageNormalsTexture; static Framebuffer gameImageNormalsFramebuffer; static ShaderProgram renderNormalsShader; */ gameImageNormalsTexture = FramebufferUtils.generateScreenTextureColor(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); Texture gameImageNormalsDepthTexture = FramebufferUtils.generateScreenTextureDepth(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); gameImageNormalsFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), gameImageNormalsTexture, gameImageNormalsDepthTexture); renderNormalsShader = ShaderProgram.loadSpecificShader("Shaders/anime/renderNormals.vs", "Shaders/anime/renderNormals.fs"); // //Transparency framebuffers // transparencyAccumulatorClear = new float[]{0.0f, 0.0f, 0.0f, 0.0f}; transparencyAccumulatorTexture = FramebufferUtils.generateOITAccumulatorTexture(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); transparencyRevealageClear = new float[]{1.0f, 1.0f, 1.0f, 1.0f}; transparencyRevealageTexture = FramebufferUtils.generateOITRevealageTexture(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); transparencyBuffer = FramebufferUtils.generateOITFramebuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), transparencyAccumulatorTexture, transparencyRevealageTexture, screenTextureDepth); oitCompositeProgram = ShaderProgram.loadSpecificShader("Shaders/oit/composite.vs", "Shaders/oit/composite.fs"); //projection matrices nearVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.1f, 100); // //Postprocessing textures and buffers // /* static Texture normalsOutlineTexture; static Framebuffer normalsOutlineFrambuffer; static ShaderProgram normalsOutlineShader; */ normalsOutlineTexture = FramebufferUtils.generateScreenTextureColorAlpha(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); normalsOutlineFrambuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), normalsOutlineTexture); // normalsOutlineShader = ShaderProgram.loadSpecificShader("Shaders/anime/outlineNormals.vs", "Shaders/anime/outlineNormals.fs"); Globals.assetManager.addShaderToQueue("Shaders/anime/outlineNormals.vs", "Shaders/anime/outlineNormals.fs"); // //Compositing shaders // compositeAnimeOutline = ShaderProgram.loadSpecificShader("Shaders/anime/compositeAnimeOutline.vs", "Shaders/anime/compositeAnimeOutline.fs"); //instantiate light manager lightManager = new LightManager(); // //Fog // //enable fog // glEnable(GL_FOG); // //set the equation to use for fog // glFogf(GL_FOG_MODE,GL_LINEAR); //// glFogf(GL_FOG_MODE,GL_EXP2); // //set the density of the fog // glFogf(GL_FOG_DENSITY,1.0f); // //these are applicable for the linear equation // glFogf(GL_FOG_START,0.8f); // glFogf(GL_FOG_END,1.0f); // //fog color // FloatBuffer fogColor = FloatBuffer.allocate(4); // fogColor.put(1.0f); // fogColor.put(1.0f); // fogColor.put(1.0f); // fogColor.put(1.0f); // fogColor.flip(); // GL11.glFogfv(GL_FOG_COLOR, fogColor); // // Projection and View matrix creation // Globals.projectionMatrix = new Matrix4f(); Globals.viewMatrix = new Matrix4f(); verticalFOV = (float)(Globals.verticalFOV * Math.PI /180.0f); //set local aspect ratio and global aspect ratio at the same time aspectRatio = Globals.aspectRatio = Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT; float nearClip = 0.001f; Globals.projectionMatrix.setPerspective(verticalFOV, Globals.aspectRatio, nearClip, Globals.userSettings.getGraphicsViewDistance()); Globals.viewMatrix.translation(new Vector3f(0.0f,0.0f,-3.0f)); } /** * Main function to draw the screen */ public void drawScreen(){ //calculate render angle for frustum culling if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){ updateFrustumBox(); } //generate depth map if(Globals.RENDER_FLAG_RENDER_SHADOW_MAP){ shadowMapPipeline.render(openGLState, renderPipelineState); } //render volume buffer if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){ volumeBufferPipeline.render(openGLState, renderPipelineState); } //Update light buffer lightManager.updateData(); //Render content to the game framebuffer if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){ if(Globals.userSettings.getGraphicsPerformanceOIT()){ mainContentPipeline.render(openGLState, renderPipelineState); } else { mainContentNoOITPipeline.render(openGLState, renderPipelineState); } debugContentPipeline.render(openGLState, renderPipelineState); normalsForOutlinePipeline.render(openGLState, renderPipelineState); postProcessingPipeline.render(openGLState, renderPipelineState); compositePipeline.render(openGLState, renderPipelineState); } //bind default FBO glBindFramebuffer(GL_FRAMEBUFFER,0); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); //Render the game framebuffer texture to a quad if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER){ renderScreenPipeline.render(openGLState, renderPipelineState); } //render ui uiPipeline.render(openGLState, renderPipelineState); //Render boundaries of ui elements if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){ DebugRendering.drawUIBoundsWireframe(); } /** * Render imgui */ if(imGuiShouldRender){ imGuiGlfw.newFrame(); ImGui.newFrame(); for(ImGuiWindow window : imGuiWindows){ window.draw(); } ImGui.render(); imGuiGl13.renderDrawData(ImGui.getDrawData()); } //check for errors // checkError(); //check and call events and swap the buffers LoggerInterface.loggerRenderer.DEBUG("Swap buffers"); glfwSwapBuffers(Globals.window); glfwPollEvents(); } /** * Updates the frustum box of the render pipeline */ void updateFrustumBox(){ renderPipelineState.updateFrustumIntersection(Globals.projectionMatrix, Globals.viewMatrix); } public void bindFramebuffer(int framebufferPointer){ glBindFramebuffer(GL_FRAMEBUFFER, framebufferPointer); } public void setViewportSize(int width, int height){ glViewport(0, 0, width, height); } public void setTitleBarDimensions(){ IntBuffer tLeft = BufferUtils.createIntBuffer(1); IntBuffer tTop = BufferUtils.createIntBuffer(1); IntBuffer tRight = BufferUtils.createIntBuffer(1); IntBuffer tBottom = BufferUtils.createIntBuffer(1); // Get the title bar dims GLFW.glfwGetWindowFrameSize(Globals.window, tLeft, tTop, tRight, tBottom); Globals.WINDOW_TITLE_BAR_HEIGHT = tTop.get(); // System.out.println(tLeft.get() + " " + tTop.get() + " " + tRight.get() + " " + tBottom.get()); } public Texture getVolumeBackfaceTexture(){ return volumeDepthBackfaceTexture; } public Texture getVolumeFrontfaceTexture(){ return volumeDepthFrontfaceTexture; } public LightManager getLightManager(){ return lightManager; } public static void incrementOutputFramebuffer(){ outputFramebuffer++; if(outputFramebuffer > 8){ outputFramebuffer = 0; } } public static void setFOV(float verticalFOV){ RenderingEngine.verticalFOV = verticalFOV; calculateProjectionMatrix(); } public static void setAspectRatio(float aspectRatio){ RenderingEngine.aspectRatio = aspectRatio; calculateProjectionMatrix(); } static void calculateProjectionMatrix(){ float radVerticalFOV = (float)(RenderingEngine.verticalFOV * Math.PI /180.0f); float nearClip = 0.001f; Globals.projectionMatrix.setPerspective(radVerticalFOV, RenderingEngine.aspectRatio, nearClip, Globals.userSettings.getGraphicsViewDistance()); } /** * Adds a window to the rendering engine * @param window The window */ public static void addImGuiWindow(ImGuiWindow window){ imGuiWindows.add(window); } /** * Removes an imgui window from the rendering engine * @param window The window */ public static void removeImGuiWindow(ImGuiWindow window){ imGuiWindows.remove(window); } /** * Gets the current render pipeline state * @return The current render pipeline state */ public RenderPipelineState getRenderPipelineState(){ return renderPipelineState; } /** * Gets the current opengl state * @return */ public OpenGLState getOpenGLState(){ return openGLState; } /** * Tries to recapture the screen */ public static void recaptureIfNecessary(){ if(Globals.controlHandler.shouldRecapture()){ //Makes the window that was just created the current OS-level window context glfwMakeContextCurrent(Globals.window); // //Maximize it glfwMaximizeWindow(Globals.window); //grab focus GLFW.glfwFocusWindow(Globals.window); //apply mouse controls state if(Globals.controlHandler.isMouseVisible()){ Globals.controlHandler.showMouse(); } else { Globals.controlHandler.hideMouse(); } Globals.controlHandler.setRecapture(false); } } /** * Checks for any errors currently caught by OpenGL. * Refer: https://docs.gl/gl4/glGetError */ private static void checkError(){ int error = GL11.glGetError(); String errorInEnglish = ""; switch(error){ case GL11.GL_NO_ERROR: { errorInEnglish = ""; } break; case GL11.GL_INVALID_ENUM: { errorInEnglish = "An unacceptable value is specified for an enumerated argument. The offending command is ignored and has no other side effect than to set the error flag."; } break; case GL11.GL_INVALID_VALUE: { errorInEnglish = "A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag."; } break; case GL11.GL_INVALID_OPERATION: { errorInEnglish = "The specified operation is not allowed in the current state. The offending command is ignored and has no other side effect than to set the error flag."; } break; case GL30.GL_INVALID_FRAMEBUFFER_OPERATION: { errorInEnglish = "The framebuffer object is not complete. The offending command is ignored and has no other side effect than to set the error flag. "; } break; case GL11.GL_OUT_OF_MEMORY: { errorInEnglish = "There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded. "; } break; case GL11.GL_STACK_UNDERFLOW: { errorInEnglish = "An attempt has been made to perform an operation that would cause an internal stack to underflow. "; } break; case GL11.GL_STACK_OVERFLOW: { errorInEnglish = "An attempt has been made to perform an operation that would cause an internal stack to overflow. "; } break; default: { errorInEnglish = "Un-enum'd error " + error; } break; } if(!errorInEnglish.equals("")){ LoggerInterface.loggerRenderer.ERROR(errorInEnglish, new Exception(errorInEnglish)); } } }