1605 lines
		
	
	
		
			74 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			1605 lines
		
	
	
		
			74 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
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 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.BufferUtils;
 | 
						||
import org.lwjgl.glfw.GLFW;
 | 
						||
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.texture.Texture;
 | 
						||
import electrosphere.renderer.ui.DrawableElement;
 | 
						||
import electrosphere.renderer.ui.Element;
 | 
						||
import electrosphere.server.pathfinding.navmesh.NavCube;
 | 
						||
import electrosphere.server.pathfinding.navmesh.NavMesh;
 | 
						||
import electrosphere.server.pathfinding.navmesh.NavShape;
 | 
						||
 | 
						||
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;
 | 
						||
    
 | 
						||
    //depth framebuffer/shader for shadow mapping
 | 
						||
    static ShaderProgram lightDepthShaderProgram;
 | 
						||
    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;
 | 
						||
 | 
						||
    /*
 | 
						||
    render normals
 | 
						||
    */
 | 
						||
    static Texture gameImageNormalsTexture;
 | 
						||
    static Framebuffer gameImageNormalsFramebuffer;
 | 
						||
    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;
 | 
						||
 | 
						||
    /*
 | 
						||
    Necessary static variables for drawing
 | 
						||
     */
 | 
						||
    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
 | 
						||
    */
 | 
						||
    static Texture normalsOutlineTexture;
 | 
						||
    static Framebuffer normalsOutlineFrambuffer;
 | 
						||
    static ShaderProgram normalsOutlineShader;
 | 
						||
 | 
						||
    /*
 | 
						||
    compositing functions
 | 
						||
    */
 | 
						||
    static ShaderProgram compositeAnimeOutline;
 | 
						||
 | 
						||
    
 | 
						||
//    public static boolean renderHitboxes = false;
 | 
						||
//    public static boolean renderPhysics = false;
 | 
						||
 | 
						||
    LightManager lightManager;
 | 
						||
    
 | 
						||
    static float currentViewPlanarAngle;
 | 
						||
    
 | 
						||
    ShaderProgram activeProgram;
 | 
						||
 | 
						||
    static int outputFramebuffer = 0;
 | 
						||
 | 
						||
    //used in calculating projection matrix
 | 
						||
    static float aspectRatio = 1.0f;
 | 
						||
    static float verticalFOV = 90.0f;
 | 
						||
 | 
						||
    static RenderPipelineState renderPipelineState = new RenderPipelineState();
 | 
						||
    
 | 
						||
    
 | 
						||
    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);
 | 
						||
        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
 | 
						||
//        GLFW.glfwSetWindowSizeCallback(Globals.window, new GLFWWindowSizeCallbackI(){
 | 
						||
//            @Override
 | 
						||
//            public void invoke(long window, int width, int height){
 | 
						||
//                Globals.WINDOW_HEIGHT = height;
 | 
						||
//                Globals.WINDOW_WIDTH = width;
 | 
						||
//            }
 | 
						||
