1688 lines
76 KiB
Java
1688 lines
76 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 java.util.LinkedList;
|
||
import java.util.List;
|
||
import java.util.concurrent.CopyOnWriteArrayList;
|
||
|
||
import org.joml.Matrix4d;
|
||
import org.joml.Matrix4f;
|
||
import org.joml.Quaterniond;
|
||
import org.joml.Quaternionf;
|
||
import org.joml.Sphered;
|
||
import org.joml.Vector3d;
|
||
import org.joml.Vector3f;
|
||
import org.lwjgl.BufferUtils;
|
||
import org.lwjgl.glfw.GLFW;
|
||
import org.lwjgl.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.renderer.ui.imgui.ImGuiLinePlot;
|
||
import electrosphere.renderer.ui.imgui.ImGuiWindow;
|
||
import electrosphere.renderer.ui.imgui.ImGuiLinePlot.ImGuiLinePlotDataset;
|
||
import electrosphere.server.pathfinding.navmesh.NavCube;
|
||
import electrosphere.server.pathfinding.navmesh.NavMesh;
|
||
import electrosphere.server.pathfinding.navmesh.NavShape;
|
||
import imgui.ImGui;
|
||
import imgui.extension.implot.ImPlot;
|
||
import imgui.gl3.ImGuiImplGl3;
|
||
import imgui.glfw.ImGuiImplGlfw;
|
||
import imgui.internal.ImGuiContext;
|
||
|
||
public class RenderingEngine {
|
||
|
||
|
||
|
||
public static final int GL_DEFAULT_FRAMEBUFFER = 0;
|
||
public static final int GL_DEFAULT_RENDERBUFFER = 0;
|
||
static Texture screenTextureColor;
|
||
static Texture screenTextureDepth;
|
||
static Framebuffer screenFramebuffer;
|
||
static Renderbuffer screenRenderbuffer;
|
||
static int screenTextureVAO;
|
||
static ShaderProgram screenTextureShaders;
|
||
static ShaderProgram drawChannel;
|
||
|
||
|
||
|
||
|
||
//
|
||
//imgui related
|
||
//
|
||
//imgui internal objects
|
||
private static final ImGuiImplGlfw imGuiGlfw = new ImGuiImplGlfw();
|
||
private static final ImGuiImplGl3 imGuiGl13 = new ImGuiImplGl3();
|
||
//the version of glsl to init imgui with
|
||
private static String glslVersion = null;
|
||
//the context pointer for the core imgui objects
|
||
private static ImGuiContext imGuiContext = null;
|
||
//if set to true, will render imgui windows
|
||
private static boolean imGuiShouldRender = true;
|
||
//All imgui windows that should be displayed
|
||
private static List<ImGuiWindow> imGuiWindows = new CopyOnWriteArrayList<ImGuiWindow>();
|
||
|
||
|
||
|
||
|
||
|
||
//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;
|
||
|
||
ShaderProgram activeProgram;
|
||
|
||
static int outputFramebuffer = 0;
|
||
|
||
//used in calculating projection matrix
|
||
static float aspectRatio = 1.0f;
|
||
static float verticalFOV = 90.0f;
|
||
|
||
//the current state of the rendering pipeline
|
||
static RenderPipelineState renderPipelineState = new RenderPipelineState();
|
||
|
||
|
||
public void createOpenglContext(){
|
||
LoggerInterface.loggerRenderer.INFO("Create OpenGL Context");
|
||
//Initializes opengl
|
||
glfwInit();
|
||
//Gives hints to glfw to control how opengl will be used
|
||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
||
glslVersion = "#version 410";
|
||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||
// glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); Allows you to make the background transparent
|
||
// glfwWindowHint(GLFW_OPACITY, 23);
|
||
//Creates the window reference object
|
||
if(Globals.userSettings.displayFullscreen()){
|
||
//below line is for fullscreen
|
||
Globals.window = glfwCreateWindow(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, "ORPG", glfwGetPrimaryMonitor(), NULL);
|
||
} else {
|
||
Globals.window = glfwCreateWindow(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, "ORPG", NULL, NULL);
|
||
}
|
||
// Errors for failure to create window (IE: No GUI mode on linux ?)
|
||
if (Globals.window == NULL) {
|
||
LoggerInterface.loggerEngine.ERROR("Failed to make window.", new Exception("Renderer Creation Failure"));
|
||
glfwTerminate();
|
||
}
|
||
//set resize callback
|
||
// 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();
|
||
|
||
//init imgui (must happen after gl.createCapabilities)
|
||
imGuiContext = ImGui.createContext();
|
||
ImPlot.createContext();
|
||
imGuiGlfw.init(Globals.window,true);
|
||
imGuiGl13.init(glslVersion);
|
||
|
||
//This enables Z-buffering so that farther-back polygons are not drawn over nearer ones
|
||
glEnable(GL_DEPTH_TEST);
|
||
|
||
// Support for transparency
|
||
glEnable(GL_BLEND);
|
||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||
|
||
//this disables vsync to make game run faster
|
||
//https://stackoverflow.com/questions/55598376/glfwswapbuffers-is-slow
|
||
if(!Globals.userSettings.graphicsPerformanceEnableVSync()){
|
||
GLFW.glfwSwapInterval(0);
|
||
}
|
||
|
||
// //Hide the cursor and capture it
|
||
// glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||
|
||
|
||
|
||
//init screen rendering quadrant
|
||
screenTextureVAO = createScreenTextureVAO();
|
||
// initScreenTextureShaderProgram();
|
||
screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/simple1/simple1.vs", "/Shaders/screentexture/simple1/simple1.fs");
|
||
// screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.vs", "/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.fs");
|
||
|
||
//generate framebuffers
|
||
screenTextureColor = FramebufferUtils.generateScreenTextureColor(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||
screenTextureDepth = FramebufferUtils.generateScreenTextureDepth(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||
screenFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), screenTextureColor, screenTextureDepth);
|
||
glBindFramebuffer(GL_FRAMEBUFFER, GL_DEFAULT_FRAMEBUFFER);
|
||
glBindRenderbuffer(GL_RENDERBUFFER, GL_DEFAULT_RENDERBUFFER);
|
||
|
||
//
|
||
//Channel debug program
|
||
//
|
||
drawChannel = ShaderProgram.loadSpecificShader("/Shaders/screentexture/drawChannel/drawChannel.vs", "/Shaders/screentexture/drawChannel/drawChannel.fs");
|
||
|
||
//
|
||
//create light depth framebuffer/shader for shadowmapping
|
||
//
|
||
lightDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/lightDepth/lightDepth.vs", "/Shaders/lightDepth/lightDepth.fs");
|
||
Globals.depthMapShaderProgramLoc = lightDepthShaderProgram.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);
|
||
}
|
||
|
||
/**
|
||
* Updates the frustum box of the render pipeline
|
||
*/
|
||
void updateFrustumBox(){
|
||
renderPipelineState.updateFrustumIntersection(Globals.projectionMatrix, Globals.viewMatrix);
|
||
}
|
||
|
||
|
||
/**
|
||
* Main function to draw the screen
|
||
*/
|
||
public void drawScreen(){
|
||
|
||
//calculate render angle for frustum culling
|
||
if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
|
||
updateFrustumBox();
|
||
}
|
||
|
||
//
|
||
//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();
|
||
}
|
||
|
||
/**
|
||
* Render imgui
|
||
*/
|
||
if(imGuiShouldRender){
|
||
imGuiGlfw.newFrame();
|
||
ImGui.newFrame();
|
||
for(ImGuiWindow window : imGuiWindows){
|
||
window.draw();
|
||
}
|
||
ImGui.render();
|
||
imGuiGl13.renderDrawData(ImGui.getDrawData());
|
||
}
|
||
|
||
|
||
//check for errors
|
||
// checkError();
|
||
|
||
//check and call events and swap the buffers
|
||
LoggerInterface.loggerRenderer.DEBUG("Swap buffers");
|
||
glfwSwapBuffers(Globals.window);
|
||
glfwPollEvents();
|
||
}
|
||
|
||
|
||
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) &&
|
||
currentEntity.containsKey(EntityDataStrings.DRAW_CAST_SHADOW)
|
||
){
|
||
//fetch actor
|
||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||
//calculate camera-modified vector3f
|
||
Vector3f cameraCenter = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
|
||
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(cameraCenter);
|
||
//calculate and apply model transform
|
||
modelTransformMatrix = modelTransformMatrix.identity();
|
||
modelTransformMatrix.translate(cameraModifiedPosition);
|
||
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
|
||
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
|
||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||
//draw
|
||
currentActor.draw(renderPipelineState);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//reset texture
|
||
glActiveTexture(GL_TEXTURE0);
|
||
glBindTexture(GL_TEXTURE_2D, 0);
|
||
//bind default framebuffer
|
||
glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||
//reset the viewport to screen size
|
||
glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
|
||
//resume culling backface
|
||
// glCullFace(GL_BACK);
|
||
}
|
||
|
||
|
||
static void renderGameContent(){
|
||
|
||
Matrix4d modelTransformMatrix = new Matrix4d();
|
||
|
||
//bind screen fbo
|
||
screenFramebuffer.bind();
|
||
glEnable(GL_DEPTH_TEST);
|
||
glDepthFunc(GL_LESS);
|
||
glDepthMask(true);
|
||
glViewport(0, 0, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||
|
||
///
|
||
/// R E N D E R I N G S T U F F
|
||
///
|
||
//Sets the background color.
|
||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||
|
||
|
||
//
|
||
// Set render pipeline state
|
||
//
|
||
renderPipelineState.setSelectedShader(SelectedShaderEnum.PRIMARY);
|
||
renderPipelineState.setUseMeshShader(true);
|
||
renderPipelineState.setBufferStandardUniforms(true);
|
||
renderPipelineState.setBufferNonStandardUniforms(false);
|
||
renderPipelineState.setUseMaterial(true);
|
||
renderPipelineState.setUseShadowMap(true);
|
||
renderPipelineState.setUseBones(true);
|
||
renderPipelineState.setUseLight(true);
|
||
|
||
|
||
//
|
||
// Pass One: Solids
|
||
//
|
||
|
||
//
|
||
// D R A W A L L E N T I T I E S
|
||
//
|
||
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
|
||
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
|
||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||
if(
|
||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
||
currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null
|
||
){
|
||
//fetch actor
|
||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||
//calculate camera-modified vector3f
|
||
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||
//calculate and apply model transform
|
||
modelTransformMatrix.identity();
|
||
modelTransformMatrix.translate(cameraModifiedPosition);
|
||
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
|
||
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
|
||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||
//draw
|
||
currentActor.draw(renderPipelineState);
|
||
}
|
||
}
|
||
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){
|
||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||
if(
|
||
currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) != null &&
|
||
currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null
|
||
){
|
||
//fetch actor
|
||
InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity);
|
||
//if the shader attribute for model matrix exists, calculate the model matrix and apply
|
||
if(InstancedActor.getInstanceModelAttribute(currentEntity) != null){
|
||
ShaderAttribute modelAttribute = InstancedActor.getInstanceModelAttribute(currentEntity);
|
||
//calculate model matrix
|
||
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||
Quaterniond rotation = EntityUtils.getRotation(currentEntity);
|
||
// modelTransformMatrix.identity();
|
||
modelTransformMatrix.identity().translationRotateScale(
|
||
cameraModifiedPosition,
|
||
new Quaternionf((float)rotation.x,(float)rotation.y,(float)rotation.z,(float)rotation.w),
|
||
new Vector3f(EntityUtils.getScale(currentEntity))
|
||
);
|
||
//set actor value
|
||
currentActor.setAttribute(modelAttribute, new Matrix4f(modelTransformMatrix));
|
||
//draw
|
||
currentActor.draw(renderPipelineState, new Vector3d(cameraModifiedPosition));
|
||
} else {
|
||
currentActor.draw(renderPipelineState);
|
||
}
|
||
}
|
||
}
|
||
//draw all instanced models
|
||
Globals.clientInstanceManager.draw(renderPipelineState);
|
||
|
||
//
|
||
// Pass Two: Transparency Accumulator + Revealage
|
||
//
|
||
// glDisable(GL_DEPTH_TEST);
|
||
glDepthMask(false);
|
||
glEnable(GL_BLEND);
|
||
glBlendFunci(0, GL_ONE, GL_ONE);
|
||
glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
|
||
glBlendEquation(GL_FUNC_ADD);
|
||
|
||
transparencyBuffer.bind();
|
||
glClearBufferfv(GL_COLOR,0,transparencyAccumulatorClear);
|
||
glClearBufferfv(GL_COLOR,1,transparencyRevealageClear);
|
||
|
||
//
|
||
// Set render pipeline state
|
||
//
|
||
renderPipelineState.setUseMeshShader(true);
|
||
renderPipelineState.setSelectedShader(SelectedShaderEnum.OIT);
|
||
glDepthFunc(GL_LEQUAL);
|
||
|
||
//
|
||
//!!!WARNING!!!
|
||
//Comments on function:
|
||
//If you're going "gee wilikers I don't know why the back planes of my transparent-labeled aren't showing through the transparency", this is for you
|
||
//The transparent pass receives the depth buffer of the opaque pass and IS DEPTH MASK CULLED
|
||
//This means if you draw the transparent object in the depth pass, it will not draw in the transparent pass as it is culled
|
||
//
|
||
//!!!WARNING!!!
|
||
//TLDR OF ABOVE: DO NOT DRAW TRANSPARENT OBJECTS IN OPAQUE PASS
|
||
//
|
||
|
||
|
||
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
|
||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||
if(
|
||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
||
currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null
|
||
){
|
||
//fetch actor
|
||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||
//calculate camera-modified vector3f
|
||
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||
//calculate and apply model transform
|
||
modelTransformMatrix.identity();
|
||
modelTransformMatrix.translate(cameraModifiedPosition);
|
||
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
|
||
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
|
||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||
//draw
|
||
currentActor.draw(renderPipelineState);
|
||
}
|
||
}
|
||
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){
|
||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||
if(
|
||
currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) != null &&
|
||
currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null
|
||
){
|
||
//fetch actor
|
||
InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity);
|
||
//if the shader attribute for model matrix exists, calculate the model matrix and apply
|
||
if(InstancedActor.getInstanceModelAttribute(currentEntity) != null){
|
||
ShaderAttribute modelAttribute = InstancedActor.getInstanceModelAttribute(currentEntity);
|
||
//calculate model matrix
|
||
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||
Quaterniond rotation = EntityUtils.getRotation(currentEntity);
|
||
// modelTransformMatrix.identity();
|
||
modelTransformMatrix.identity().translationRotateScale(
|
||
cameraModifiedPosition,
|
||
new Quaternionf((float)rotation.x,(float)rotation.y,(float)rotation.z,(float)rotation.w),
|
||
new Vector3f(EntityUtils.getScale(currentEntity))
|
||
);
|
||
//set actor value
|
||
currentActor.setAttribute(modelAttribute, new Matrix4f(modelTransformMatrix));
|
||
//draw
|
||
currentActor.draw(renderPipelineState, new Vector3d(cameraModifiedPosition));
|
||
} else {
|
||
currentActor.draw(renderPipelineState);
|
||
}
|
||
}
|
||
}
|
||
//draw all instanced models
|
||
Globals.clientInstanceManager.draw(renderPipelineState);
|
||
|
||
|
||
//
|
||
// Set render pipeline state
|
||
//
|
||
renderPipelineState.setSelectedShader(SelectedShaderEnum.PRIMARY);
|
||
|
||
|
||
|
||
// glBindVertexArray(0);
|
||
}
|
||
|
||
static void renderGameContentNoOIT(){
|
||
|
||
//bind screen fbo
|
||
screenFramebuffer.bind();
|
||
glEnable(GL_DEPTH_TEST);
|
||
glDepthFunc(GL_LESS);
|
||
glDepthMask(true);
|
||
glViewport(0, 0, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||
|
||
glEnable(GL_BLEND);
|
||
glBlendFunci(0, GL_ONE, GL_ONE);
|
||
glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
|
||
glBlendEquation(GL_FUNC_ADD);
|
||
|
||
///
|
||
/// R E N D E R I N G S T U F F
|
||
///
|
||
//Sets the background color.
|
||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||
|
||
|
||
//
|
||
// Set render pipeline state
|
||
//
|
||
renderPipelineState.setUseMeshShader(true);
|
||
renderPipelineState.setBufferStandardUniforms(true);
|
||
renderPipelineState.setBufferNonStandardUniforms(false);
|
||
renderPipelineState.setUseMaterial(true);
|
||
renderPipelineState.setUseShadowMap(true);
|
||
renderPipelineState.setUseBones(true);
|
||
renderPipelineState.setUseLight(true);
|
||
|
||
//
|
||
// D R A W A L L E N T I T I E S
|
||
//
|
||
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
|
||
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
|
||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||
if(
|
||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW)
|
||
){
|
||
//fetch actor
|
||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||
//calculate camera-modified vector3f
|
||
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||
//calculate and apply model transform
|
||
modelTransformMatrix.identity();
|
||
modelTransformMatrix.translate(cameraModifiedPosition);
|
||
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
|
||
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
|
||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||
//draw
|
||
currentActor.draw(renderPipelineState);
|
||
}
|
||
}
|
||
}
|
||
|
||
static void renderDebugContent(){
|
||
|
||
//bind screen fbo
|
||
screenFramebuffer.bind();
|
||
glEnable(GL_DEPTH_TEST);
|
||
glDepthFunc(GL_LESS);
|
||
glDepthMask(true);
|
||
glViewport(0, 0, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||
|
||
///
|
||
/// R E N D E R I N G S T U F F
|
||
///
|
||
//Sets the background color.
|
||
|
||
|
||
//
|
||
// Set render pipeline state
|
||
//
|
||
renderPipelineState.setUseMeshShader(true);
|
||
renderPipelineState.setBufferStandardUniforms(true);
|
||
renderPipelineState.setBufferNonStandardUniforms(false);
|
||
renderPipelineState.setUseMaterial(true);
|
||
renderPipelineState.setUseShadowMap(true);
|
||
renderPipelineState.setUseBones(true);
|
||
renderPipelineState.setUseLight(true);
|
||
|
||
Matrix4d modelTransformMatrix = new Matrix4d();
|
||
|
||
if(Globals.userSettings.graphicsDebugDrawCollisionSpheres()){
|
||
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
|
||
if((boolean)currentHitbox.getData(EntityDataStrings.DATA_STRING_DRAW)){
|
||
Model hitboxModel;
|
||
HitboxData data = HitboxUtils.getHitboxData(currentHitbox);
|
||
if(data.isActive()){
|
||
if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){
|
||
if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere.fbx")) != null){
|
||
Vector3d position = EntityUtils.getPosition(currentHitbox);
|
||
//calculate camera-modified vector3f
|
||
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||
modelTransformMatrix.identity();
|
||
modelTransformMatrix.translate(cameraModifiedPosition);
|
||
// modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
||
modelTransformMatrix.scale(data.getRadius() * 2);
|
||
hitboxModel.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
|
||
){
|
||
//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) &&
|
||
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) &&
|
||
!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) &&
|
||
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());
|
||
}
|
||
|
||
/**
|
||
* Adds a window to the rendering engine
|
||
* @param window The window
|
||
*/
|
||
public static void addImGuiWindow(ImGuiWindow window){
|
||
imGuiWindows.add(window);
|
||
}
|
||
|
||
/**
|
||
* Removes an imgui window from the rendering engine
|
||
* @param window The window
|
||
*/
|
||
public static void removeImGuiWindow(ImGuiWindow window){
|
||
imGuiWindows.remove(window);
|
||
}
|
||
|
||
/**
|
||
* Gets the current render pipeline state
|
||
* @return The current render pipeline state
|
||
*/
|
||
public RenderPipelineState getRenderPipelineState(){
|
||
return renderPipelineState;
|
||
}
|
||
|
||
/**
|
||
* Tries to recapture the screen
|
||
*/
|
||
public static void recaptureIfNecessary(){
|
||
if(Globals.controlHandler.shouldRecapture()){
|
||
//Makes the window that was just created the current OS-level window context
|
||
glfwMakeContextCurrent(Globals.window);
|
||
// //Maximize it
|
||
glfwMaximizeWindow(Globals.window);
|
||
//grab focus
|
||
GLFW.glfwFocusWindow(Globals.window);
|
||
//apply mouse controls state
|
||
if(Globals.controlHandler.isMouseVisible()){
|
||
Globals.controlHandler.showMouse();
|
||
} else {
|
||
Globals.controlHandler.hideMouse();
|
||
}
|
||
Globals.controlHandler.setRecapture(false);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Checks for any errors currently caught by OpenGL.
|
||
* Refer: https://docs.gl/gl4/glGetError
|
||
*/
|
||
private static void checkError(){
|
||
int error = GL11.glGetError();
|
||
String errorInEnglish = "";
|
||
switch(error){
|
||
case GL11.GL_NO_ERROR: {
|
||
errorInEnglish = "";
|
||
} break;
|
||
case GL11.GL_INVALID_ENUM: {
|
||
errorInEnglish = "An unacceptable value is specified for an enumerated argument. The offending command is ignored and has no other side effect than to set the error flag.";
|
||
} break;
|
||
case GL11.GL_INVALID_VALUE: {
|
||
errorInEnglish = "A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag.";
|
||
} break;
|
||
case GL11.GL_INVALID_OPERATION: {
|
||
errorInEnglish = "The specified operation is not allowed in the current state. The offending command is ignored and has no other side effect than to set the error flag.";
|
||
} break;
|
||
case GL30.GL_INVALID_FRAMEBUFFER_OPERATION: {
|
||
errorInEnglish = "The framebuffer object is not complete. The offending command is ignored and has no other side effect than to set the error flag. ";
|
||
} break;
|
||
case GL11.GL_OUT_OF_MEMORY: {
|
||
errorInEnglish = "There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded. ";
|
||
} break;
|
||
case GL11.GL_STACK_UNDERFLOW: {
|
||
errorInEnglish = "An attempt has been made to perform an operation that would cause an internal stack to underflow. ";
|
||
} break;
|
||
case GL11.GL_STACK_OVERFLOW: {
|
||
errorInEnglish = "An attempt has been made to perform an operation that would cause an internal stack to overflow. ";
|
||
} break;
|
||
default: {
|
||
errorInEnglish = "Un-enum'd error " + error;
|
||
} break;
|
||
}
|
||
if(!errorInEnglish.equals("")){
|
||
LoggerInterface.loggerRenderer.ERROR(errorInEnglish, new Exception(errorInEnglish));
|
||
}
|
||
}
|
||
|
||
}
|