Renderer/src/main/java/electrosphere/renderer/RenderUtils.java
2021-06-07 20:11:56 -04:00

756 lines
29 KiB
Java

package electrosphere.renderer;
import electrosphere.entity.CameraEntityUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import electrosphere.main.Globals;
import electrosphere.main.Main;
import static electrosphere.main.Main.deltaTime;
import static electrosphere.main.Main.view_Range;
import electrosphere.renderer.framebuffer.Framebuffer;
import electrosphere.renderer.framebuffer.FramebufferUtils;
import electrosphere.renderer.framebuffer.Renderbuffer;
import electrosphere.renderer.ui.Widget;
import electrosphere.util.Utilities;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.lwjgl.BufferUtils;
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_FALSE;
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.GLFW_TRANSPARENT_FRAMEBUFFER;
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
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.opengl.GL;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.GL_BACK;
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_CULL_FACE;
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_FLOAT;
import static org.lwjgl.opengl.GL11.GL_FRONT;
import static org.lwjgl.opengl.GL11.GL_INT;
import static org.lwjgl.opengl.GL11.GL_LEQUAL;
import static org.lwjgl.opengl.GL11.GL_LESS;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_SHORT;
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_TRUE;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
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.glCullFace;
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 org.lwjgl.opengl.GL15;
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
import static org.lwjgl.opengl.GL15.glBindBuffer;
import static org.lwjgl.opengl.GL15.glGenBuffers;
import org.lwjgl.opengl.GL20;
import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS;
import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER;
import static org.lwjgl.opengl.GL20.GL_LINK_STATUS;
import static org.lwjgl.opengl.GL20.GL_VERTEX_SHADER;
import static org.lwjgl.opengl.GL20.glAttachShader;
import static org.lwjgl.opengl.GL20.glCompileShader;
import static org.lwjgl.opengl.GL20.glCreateProgram;
import static org.lwjgl.opengl.GL20.glCreateShader;
import static org.lwjgl.opengl.GL20.glDeleteShader;
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
import static org.lwjgl.opengl.GL20.glGetProgramInfoLog;
import static org.lwjgl.opengl.GL20.glGetProgrami;
import static org.lwjgl.opengl.GL20.glGetShaderi;
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
import static org.lwjgl.opengl.GL20.glLinkProgram;
import static org.lwjgl.opengl.GL20.glShaderSource;
import static org.lwjgl.opengl.GL20.glUniform1fv;
import static org.lwjgl.opengl.GL20.glUniform1i;
import static org.lwjgl.opengl.GL20.glUniform3fv;
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
import static org.lwjgl.opengl.GL20.glUseProgram;
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
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.glGenVertexArrays;
import static org.lwjgl.system.MemoryUtil.NULL;
/**
*
* @author amaterasu
*/
public class RenderUtils {
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 int createScreenTextureVAO(){
int rVal = glGenVertexArrays();
glBindVertexArray(rVal);
//vertices
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(12);
VertexArrayBufferData.put(-1.0f);
VertexArrayBufferData.put( 1.0f);
VertexArrayBufferData.put(-1.0f);
VertexArrayBufferData.put(-1.0f);
VertexArrayBufferData.put( 1.0f);
VertexArrayBufferData.put(-1.0f);
VertexArrayBufferData.put(-1.0f);
VertexArrayBufferData.put( 1.0f);
VertexArrayBufferData.put( 1.0f);
VertexArrayBufferData.put(-1.0f);
VertexArrayBufferData.put( 1.0f);
VertexArrayBufferData.put( 1.0f);
VertexArrayBufferData.flip();
int vertexBuffer = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
GL15.glBufferData(GL_ARRAY_BUFFER, VertexArrayBufferData, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);
//texture coords
FloatBuffer TextureArrayBufferData = BufferUtils.createFloatBuffer(12);
TextureArrayBufferData.put(0.0f);
TextureArrayBufferData.put(1.0f);
TextureArrayBufferData.put(0.0f);
TextureArrayBufferData.put(0.0f);
TextureArrayBufferData.put(1.0f);
TextureArrayBufferData.put(0.0f);
TextureArrayBufferData.put(0.0f);
TextureArrayBufferData.put(1.0f);
TextureArrayBufferData.put(1.0f);
TextureArrayBufferData.put(0.0f);
TextureArrayBufferData.put(1.0f);
TextureArrayBufferData.put(1.0f);
TextureArrayBufferData.flip();
int textureCoordBuffer = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, textureCoordBuffer);
GL15.glBufferData(GL_ARRAY_BUFFER, TextureArrayBufferData, GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(1);
return rVal;
}
public static void createOpenglContext(){
//Sets the variables that control the window sizing
int screenWidth = Globals.WINDOW_WIDTH;
int screenHeight = Globals.WINDOW_HEIGHT;
//Initializes opengl
glfwInit();
//Gives hints to glfw to control how opengl will be used
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
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(screenWidth, screenHeight, "LearnOpenGL", NULL, NULL);
//Errors for failure to create window (IE: No GUI mode on linux ?)
if (Globals.window == NULL) {
System.out.println("Failed to make window.");
glfwTerminate();
}
//Makes the window that was just created the current OS-level window context
glfwMakeContextCurrent(Globals.window);
//Maximize it
glfwMaximizeWindow(Globals.window);
//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);
//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);
lightDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/lightDepth/lightDepth.vs", "/Shaders/lightDepth/lightDepth.fs");
Globals.depthMapShaderProgramLoc = lightDepthShaderProgram.shaderProgram;
lightDepthBuffer = FramebufferUtils.generateDepthBuffer();
Globals.shadowMapTextureLoc = lightDepthBuffer.getTexture();
// glEnable(GL_CULL_FACE); // enabled for shadow mapping
//
// Projection and View matrix creation
//
Globals.projectionMatrix = new Matrix4f();
Globals.viewMatrix = new Matrix4f();
float FOV = (float)(120.0f * Math.PI /180.0f);
Globals.projectionMatrix.setPerspective(FOV, 1.0f, 0.1f, view_Range);
Globals.viewMatrix.translation(new Vector3f(0.0f,0.0f,-3.0f));
}
public static void recaptureScreen(){
//Makes the window that was just created the current OS-level window context
glfwMakeContextCurrent(Globals.window);
//Maximize it
glfwMaximizeWindow(Globals.window);
//Hide the cursor and capture it
glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}
public static Model createSkyboxModel(Material optionalMaterial){
Model skyboxModel = new Model();
skyboxModel.meshes = new ArrayList();
skyboxModel.modelMatrix = new Matrix4f();
boolean apply_lighting = false;
boolean has_bones = false;
Mesh skyboxmesh = new Mesh(){
@Override
public void draw(){
GL11.glDepthFunc(GL_LEQUAL);
glUseProgram(shader.shaderProgram);
if(material == null){
Globals.materialDefault.apply_material(0,1);
Iterator<Vector3f> colorIterator = Globals.skyboxColors.iterator();
int counter = 0;
float[] temp = new float[3];
while(colorIterator.hasNext()){
Vector3f colorCurrent = colorIterator.next();
temp[0] = colorCurrent.x / 255.0f;
temp[1] = colorCurrent.y / 255.0f;
temp[2] = colorCurrent.z / 255.0f;
// System.out.println("colors[" + counter + "] " + temp[0] + " " + temp[1] + " " + temp[2]);
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "colors[" + counter + "]"), temp);
counter++;
}
}
glBindVertexArray(vertexArrayObject);
//buffer model/view/proj matrices
glUniformMatrix4fv(shader.shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16]));
glUniformMatrix4fv(shader.shaderVertexViewLoc, false, new Matrix4f(Globals.viewMatrix).scale(100).get(new float[16]));
glUniformMatrix4fv(shader.shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16]));
glUniform3fv(shader.shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3)));
GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
GL11.glDepthFunc(GL_LESS);
}
};
skyboxmesh.mesh = null;
//
// VAO
//
skyboxmesh.vertexArrayObject = glGenVertexArrays();
glBindVertexArray(skyboxmesh.vertexArrayObject);
float[] vertexcoords = {
1.0f,1.0f,1.0f,
1.0f,1.0f,-1.0f,
1.0f,-1.0f,1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,1.0f,1.0f,
-1.0f,1.0f,-1.0f,
-1.0f,-1.0f,1.0f,
-1.0f,-1.0f,-1.0f,
};
//
//Buffer data to GPU
//
try {
skyboxmesh.vertexCount = vertexcoords.length / 3;
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.vertexCount * 3);
float[] temp = new float[3];
for (int i = 0; i < skyboxmesh.vertexCount; i++) {
temp[0] = vertexcoords[i * 3 + 0];
temp[1] = vertexcoords[i * 3 + 1];
temp[2] = vertexcoords[i * 3 + 2];
VertexArrayBufferData.put(temp);
}
VertexArrayBufferData.flip();
skyboxmesh.buffer_vertices(VertexArrayBufferData, 3);
} catch (NullPointerException ex){
ex.printStackTrace();
}
int[] facedata = {
0,1,4,
1,4,5,
1,3,5,
3,5,7,
4,5,7,
4,6,7,
0,2,4,
2,4,6,
0,1,2,
1,2,3,
2,3,6,
3,6,7,
};
//
// FACES
//
skyboxmesh.faceCount = facedata.length / 3;
skyboxmesh.elementCount = facedata.length;
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(skyboxmesh.elementCount);
for(int i = 0; i < skyboxmesh.faceCount; i++){
int[] temp = new int[3];
temp[0] = facedata[i * 3 + 0];
temp[1] = facedata[i * 3 + 1];
temp[2] = facedata[i * 3 + 2];
elementArrayBufferData.put(temp);
}
elementArrayBufferData.flip();
skyboxmesh.buffer_faces(elementArrayBufferData);
if(optionalMaterial != null){
//
// NORMALS
//
try {
skyboxmesh.normalCount = vertexcoords.length / 3;
FloatBuffer NormalArrayBufferData;
if(skyboxmesh.normalCount > 0){
NormalArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.normalCount * 3);
float[] temp = new float[3];
for (int i = 0; i < skyboxmesh.normalCount; i++) {
temp[0] = vertexcoords[i * 3 + 0];
temp[1] = vertexcoords[i * 3 + 1];
temp[2] = vertexcoords[i * 3 + 2];
NormalArrayBufferData.put(temp);
}
NormalArrayBufferData.flip();
skyboxmesh.buffer_normals(NormalArrayBufferData, 3);
}
} catch (NullPointerException ex){
ex.printStackTrace();
}
//
// TEXTURE COORDINATES
//
/*try {
skyboxmesh.textureCoordCount = mesh.mTextureCoords(0).capacity();
FloatBuffer TextureArrayBufferData;
if(skyboxmesh.textureCoordCount > 0){
TextureArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.textureCoordCount * 2);
float[] temp = new float[2];
for (int i = 0; i < skyboxmesh.textureCoordCount; i++) {
AIVector3D normal = texturecoords.get(i);
temp[0] = normal.x();
temp[1] = normal.y();
// temp[2] = normal.z();
TextureArrayBufferData.put(temp);
}
TextureArrayBufferData.flip();
skyboxmesh.buffer_texture_coords(TextureArrayBufferData);
}
} catch (NullPointerException ex){
ex.printStackTrace();
}
skyboxmesh.shader = ShaderProgram.smart_assemble_shader(has_bones, apply_lighting);
skybox_model.materials.add(optionalMaterial);
*/
} else {
skyboxmesh.shader = ShaderProgram.loadSpecificShader("/Shaders/skybox/VertexShaderNoTexture.vs", "/Shaders/skybox/FragmentShaderNoTexture.fs");
try {
FloatBuffer ColorArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.vertexCount);
for (int i = 0; i < skyboxmesh.vertexCount; i++) {
ColorArrayBufferData.put(i);
}
ColorArrayBufferData.flip();
int idBuffer = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, idBuffer);
GL15.glBufferData(GL_ARRAY_BUFFER, ColorArrayBufferData, GL_STATIC_DRAW);
glVertexAttribPointer(1, 1, GL11.GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(1);
} catch (NullPointerException ex){
ex.printStackTrace();
}
}
skyboxmesh.hasBones = false;
glBindVertexArray(0);
skyboxmesh.nodeID = "skybox";
skyboxmesh.parent = skyboxModel;
skyboxModel.meshes.add(skyboxmesh);
return skyboxModel;
}
public static void drawScreen(){
//
//first pass: generate depth map
//
if(Globals.RENDER_FLAG_RENDER_SHADOW_MAP){
renderShadowMapFramebufferContent();
}
/*
Render content to the game framebuffer
*/
if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
renderGameFramebufferContent();
}
//bind default FBO
glBindFramebuffer(GL_FRAMEBUFFER,0);
glDisable(GL_DEPTH_TEST);
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 any ui elements
*/
if(Globals.RENDER_FLAG_RENDER_UI){
renderUI();
}
//check and call events and swap the buffers
glfwSwapBuffers(Globals.window);
glfwPollEvents();
}
static void renderShadowMapFramebufferContent(){
Matrix4f modelTransformMatrix = new Matrix4f();
//set the viewport to shadow map size
glViewport(0, 0, 4096, 4096);
glEnable(GL_DEPTH_TEST);
lightDepthBuffer.bind();
glClear(GL_DEPTH_BUFFER_BIT);
//set matrices for light render
float near_plane = 0.001f, far_plane = 100.5f;
Matrix4f lightProjection = new Matrix4f().setOrtho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);//glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
Matrix4f lightView = new Matrix4f().lookAt(
new Vector3f(-20.0f, 40.0f, -10.0f),
new Vector3f( 0.0f, 0.0f, 0.0f),
new Vector3f( 0.0f, 1.0f, 0.0f)
);
Globals.lightDepthMatrix = new Matrix4f(lightProjection).mul(lightView);
glUseProgram(lightDepthShaderProgram.shaderProgram);
glUniformMatrix4fv(glGetUniformLocation(lightDepthShaderProgram.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
//
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.entityManager.getDrawable()){
//fetch actor
Actor currentActor = EntityUtils.getEntityActor(currentEntity);
//increment animations
if(currentActor.getCurrentAnimation() != null){
currentActor.incrementAnimationTime(deltaTime * 500);
}
//calculate and apply model transform
modelTransformMatrix.identity();
modelTransformMatrix.translate(new Vector3f(EntityUtils.getEntityPosition(currentEntity)).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)).sub(new Vector3f(0,1,0)));
modelTransformMatrix.rotate(EntityUtils.getEntityRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getEntityScale(currentEntity));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
currentActor.drawForDepthBuffer();
}
//bind default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER,0);
//reset texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
//reset the viewport to screen size
glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
//resume culling backface
// glCullFace(GL_BACK);
}
static void renderGameFramebufferContent(){
Matrix4f modelTransformMatrix = new Matrix4f();
//bind screen fbo
screenFramebuffer.bind();
glEnable(GL_DEPTH_TEST);
///
/// 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
//
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.entityManager.getDrawable()){
//fetch actor
Actor currentActor = EntityUtils.getEntityActor(currentEntity);
//increment animations
//this is incremented in the shadow calculations
// if(currentActor.getCurrentAnimation() != null){
// currentActor.incrementAnimationTime(deltaTime * 500);
// }
//calculate and apply model transform
modelTransformMatrix.identity();
modelTransformMatrix.translate(new Vector3f(EntityUtils.getEntityPosition(currentEntity)).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)).sub(new Vector3f(0,1,0)));
modelTransformMatrix.rotate(EntityUtils.getEntityRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getEntityScale(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();
// }
}
for(Entity currentHitbox : Globals.hitboxManager.getAllHitboxes()){
Model hitboxModel;
if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere.fbx")) != null){
Vector3f position = EntityUtils.getEntityPosition(currentHitbox);
modelTransformMatrix.identity();
modelTransformMatrix.translate(new Vector3f(position).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)).sub(new Vector3f(0,1,0)));
// modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
modelTransformMatrix.scale((Float)currentHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_SIZE));
hitboxModel.modelMatrix = modelTransformMatrix;
hitboxModel.draw();
}
}
// 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);
//render full screen quad
glUseProgram(screenTextureShaders.shaderProgram);
glBindVertexArray(screenTextureVAO);
glBindTexture(GL_TEXTURE_2D, screenFramebuffer.getTexture());
// glBindTexture(GL_TEXTURE_2D, lightDepthBuffer.getTexture());
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
static void renderUI(){
Matrix4f modelTransformMatrix = new Matrix4f();
for(Widget currentWidget : Globals.widgetManager.getWidgetList()){
if(currentWidget.isDraw()){
currentWidget.draw();
}
}
// 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 renderBlackBackground(){
//render full screen quad
glUseProgram(screenTextureShaders.shaderProgram);
glBindVertexArray(screenTextureVAO);
Globals.blackTexture.bind();
// glBindTexture(GL_TEXTURE_2D, screenFramebuffer.getTexture());
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
}