Renderer/src/main/java/electrosphere/renderer/RenderingEngine.java
2022-03-01 23:24:46 -05:00

975 lines
47 KiB
Java
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package electrosphere.renderer;
import electrosphere.controls.ControlCallback;
import electrosphere.controls.MouseCallback;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.game.data.creature.type.CollidableTemplate;
import electrosphere.game.server.pathfinding.navmesh.NavCube;
import electrosphere.game.server.pathfinding.navmesh.NavMesh;
import electrosphere.game.server.pathfinding.navmesh.NavShape;
import electrosphere.logger.LoggerInterface;
import electrosphere.main.Globals;
import static electrosphere.main.Main.deltaTime;
import static electrosphere.main.Main.view_Range;
import static electrosphere.renderer.RenderUtils.createScreenTextureVAO;
import electrosphere.renderer.actor.Actor;
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 java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ListIterator;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWKeyCallback;
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_CURSOR;
import static org.lwjgl.glfw.GLFW.GLFW_CURSOR_DISABLED;
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.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.glfwSetInputMode;
import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
import static org.lwjgl.glfw.GLFW.glfwTerminate;
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
import org.lwjgl.glfw.GLFWWindowSizeCallbackI;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import static org.lwjgl.opengl.GL11.GL_BLEND;
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_EXP2;
import static org.lwjgl.opengl.GL11.GL_FOG;
import static org.lwjgl.opengl.GL11.GL_FOG_COLOR;
import static org.lwjgl.opengl.GL11.GL_FOG_DENSITY;
import static org.lwjgl.opengl.GL11.GL_FOG_END;
import static org.lwjgl.opengl.GL11.GL_FOG_MODE;
import static org.lwjgl.opengl.GL11.GL_FOG_START;
import static org.lwjgl.opengl.GL11.GL_LINEAR;
import static org.lwjgl.opengl.GL11.GL_NEAREST;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
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.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.glDisable;
import static org.lwjgl.opengl.GL11.glDrawArrays;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glFogf;
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.GL20.glGetUniformLocation;
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.glBlitFramebuffer;
import static org.lwjgl.system.MemoryUtil.NULL;
public class RenderingEngine {
public static final int GL_DEFAULT_FRAMEBUFFER = 0;
public static final int GL_DEFAULT_RENDERBUFFER = 0;
static Framebuffer screenFramebuffer;
static Renderbuffer screenRenderbuffer;
static int screenTextureVAO;
static ShaderProgram screenTextureShaders;
static ShaderProgram lightDepthShaderProgram;
static Framebuffer lightDepthBuffer;
static Matrix4f nearVolumeProjectionMatrix = new Matrix4f();
static Matrix4f midVolumeProjectionMatrix = new Matrix4f();
static Matrix4f farVolumeProjectionMatrix = new Matrix4f();
static ShaderProgram volumeDepthShaderProgram;
static Framebuffer volumeDepthBackfaceFramebuffer;
static Texture volumeDepthBackfaceTexture;
static Framebuffer volumeDepthFrontfaceFramebuffer;
static Texture volumeDepthFrontfaceTexture;
static float volumeDepthLinearCoef = 0.1f;
static float volumeDepthQuadCoef = 0.01f;
// public static boolean renderHitboxes = false;
// public static boolean renderPhysics = false;
LightManager lightManager;
static float currentViewPlanarAngle;
ShaderProgram activeProgram;
static int outputFramebuffer = 0;
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
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;
//set key callback
Globals.controlCallback = new ControlCallback();
GLFW.glfwSetKeyCallback(Globals.window, Globals.controlCallback);
//set mouse callback
Globals.mouseCallback = new MouseCallback();
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
screenFramebuffer = FramebufferUtils.generateScreensizeTextureFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, GL_DEFAULT_FRAMEBUFFER);
glBindRenderbuffer(GL_RENDERBUFFER, GL_DEFAULT_RENDERBUFFER);
//
//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.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
volumeDepthBackfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, volumeDepthBackfaceTexture);
volumeDepthFrontfaceTexture = FramebufferUtils.generateDepthBufferTexture(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
volumeDepthFrontfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, volumeDepthFrontfaceTexture);
//projection matrices
nearVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.1f, 100);
// midVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.01f, 7);
// farVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.1f, 50);
//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();
float verticalFOV = (float)(Globals.verticalFOV * Math.PI /180.0f);
float aspectRatio = (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT;
float nearClip = 0.001f;
Globals.projectionMatrix.setPerspective(verticalFOV, aspectRatio, nearClip, view_Range);
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){
renderGameContent();
renderDebugContent();
}
//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();
}
//check and call events and swap the buffers
glfwSwapBuffers(Globals.window);
glfwPollEvents();
}
static void renderShadowMapContent(){
Matrix4f modelTransformMatrix = new Matrix4f();
//set the viewport to shadow map size
glViewport(0, 0, 4096, 4096);
glEnable(GL_DEPTH_TEST);
Globals.renderingEngine.setActiveShader(lightDepthShaderProgram);
lightDepthBuffer.bind();
glClear(GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
// glBindTexture(GL_TEXTURE_2D, woodTexture);
// renderScene(simpleDepthShader);
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);
//
// D R A W A L L E N T I T I E S
//
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.entityManager.getDrawable()){
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.getDataKeys().contains(EntityDataStrings.DRAW_CAST_SHADOW)
){
//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(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.drawForDepthBuffer();
// System.out.println(currentActor.modelPath);
// }
}
}
//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(){
Matrix4f modelTransformMatrix = new Matrix4f();
//bind screen fbo
screenFramebuffer.bind();
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
///
/// 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, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
// D R A W A L L E N T I T I E S
//
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.entityManager.getDrawable()){
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);
currentActor.incrementAnimationTime(0.001);
//increment animations
//this is incremented in the shadow calculations
// if(currentActor.getCurrentAnimation() != null){
// currentActor.incrementAnimationTime(deltaTime * 500);
// }
//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(EntityUtils.getScale(currentEntity));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
currentActor.draw();
// Model currentModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(currentEntity));
// if(currentModel != null){
// if(currentModel.currentAnimation != null){
// currentModel.incrementTime(deltaTime * 500);
// }
// currentModel.modelMatrix = new Matrix4f();
// currentModel.modelMatrix.translate(new Vector3f(EntityUtils.getEntityPosition(currentEntity)).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)).sub(new Vector3f(0,1,0)));
// currentModel.modelMatrix.rotate(EntityUtils.getEntityRotation(currentEntity));
// currentModel.modelMatrix.scale(EntityUtils.getEntityScale(currentEntity));
// currentModel.draw();
// }
}
}
// glBindVertexArray(0);
}
static void renderDebugContent(){
Matrix4f modelTransformMatrix = new Matrix4f();
if(Globals.userSettings.graphicsDebugDrawCollisionSpheres()){
for(Entity currentHitbox : Globals.hitboxManager.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(true, true, false, true, true, true, true);
}
} 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(true, true, false, true, true, true, true);
}
}
} 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(true, true, false, true, true, true, true);
}
}
}
}
}
if(Globals.userSettings.graphicsDebugDrawPhysicsObjects()){
Model physicsGraphicsModel;
for(Entity physicsEntity : Globals.collisionEngine.getDynamicPhysicsEntities()){
if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){
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.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
modelTransformMatrix.scale(template.getDimension1(),template.getDimension2(),template.getDimension3());
physicsGraphicsModel.modelMatrix = modelTransformMatrix;
physicsGraphicsModel.draw(true, true, false, true, true, true, true);
}
break;
case "CUBE":
if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){
Vector3d position = EntityUtils.getPosition(physicsEntity);
Vector3f scale = EntityUtils.getScale(physicsEntity);
Quaternionf 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(template.getDimension1(),template.getDimension2(),template.getDimension3());
physicsGraphicsModel.modelMatrix = modelTransformMatrix;
physicsGraphicsModel.draw(true, true, false, true, true, true, true);
}
break;
}
}
}
for(Entity physicsEntity : Globals.collisionEngine.getStructurePhysicsEntities()){
if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){
if(physicsEntity.getDataKeys().contains(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE)){
if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitplane.fbx")) != null){
Vector3d position = EntityUtils.getPosition(physicsEntity);
Vector3f scale = EntityUtils.getScale(physicsEntity);
Quaternionf 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(scale);
physicsGraphicsModel.modelMatrix = modelTransformMatrix;
physicsGraphicsModel.draw(true, true, false, true, true, true, true);
}
} else if(physicsEntity.getDataKeys().contains(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE)){
if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){
Vector3d position = EntityUtils.getPosition(physicsEntity);
Vector3f scale = EntityUtils.getScale(physicsEntity);
Quaternionf 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(scale);
physicsGraphicsModel.modelMatrix = modelTransformMatrix;
physicsGraphicsModel.draw(true, true, false, true, true, true, true);
}
}
}
}
}
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(scale);
shapeGraphicsModel.modelMatrix = modelTransformMatrix;
shapeGraphicsModel.draw(true, true, false, true, true, true, true);
}
}
}
}
}
}
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(screenTextureShaders);
glBindVertexArray(screenTextureVAO);
//aaa
if(outputFramebuffer == 0){
glBindTexture(GL_TEXTURE_2D, screenFramebuffer.getTexturePointer());
} else if(outputFramebuffer == 1){
glBindTexture(GL_TEXTURE_2D, lightDepthBuffer.getTexturePointer());
} else if(outputFramebuffer == 2){
glBindTexture(GL_TEXTURE_2D, volumeDepthBackfaceTexture.getTexturePointer());
} else if(outputFramebuffer == 3){
glBindTexture(GL_TEXTURE_2D, volumeDepthFrontfaceTexture.getTexturePointer());
}
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
static void renderUI(){
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(){
Matrix4f modelTransformMatrix = new Matrix4f();
//set the viewport to shadow map size
glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
glEnable(GL_DEPTH_TEST);
//stop rendering front faces
GL15.glEnable(GL15.GL_CULL_FACE);
GL15.glCullFace(GL15.GL_FRONT);
Globals.renderingEngine.setActiveShader(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);
//
// 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.entityManager.getDrawable()){
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.getDataKeys().contains(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(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.drawForDepthBuffer();
// System.out.println(currentActor.modelPath);
// }
}
}
//stop rendering front faces
GL15.glEnable(GL15.GL_CULL_FACE);
GL15.glCullFace(GL15.GL_BACK);
Globals.renderingEngine.setActiveShader(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.entityManager.getDrawable()){
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.getDataKeys().contains(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(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.drawForDepthBuffer();
// 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);
}
public void setActiveShader(ShaderProgram program){
glUseProgram(program.shaderProgram);
activeProgram = program;
}
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 > 3){
outputFramebuffer = 0;
}
}
}