//        });
 | 
						||
        //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();
 | 
						||
 | 
						||
        //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.shaderProgram;
 | 
						||
        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));
 | 
						||
    }
 | 
						||
    
 | 
						||
    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);
 | 
						||
    }
 | 
						||
    
 | 
						||
    
 | 
						||
    static boolean drawPoint(Vector3f cameraPos, Vector3f position){
 | 
						||
        boolean rVal = true;
 | 
						||
        float phi = (float)Math.abs((calculateAngle(cameraPos,position) - currentViewPlanarAngle) % (Math.PI * 2.0f));
 | 
						||
        if(phi > Math.PI){
 | 
						||
            phi = (float)(Math.PI * 2) - phi;
 | 
						||
        }
 | 
						||
        float rotationalDiff = phi;
 | 
						||
        float dist = calculateDist(new Vector3f(cameraPos.x,0,cameraPos.z), new Vector3f(position.x,0,position.z));
 | 
						||
        if(rotationalDiff > (Globals.verticalFOV / 180 * Math.PI) && dist > 300){
 | 
						||
            rVal = false;
 | 
						||
        }
 | 
						||
        return rVal;
 | 
						||
    }
 | 
						||
    
 | 
						||
    void calculateRenderingAngle(){
 | 
						||
        currentViewPlanarAngle = calculateAngle(CameraEntityUtils.getCameraEye(Globals.playerCamera), new Vector3f(0,0,0));
 | 
						||
//        System.out.println(currentViewPlanarAngle);
 | 
						||
    }
 | 
						||
    
 | 
						||
    
 | 
						||
    public void drawScreen(){
 | 
						||
        
 | 
						||
        //calculate render angle for frustum culling
 | 
						||
        if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
 | 
						||
            calculateRenderingAngle();
 | 
						||
        }
 | 
						||
        
 | 
						||
        //
 | 
						||
        //first pass: generate depth map
 | 
						||
        //
 | 
						||
        if(Globals.RENDER_FLAG_RENDER_SHADOW_MAP){
 | 
						||
            renderShadowMapContent();
 | 
						||
        }
 | 
						||
 | 
						||
        /*
 | 
						||
        render volume buffer
 | 
						||
        */
 | 
						||
        if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
 | 
						||
            updateVolumeBuffer();
 | 
						||
        }
 | 
						||
        
 | 
						||
        /*
 | 
						||
        Update light buffer
 | 
						||
        */
 | 
						||
        lightManager.updateData();
 | 
						||
 | 
						||
        
 | 
						||
        /*
 | 
						||
        Render content to the game framebuffer
 | 
						||
        */
 | 
						||
        if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
 | 
						||
            if(Globals.userSettings.getGraphicsPerformanceOIT()){
 | 
						||
                renderGameContent();
 | 
						||
            } else {
 | 
						||
                renderGameContentNoOIT();
 | 
						||
            }
 | 
						||
            renderDebugContent();
 | 
						||
            renderNormalsForOutline();
 | 
						||
            applyKernelsAndPostprocessing();
 | 
						||
            compositeGameImage();
 | 
						||
        }
 | 
						||
        
 | 
						||
        
 | 
						||
        
 | 
						||
 | 
						||
        //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){
 | 
						||
            renderScreenFramebuffer();
 | 
						||
        }
 | 
						||
        
 | 
						||
        /*
 | 
						||
        Render black background
 | 
						||
        */
 | 
						||
        if(Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND){
 | 
						||
            renderBlackBackground();
 | 
						||
        }
 | 
						||
        
 | 
						||
        /*
 | 
						||
        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
 | 
						||
        */
 | 
						||
        if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){
 | 
						||
            DebugRendering.drawUIBoundsWireframe();
 | 
						||
        }
 | 
						||
        
 | 
						||
        
 | 
						||
        //check for errors
 | 
						||
        // checkError();
 | 
						||
        
 | 
						||
        //check and call events and swap the buffers
 | 
						||
        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().shaderProgram, "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) && 
 | 
						||
                    drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) &&
 | 
						||
                    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 && 
 | 
						||
                drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
 | 
						||
                ){
 | 
						||
                //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 && 
 | 
						||
                drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
 | 
						||
                ){
 | 
						||
                //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))
 | 
						||
                    );
 | 
						||
                    // modelTransformMatrix.translate(cameraModifiedPosition);
 | 
						||
                    // modelTransformMatrix.rotate(rotation);
 | 
						||
                    // modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
 | 
						||
                    //set actor value
 | 
						||
                    currentActor.setAttribute(modelAttribute, new Matrix4f(modelTransformMatrix));
 | 
						||
                    // ((Matrix4f)currentActor.getAttributeValue(modelAttribute)).set(modelTransformMatrix);
 | 
						||
                }
 | 
						||
                //draw
 | 
						||
                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 && 
 | 
						||
                drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
 | 
						||
                ){
 | 
						||
                //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 && 
 | 
						||
                drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
 | 
						||
                ){
 | 
						||
                //fetch actor
 | 
						||
                InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity);
 | 
						||
                //draw
 | 
						||
                if(currentActor != null){
 | 
						||
                    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) && 
 | 
						||
                drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
 | 
						||
                ){
 | 
						||
                //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.modelMatrix = 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.modelMatrix = 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.modelMatrix = 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.modelMatrix = 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.modelMatrix = 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.modelMatrix = 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.modelMatrix = 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.modelMatrix = 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 &&
 | 
						||
                drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
 | 
						||
                ){
 | 
						||
                //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().shaderProgram, "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().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);
 | 
						||
 | 
						||
        GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "near"), 0.1f);
 | 
						||
        GL20.glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "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) && 
 | 
						||
                    drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) &&
 | 
						||
                    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().shaderProgram, "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) && 
 | 
						||
                    drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) &&
 | 
						||
                    !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().shaderProgram, "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) && 
 | 
						||
                    drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) &&
 | 
						||
                    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.shaderProgram);
 | 
						||
        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.shaderProgram);
 | 
						||
        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
 | 
						||
     */
 | 
						||
    public void setActiveShader(RenderPipelineState renderPipelineState, ShaderProgram program){
 | 
						||
        glUseProgram(program.shaderProgram);
 | 
						||
        activeProgram = program;
 | 
						||
        renderPipelineState.setCurrentShaderPointer(program.shaderProgram);
 | 
						||
    }
 | 
						||
    
 | 
						||
    public ShaderProgram getActiveShader(){
 | 
						||
        return activeProgram;
 | 
						||
    }
 | 
						||
    
 | 
						||
    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());
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * Gets the current render pipeline state
 | 
						||
     * @return The current render pipeline state
 | 
						||
     */
 | 
						||
    public RenderPipelineState getRenderPipelineState(){
 | 
						||
        return renderPipelineState;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 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));
 | 
						||
        }
 | 
						||
    }
 | 
						||
    
 | 
						||
}
 |