diff --git a/.vscode/launch.json b/.vscode/launch.json index ff51c075..98bf68df 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,7 +15,7 @@ "name": "Launch Main", "request": "launch", "mainClass": "electrosphere.engine.Main", - "vmArgs": "-Xmx1G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", + "vmArgs": "-Xmx2G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", "projectName": "Renderer" }, { @@ -26,7 +26,7 @@ "env": { "ALSOFT_LOGLEVEL": 4, }, - "vmArgs": "-Xmx1G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", + "vmArgs": "-Xmx2G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", "projectName": "Renderer" }, { diff --git a/buildNumber.properties b/buildNumber.properties index 77178d38..58fecef4 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sat Mar 09 15:31:50 EST 2024 -buildNumber=34 +#Sun Mar 10 11:10:27 EDT 2024 +buildNumber=45 diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index d3d3e787..0833017e 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -139,6 +139,11 @@ Timekeeping class that defaults to gltf time and falls back to systemCurrentTime Methods for sleeping physics bodies if nothing nearby them is dynamic (ie trees if there are no moving creatures near them) - SAP2 space from ode4j specifically (ended up using BVH space instead) +Overhaul mesh class + - remove unused stuff + - private constructor + (this is going to require changing a lot of dependencies) + @@ -152,11 +157,6 @@ De-dupe render calls via doing mutations in render pipeline status and dont call Clean up main method/class -Overhaul mesh class - - remove unused stuff - - private constructor - (this is going to require changing a lot of dependencies) - Build a lod system - Could potentially be held at actor level - Link different models based on LOD level diff --git a/src/main/java/electrosphere/client/fluid/cells/FluidDrawCell.java b/src/main/java/electrosphere/client/fluid/cells/FluidDrawCell.java index 736a43e1..0b2fd4bd 100644 --- a/src/main/java/electrosphere/client/fluid/cells/FluidDrawCell.java +++ b/src/main/java/electrosphere/client/fluid/cells/FluidDrawCell.java @@ -11,7 +11,7 @@ import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; import electrosphere.entity.types.fluid.FluidChunk; -import electrosphere.renderer.ShaderProgram; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.texture.Texture; /** diff --git a/src/main/java/electrosphere/client/fluid/cells/FluidDrawCellManager.java b/src/main/java/electrosphere/client/fluid/cells/FluidDrawCellManager.java index 51754d5a..cd66a1cd 100644 --- a/src/main/java/electrosphere/client/fluid/cells/FluidDrawCellManager.java +++ b/src/main/java/electrosphere/client/fluid/cells/FluidDrawCellManager.java @@ -13,7 +13,7 @@ import electrosphere.client.terrain.manager.ClientTerrainManager; import electrosphere.engine.Globals; import electrosphere.entity.EntityUtils; import electrosphere.net.parser.net.message.TerrainMessage; -import electrosphere.renderer.ShaderProgram; +import electrosphere.renderer.shader.ShaderProgram; /** * diff --git a/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java b/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java index ff9099b2..4dc591a3 100644 --- a/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java +++ b/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java @@ -17,8 +17,8 @@ import electrosphere.engine.Globals; import electrosphere.entity.types.fluid.FluidChunkModelData; import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.TerrainMessage; -import electrosphere.renderer.Model; import electrosphere.renderer.meshgen.FluidChunkModelGeneration; +import electrosphere.renderer.model.Model; import electrosphere.server.terrain.manager.ServerTerrainManager; /** diff --git a/src/main/java/electrosphere/client/terrain/cells/DrawCell.java b/src/main/java/electrosphere/client/terrain/cells/DrawCell.java index fd44253c..0ab899e6 100644 --- a/src/main/java/electrosphere/client/terrain/cells/DrawCell.java +++ b/src/main/java/electrosphere/client/terrain/cells/DrawCell.java @@ -11,7 +11,7 @@ import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; import electrosphere.entity.types.terrain.TerrainChunk; -import electrosphere.renderer.ShaderProgram; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.texture.Texture; import electrosphere.server.datacell.Realm; diff --git a/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java b/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java index 4f7c4240..ebb2768b 100644 --- a/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java +++ b/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java @@ -13,7 +13,7 @@ import electrosphere.client.terrain.manager.ClientTerrainManager; import electrosphere.engine.Globals; import electrosphere.entity.EntityUtils; import electrosphere.net.parser.net.message.TerrainMessage; -import electrosphere.renderer.ShaderProgram; +import electrosphere.renderer.shader.ShaderProgram; /** * diff --git a/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java b/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java index 232a3c35..972d4eec 100644 --- a/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java +++ b/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java @@ -19,8 +19,8 @@ import electrosphere.engine.Globals; import electrosphere.entity.types.terrain.TerrainChunkData; import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.TerrainMessage; -import electrosphere.renderer.Model; import electrosphere.renderer.meshgen.TerrainChunkModelGeneration; +import electrosphere.renderer.model.Model; import electrosphere.server.terrain.manager.ServerTerrainManager; /** diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index 38a12738..20d4213e 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -46,16 +46,16 @@ import electrosphere.net.server.player.Player; import electrosphere.net.server.player.PlayerManager; import electrosphere.net.synchronization.ClientSynchronizationManager; import electrosphere.net.synchronization.EntityValueTrackingService; -import electrosphere.renderer.Material; import electrosphere.renderer.RenderUtils; import electrosphere.renderer.RenderingEngine; -import electrosphere.renderer.ShaderProgram; import electrosphere.renderer.actor.instance.InstanceManager; import electrosphere.renderer.light.PointLight; import electrosphere.renderer.light.SpotLight; import electrosphere.renderer.loading.ModelPretransforms; import electrosphere.renderer.meshgen.TerrainChunkModelGeneration; +import electrosphere.renderer.model.Material; import electrosphere.renderer.shader.ShaderOptionMap; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.texture.TextureMap; import electrosphere.renderer.ui.ElementManager; import electrosphere.renderer.ui.elements.ImagePanel; @@ -473,8 +473,6 @@ public class Globals { //init fluid shader program terrainShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/fluid1/fluid1.vs", "/Shaders/fluid1/fluid1.fs"); TerrainChunkModelGeneration.terrainChunkShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/fluid1/fluid1.vs", "/Shaders/fluid1/fluid1.fs"); - //init skybox - assetManager.registerModelToSpecificString(RenderUtils.createSkyboxModel(null), AssetDataStrings.ASSET_STRING_SKYBOX_BASIC); //init models assetManager.addModelPathToQueue("Models/unitsphere.fbx"); assetManager.addModelPathToQueue("Models/unitsphere_1.fbx"); diff --git a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java index 9924a28e..a40cc7a9 100644 --- a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java +++ b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java @@ -5,13 +5,13 @@ import electrosphere.collision.CollisionBodyCreation; import electrosphere.collision.CollisionEngine; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; -import electrosphere.renderer.Mesh; -import electrosphere.renderer.Model; -import electrosphere.renderer.ShaderProgram; import electrosphere.renderer.actor.ActorShaderMask; import electrosphere.renderer.buffer.HomogenousInstancedArray; import electrosphere.renderer.buffer.HomogenousUniformBuffer; import electrosphere.renderer.loading.ModelLoader; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.texture.Texture; import electrosphere.server.poseactor.PoseModel; @@ -187,9 +187,9 @@ public class AssetManager { for(MeshShaderOverride shaderOverride : shaderOverrides){ Model model = null; if((model = fetchModel(shaderOverride.modelName)) != null){ - for(Mesh mesh : model.meshes){ - if(mesh.nodeID.equals(shaderOverride.getMeshName())){ - mesh.shader = ShaderProgram.loadSpecificShader(shaderOverride.vertPath, shaderOverride.fragPath); + for(Mesh mesh : model.getMeshes()){ + if(mesh.getMeshName().equals(shaderOverride.getMeshName())){ + mesh.setShader(ShaderProgram.loadSpecificShader(shaderOverride.vertPath, shaderOverride.fragPath)); } } toRemove.add(shaderOverride); diff --git a/src/main/java/electrosphere/entity/EntityUtils.java b/src/main/java/electrosphere/entity/EntityUtils.java index 8e18a238..953880fc 100644 --- a/src/main/java/electrosphere/entity/EntityUtils.java +++ b/src/main/java/electrosphere/entity/EntityUtils.java @@ -10,9 +10,9 @@ import electrosphere.entity.state.movement.GroundMovementTree; import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.item.ItemUtils; -import electrosphere.renderer.Model; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorUtils; +import electrosphere.renderer.model.Model; import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.ServerDataCell; import electrosphere.server.datacell.utils.DataCellSearchUtils; diff --git a/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java index fc6b632d..d7d42fb6 100644 --- a/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java @@ -20,8 +20,8 @@ import electrosphere.entity.state.movement.SprintTree.SprintTreeState; import electrosphere.net.NetUtils; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.renderer.anim.Animation; +import electrosphere.renderer.model.Model; import electrosphere.server.datacell.utils.DataCellSearchUtils; -import electrosphere.renderer.Model; import electrosphere.renderer.actor.Actor; import java.util.LinkedList; diff --git a/src/main/java/electrosphere/entity/state/movement/ServerGroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/ServerGroundMovementTree.java index 38987153..c181f9cc 100644 --- a/src/main/java/electrosphere/entity/state/movement/ServerGroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/ServerGroundMovementTree.java @@ -19,9 +19,9 @@ import electrosphere.entity.state.movement.ServerSprintTree.SprintTreeState; import electrosphere.net.NetUtils; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.renderer.anim.Animation; +import electrosphere.renderer.model.Model; import electrosphere.server.datacell.utils.DataCellSearchUtils; import electrosphere.server.poseactor.PoseActor; -import electrosphere.renderer.Model; import electrosphere.renderer.actor.Actor; import java.util.LinkedList; diff --git a/src/main/java/electrosphere/entity/types/attach/AttachUtils.java b/src/main/java/electrosphere/entity/types/attach/AttachUtils.java index d30e09f9..575de76a 100644 --- a/src/main/java/electrosphere/entity/types/attach/AttachUtils.java +++ b/src/main/java/electrosphere/entity/types/attach/AttachUtils.java @@ -6,8 +6,8 @@ import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityTags; import electrosphere.entity.EntityUtils; import electrosphere.entity.types.creature.CreatureUtils; -import electrosphere.renderer.Model; import electrosphere.renderer.actor.Actor; +import electrosphere.renderer.model.Model; import electrosphere.server.datacell.ServerDataCell; import electrosphere.server.datacell.utils.ServerEntityTagUtils; diff --git a/src/main/java/electrosphere/menu/MenuGenerators.java b/src/main/java/electrosphere/menu/MenuGenerators.java index 367e8dce..b167e761 100644 --- a/src/main/java/electrosphere/menu/MenuGenerators.java +++ b/src/main/java/electrosphere/menu/MenuGenerators.java @@ -17,11 +17,11 @@ import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.net.NetUtils; -import electrosphere.renderer.Model; import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorStaticMorph; import electrosphere.renderer.actor.ActorUtils; +import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.ClickableElement; import electrosphere.renderer.ui.Element; import electrosphere.renderer.ui.NavigableElement.NavigationEventCallback; diff --git a/src/main/java/electrosphere/menu/MenuGeneratorsInGame.java b/src/main/java/electrosphere/menu/MenuGeneratorsInGame.java index f7a6afc5..768d21ea 100644 --- a/src/main/java/electrosphere/menu/MenuGeneratorsInGame.java +++ b/src/main/java/electrosphere/menu/MenuGeneratorsInGame.java @@ -11,10 +11,10 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; -import electrosphere.renderer.Model; import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorStaticMorph; +import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.ClickableElement; import electrosphere.renderer.ui.Window; import electrosphere.renderer.ui.NavigableElement.NavigationEventCallback; diff --git a/src/main/java/electrosphere/menu/MenuGeneratorsMultiplayer.java b/src/main/java/electrosphere/menu/MenuGeneratorsMultiplayer.java index c29ece93..e9b6c2a8 100644 --- a/src/main/java/electrosphere/menu/MenuGeneratorsMultiplayer.java +++ b/src/main/java/electrosphere/menu/MenuGeneratorsMultiplayer.java @@ -13,13 +13,13 @@ import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.visualattribute.AttributeVariant; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.net.parser.net.message.CharacterMessage; -import electrosphere.renderer.Model; import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorStaticMorph; import electrosphere.renderer.actor.ActorUtils; import electrosphere.renderer.actor.ActorStaticMorph.StaticMorphTransforms; import electrosphere.renderer.anim.Animation; +import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.ClickableElement; import electrosphere.renderer.ui.Element; import electrosphere.renderer.ui.ValueElement.ValueChangeEventCallback; diff --git a/src/main/java/electrosphere/renderer/Camera.java b/src/main/java/electrosphere/renderer/Camera.java deleted file mode 100644 index e0d4dffe..00000000 --- a/src/main/java/electrosphere/renderer/Camera.java +++ /dev/null @@ -1,40 +0,0 @@ -package electrosphere.renderer; - -import org.joml.Matrix4f; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -/** - * - * @author satellite - */ -@Deprecated -public class Camera { - public Vector3f pos_Center = new Vector3f(0,0,0); -// public Vector3f pos_Front = new Vector3f(0,0,0); -// public Vector3f pos_Top = new Vector3f(0,0,0); - public Quaternionf rotation = new Quaternionf(); - public Camera(){ - - } - - public void apply_camera(Camera c){ - pos_Center = new Vector3f(c.pos_Center); - rotation = new Quaternionf(c.rotation); - } - - public Matrix4f get_view_matrix(){ - Matrix4f rVal = new Matrix4f(); -// rVal.setLookAt(pos_Center, pos_Front, pos_Top); - Vector3f up = new Vector3f(pos_Center); - //new Vector3f(pos_Center).add(new Quaternionf(rotation)..transform(new Vector3f(1,0,0))) - Vector3f up_modifier = new Vector3f(1,0,0); - Quaternionf up_transformation = new Quaternionf(rotation); - up_transformation.rotateAxis((float)Math.PI/2.0f, new Vector3f(up).cross(new Vector3f(0,1,0))); // the hard part is getting the axis in this logic to correspond to the vertical - up = up.add(up_transformation.transform(up_modifier)); - rVal.setLookAt(pos_Center, //where our camera is - new Vector3f(pos_Center).add(rotation.transform(new Vector3f(1,0,0))), //where our camera wants to look - up); //where "up" is relative to our camera - return rVal; - } -} diff --git a/src/main/java/electrosphere/renderer/Mesh.java b/src/main/java/electrosphere/renderer/Mesh.java deleted file mode 100644 index 7f229dd7..00000000 --- a/src/main/java/electrosphere/renderer/Mesh.java +++ /dev/null @@ -1,779 +0,0 @@ -package electrosphere.renderer; - -import electrosphere.engine.Globals; -import electrosphere.engine.Main; -import electrosphere.entity.types.camera.CameraEntityUtils; -import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum; -import electrosphere.renderer.actor.ActorTextureMask; -import electrosphere.renderer.actor.instance.InstanceData; -import electrosphere.renderer.buffer.HomogenousInstancedArray; -import electrosphere.renderer.buffer.HomogenousUniformBuffer; -import electrosphere.renderer.buffer.ShaderAttribute; -import electrosphere.renderer.buffer.HomogenousUniformBuffer.HomogenousBufferTypes; -import electrosphere.renderer.light.LightManager; -import electrosphere.renderer.loading.ModelPretransforms; -import electrosphere.renderer.texture.Texture; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.joml.Matrix4d; -import org.joml.Matrix4f; -import org.joml.Quaternionf; -import org.joml.Sphered; -import org.joml.Vector3d; -import org.joml.Vector3f; -import org.joml.Vector4d; -import org.lwjgl.BufferUtils; -import org.lwjgl.PointerBuffer; -import org.lwjgl.assimp.AIBone; -import org.lwjgl.assimp.AIFace; -import org.lwjgl.assimp.AIMesh; -import org.lwjgl.assimp.AIVector2D; -import org.lwjgl.assimp.AIVector3D; -import org.lwjgl.assimp.AIVertexWeight; -import static org.lwjgl.opengl.ARBVertexBufferObject.*; -import org.lwjgl.opengl.GL11; -import static org.lwjgl.opengl.GL11.GL_FALSE; -import static org.lwjgl.opengl.GL11.GL_FLOAT; -import static org.lwjgl.opengl.GL11.GL_INT; -import static org.lwjgl.opengl.GL11.GL_TRIANGLES; -import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL15C; - -import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; -import static org.lwjgl.opengl.GL15.GL_ELEMENT_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.*; -import static org.lwjgl.opengl.GL20.glGetUniformLocation; -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.glBindVertexArray; -import static org.lwjgl.opengl.GL30.glGenVertexArrays; - -import org.lwjgl.opengl.GL40; -import org.lwjgl.opengl.GL45; - -/** - * - * @author satellite - */ -public class Mesh { - - //THIS IS NOT GUARANTEED TO BE THE PARENT MODEL THAT THIS WAS LOADED IN - //THIS CAN BE POST-LOAD SET IN MODEL VIA MODELMASK BEHAVIOR - public Model parent; - public String nodeID; - public AIMesh mesh; - public int vertexBuffer; - public int normalBuffer; - public int elementArrayBuffer; - public int elementCount; - public int faceCount; - public int vertexArrayObject; - public int vertexCount; - public int normalCount; - public int boneWeightBuffer; - public int boneIndexBuffer; - public int boneCount; - public int textureCoordBuffer; - public int textureCoordCount; - //THIS IS NOT GUARANTEED TO BE THE PARENT MODEL THAT THIS WAS LOADED IN - //THIS CAN BE POST-LOAD SET IN MODEL VIA MODELMASK BEHAVIOR - public ArrayList bones = new ArrayList(); - public ArrayList bone_id_list = new ArrayList(); - HashMap uniforms = new HashMap(); - int bone_map_size = 0; - boolean hasBones = true; - public boolean hasTextureCoords = true; - - public ActorTextureMask textureMask; - - public float vertexMinX; - public float vertexMaxX; - public float vertexMinY; - public float vertexMaxY; - public float vertexMinZ; - public float vertexMaxZ; - - public ShaderProgram shader; - ShaderProgram oitShader; - - int shaderBoneArrayLocation; - - Material material; - - //the bounding sphere for this mesh - Sphered boundingSphere; - - public static Mesh create_mesh_from_aimesh(AIMesh mesh, ModelPretransforms.MeshMetadata metadata){ - boolean has_bones = false; - boolean apply_lighting = true; - - Mesh rVal = new Mesh(); - rVal.mesh = mesh; - rVal.nodeID = mesh.mName().dataString(); - - // - // VAO - // - //Check for headless to not call gl functions when not running with gpu - if(!Globals.HEADLESS){ - rVal.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(rVal.vertexArrayObject); - } - - - - //Basic checks - //check num vertices - int numVertices = mesh.mNumVertices(); - AIVector3D.Buffer vertexData = mesh.mVertices(); - // while(vertexData.hasRemaining()){ - // vertexData.get(); - // numVertices++; - // } - // vertexData = vertexData.rewind(); - //check num normals - int numNormals = mesh.mNumVertices(); - // AIVector3D.Buffer normalData = mesh.mNormals(); - // while(normalData.hasRemaining()){ - // normalData.get(); - // numNormals++; - // } - // normalData.rewind(); - if(numVertices != numNormals){ - LoggerInterface.loggerNetworking.ERROR("Catastrophic failure: Number of vertices =/= Number of normals", new Exception("Catastrophic failure: Number of vertices =/= Number of normals")); - } - - - - - - - - - Matrix4d vertexPretransform = new Matrix4d().identity(); - if(metadata != null){ - LoggerInterface.loggerRenderer.DEBUG("Pretransforming"); - vertexPretransform.translationRotateScale(metadata.getOffset(), metadata.getRotation(), metadata.getScale()); - } - - // - //Buffer data to GPU - // - vertexData.rewind(); - - try { - rVal.vertexCount = mesh.mNumVertices(); - FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(rVal.vertexCount * 3); - float[] temp = new float[3]; - boolean definedDimensions = false; - float minX = 0, maxX = 0, minY = 0, maxY = 0, minZ = 0, maxZ = 0; - for (int i = 0; i < rVal.vertexCount; i++) { - AIVector3D vertex = vertexData.get(); - float x = vertex.x(); - float y = vertex.y(); - float z = vertex.z(); - //store dimensions of the model - if(definedDimensions){ - if(x < minX){ minX = x; } - if(x > maxX){ maxX = x; } - if(y < minY){ minY = y; } - if(y > maxY){ maxY = y; } - if(z < minZ){ minZ = z; } - if(z > maxZ){ maxZ = z; } - } else { - definedDimensions = true; - minX = maxX = x; - minY = maxY = y; - minZ = maxZ = z; - } - //update bounding sphere - double dist = Math.sqrt(x*x+y*y+z*z); - if(dist > rVal.boundingSphere.r){ - rVal.boundingSphere.r = dist; - } - //store vertex data - Vector4d transformedVertex = vertexPretransform.transform(new Vector4d(x,y,z,1.0)); - transformedVertex.w = 1.0; - temp[0] = (float)transformedVertex.x; - temp[1] = (float)transformedVertex.y; - temp[2] = (float)transformedVertex.z; - VertexArrayBufferData.put(temp); - } - - rVal.vertexMaxX = maxX; - rVal.vertexMinX = minX; - rVal.vertexMaxY = maxY; - rVal.vertexMinY = minY; - rVal.vertexMaxZ = maxZ; - rVal.vertexMinZ = minZ; - - VertexArrayBufferData.flip(); - rVal.buffer_vertices(VertexArrayBufferData, 3); - } catch (NullPointerException ex){ - ex.printStackTrace(); - } - // - // NORMALS - // - AIVector3D.Buffer normals = mesh.mNormals(); - try { - rVal.normalCount = mesh.mNumVertices(); - FloatBuffer NormalArrayBufferData; - if(rVal.normalCount > 0){ - NormalArrayBufferData = BufferUtils.createFloatBuffer(rVal.normalCount * 3); - float[] temp = new float[3]; - for (int i = 0; i < rVal.normalCount; i++) { - AIVector3D normal = normals.get(i); - temp[0] = normal.x(); - temp[1] = normal.y(); - temp[2] = normal.z(); - NormalArrayBufferData.put(temp); - } - NormalArrayBufferData.flip(); - rVal.buffer_normals(NormalArrayBufferData, 3); - } - } catch (NullPointerException ex){ - ex.printStackTrace(); - } - // - // FACES - // - rVal.faceCount = mesh.mNumFaces(); - rVal.elementCount = rVal.faceCount * 3; - IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(rVal.elementCount); - AIFace.Buffer facesBuffer = mesh.mFaces(); - for(int i = 0; i < rVal.faceCount; i++){ - AIFace face = facesBuffer.get(i); - if(face.mNumIndices() != 3){ - throw new IllegalStateException("AIFace.mNumIndices() != 3"); - } - elementArrayBufferData.put(face.mIndices()); - } - elementArrayBufferData.flip(); - rVal.buffer_faces(elementArrayBufferData); - - - - - - // - // TEXTURE COORDINATES - // - if(mesh.mTextureCoords().capacity() > 0){ - AIVector3D.Buffer texturecoords = mesh.mTextureCoords(0); - try { - rVal.textureCoordCount = mesh.mTextureCoords(0).capacity(); - FloatBuffer TextureArrayBufferData; - if(rVal.textureCoordCount > 0){ - TextureArrayBufferData = BufferUtils.createFloatBuffer(rVal.textureCoordCount * 2); - float[] temp = new float[2]; - for (int i = 0; i < rVal.textureCoordCount; i++) { - AIVector3D normal = texturecoords.get(i); - temp[0] = normal.x(); - temp[1] = normal.y(); -// temp[2] = normal.z(); - TextureArrayBufferData.put(temp); - } - TextureArrayBufferData.flip(); - rVal.buffer_texture_coords(TextureArrayBufferData, 2); - } - } catch (NullPointerException ex){ - ex.printStackTrace(); - } - //System.out.println("Enabled texture coordinates"); - } - - - - - - - - - - - - - - // - //Read in bones - //AND buffer data (weights) to GPU - // - PointerBuffer boneBuffer = mesh.mBones(); - if(boneBuffer != null){ - has_bones = true; - while(boneBuffer.hasRemaining()){ - long currentAddr = boneBuffer.get(); - AIBone currentBoneData = AIBone.createSafe(currentAddr); -// System.out.println("Num weights: " + currentBoneData.mNumWeights()); - Bone currentBone = new Bone(); - currentBone.boneID = currentBoneData.mName().dataString(); - currentBone.inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrixd(currentBoneData.mOffsetMatrix()); - currentBone.numWeights = currentBoneData.mNumWeights(); - currentBone.weights = new HashMap(); - Iterator weightIterator = currentBoneData.mWeights().iterator(); - while(weightIterator.hasNext()){ - AIVertexWeight currentWeightData = weightIterator.next(); - currentBone.weights.put(currentWeightData.mVertexId(), currentWeightData.mWeight()); - } - rVal.bones.add(currentBone); - rVal.bone_id_list.add(currentBone.boneID); - } - rVal.boneCount = rVal.bones.size(); - FloatBuffer boneWeightDataBuffer = BufferUtils.createFloatBuffer(4 * rVal.vertexCount);//FloatBuffer.allocate(4 * vertexCount); - FloatBuffer boneIndexDataBuffer = BufferUtils.createFloatBuffer(4 * rVal.vertexCount);//IntBuffer.allocate(4 * vertexCount); - Iterator boneIterator; - for(int i = 0; i < rVal.vertexCount; i++){ - float[] weight = new float[4]; - float[] index = new float[4]; - int boneCounter = 0; - boneIterator = rVal.bones.iterator(); - while(boneIterator.hasNext()){ - Bone currentBone = boneIterator.next(); - float boneVal = 0; - if(currentBone.weights.get(i) != null){ - boneVal = currentBone.weights.get(i); - } - if(boneVal > 0){ - if(boneVal > weight[0]){ - weight[3] = weight[2]; - weight[2] = weight[1]; - weight[1] = weight[0]; - weight[0] = boneVal; - index[3] = index[2]; - index[2] = index[1]; - index[1] = index[0]; - index[0] = boneCounter; - // if(rVal.nodeID.equals("Torso")){ - // System.out.println(index[3] + " " + index[2] + " " + index[1] + " " + index[0]); - // } - } else if(boneVal > weight[1]){ - weight[3] = weight[2]; - weight[2] = weight[1]; - weight[1] = boneVal; - index[3] = index[2]; - index[2] = index[1]; - index[1] = boneCounter; - } else if(boneVal > weight[2]){ - weight[3] = weight[2]; - weight[2] = boneVal; - index[3] = index[2]; - index[2] = boneCounter; - } else if(boneVal > weight[3]){ - weight[3] = boneVal; - index[3] = boneCounter; - } - } - boneCounter++; - } - float total = weight[0] + weight[1] + weight[2] + weight[3]; - if(total != 1.0f){ - weight[0] = weight[0] * (1.0f / total); - weight[1] = weight[1] * (1.0f / total); - weight[2] = weight[2] * (1.0f / total); - weight[3] = weight[3] * (1.0f / total); - } - //If all are 0 (for instance the vertex doesn't have any bones with any weight > 0), the values for each weight will be NaN after the divide immediately above - //If NaN, set all to 0 - if(Float.isNaN(weight[0])){ - weight[0] = 0; - weight[1] = 0; - weight[2] = 0; - weight[3] = 0; - } - boneIndexDataBuffer.put(index); - boneWeightDataBuffer.put(weight); - } - boneIndexDataBuffer.flip(); - boneWeightDataBuffer.flip(); - - if(!Globals.HEADLESS){ - rVal.boneWeightBuffer = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, rVal.boneWeightBuffer); - GL15.glBufferData(GL_ARRAY_BUFFER, boneWeightDataBuffer, GL_STATIC_DRAW); - glVertexAttribPointer(2, 4, GL_FLOAT, false, 0, 0); - glEnableVertexAttribArray(2); - - - rVal.boneIndexBuffer = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, rVal.boneIndexBuffer); - GL15.glBufferData(GL_ARRAY_BUFFER, boneIndexDataBuffer, GL_STATIC_DRAW); - glVertexAttribPointer(3, 4, GL_FLOAT, false, 0, 0); - glEnableVertexAttribArray(3); - } - } else { - rVal.hasBones = false; - } - - - - - - - - - - - - if(!Globals.HEADLESS){ - rVal.shader = ShaderProgram.smart_assemble_shader(has_bones, apply_lighting); - rVal.oitShader = ShaderProgram.smartAssembleOITProgram(has_bones, apply_lighting); - } - - - - - - - - - - - - - - - - if(!Globals.HEADLESS){ - glBindVertexArray(0); - } - - - - - - - - - - return rVal; - } - - - public Mesh(){ - this.boundingSphere = new Sphered(); - } - - - public void buffer_vertices(FloatBuffer verticies, int vertexDimension){ - if(!Globals.HEADLESS){ - vertexBuffer = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - GL15.glBufferData(GL_ARRAY_BUFFER, verticies, GL_STATIC_DRAW); - glVertexAttribPointer(0, vertexDimension, GL_FLOAT, false, 0, 0); - glEnableVertexAttribArray(0); - } - } - - public void buffer_normals(FloatBuffer normals, int normalDimension){ - if(!Globals.HEADLESS){ - normalBuffer = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, normalBuffer); - GL15.glBufferData(GL_ARRAY_BUFFER, normals, GL_STATIC_DRAW); - glVertexAttribPointer(1, normalDimension, GL_FLOAT, false, 0, 0); - glEnableVertexAttribArray(1); - } - } - - public void buffer_faces(IntBuffer faces){ - if(!Globals.HEADLESS){ - elementArrayBuffer = glGenBuffers(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer); - GL15.glBufferData(GL_ELEMENT_ARRAY_BUFFER, faces, GL_STATIC_DRAW); - elementCount = faces.capacity(); - } - } - - public void buffer_texture_coords(FloatBuffer coords, int textureDimension){ - if(!Globals.HEADLESS){ - textureCoordBuffer = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, textureCoordBuffer); - GL15.glBufferData(GL_ARRAY_BUFFER, coords, GL_STATIC_DRAW); - glVertexAttribPointer(4, textureDimension, GL_FLOAT, false, 0, 0); - glEnableVertexAttribArray(4); - } - } - - public void bufferCustomFloatAttribArray(FloatBuffer buffer, int bufferDimension, int attribIndex){ - if(!Globals.HEADLESS){ - int customBuffer = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, customBuffer); - GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW); - glVertexAttribPointer(attribIndex, bufferDimension, GL_FLOAT, false, 0, 0); - glEnableVertexAttribArray(attribIndex); - } - } - - public void bufferCustomIntAttribArray(IntBuffer buffer, int bufferDimension, int attribIndex){ - if(!Globals.HEADLESS){ - int customBuffer = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, customBuffer); - GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW); - glVertexAttribPointer(attribIndex, bufferDimension, GL_INT, false, 0, 0); - glEnableVertexAttribArray(attribIndex); - } - } - - public void bufferCustomUIntAttribArray(IntBuffer buffer, int bufferDimension, int attribIndex){ - if(!Globals.HEADLESS){ - int customBuffer = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, customBuffer); - GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW); - glVertexAttribPointer(attribIndex, bufferDimension, GL_UNSIGNED_INT, false, 0, 0); - glEnableVertexAttribArray(attribIndex); - } - } - - public void setTextureMask(ActorTextureMask textureMask){ - this.textureMask = textureMask; - } - - public void setMaterial(Material input){ - this.material = input; - } - - public void generateShader(SelectedShaderEnum selectedShader, boolean hasBones, boolean applyLighting){ - switch(selectedShader){ - case PRIMARY: { - shader = ShaderProgram.smart_assemble_shader(hasBones, applyLighting); - } break; - case OIT: { - oitShader = ShaderProgram.smartAssembleOITProgram(hasBones, applyLighting); - } break; - } - } - - public void setShader(ShaderProgram shader){ - this.shader = shader; - } - - - - public void setUniform(String key, Object o){ - uniforms.put(key, o); - } - - void bufferAllUniforms(){ - for(String key : uniforms.keySet()){ - Object currentUniformRaw = uniforms.get(key); - if(currentUniformRaw instanceof Matrix4f){ - Matrix4f currentUniform = (Matrix4f)currentUniformRaw; - glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, key), false, currentUniform.get(new float[16])); - } - if(currentUniformRaw instanceof Vector3f){ - Vector3f currentUniform = (Vector3f)currentUniformRaw; - glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, key), currentUniform.get(BufferUtils.createFloatBuffer(3))); - } - if(currentUniformRaw instanceof Integer){ - int currentInform = (Integer)currentUniformRaw; - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, key), currentInform); - } - } - } - - /** - * Sends a buffer to the gpu - * @param uniformTypeMap The type of the buffer - * @param buffers The buffer - */ - void bufferInstanceData( - RenderPipelineState renderPipelineState, - Map buffers, - Map uniformGlBufferMap - ){ - for(ShaderAttribute attribute : buffers.keySet()){ - HomogenousInstancedArray buffer = uniformGlBufferMap.get(attribute); - buffer.updateBuffer(buffers.get(attribute), 0); - buffer.bind(renderPipelineState); - } - } - - - /** - * Draws the mesh - * @param renderPipelineState The state of the render pipeline - */ - public void complexDraw(RenderPipelineState renderPipelineState){ - - if(renderPipelineState.getUseMeshShader()){ - ShaderProgram selectedProgram = null; - switch(renderPipelineState.getSelectedShader()){ - case PRIMARY: { - selectedProgram = shader; - } break; - case OIT: { - selectedProgram = oitShader; - } break; - } - if(selectedProgram == null){ - selectedProgram = shader; - } - Globals.renderingEngine.setActiveShader(renderPipelineState, selectedProgram); - } - - if(renderPipelineState.getUseLight()){ - //Until we switch to uniform buffer objects we will have to buffer lighting data here manually each time we draw - //side note: :( - if(Globals.renderingEngine.getLightManager() == null){ - //don't buffer as the light manager hasn't initialized - } else { - LightManager lightManager = Globals.renderingEngine.getLightManager(); - lightManager.bindBuffer(Globals.renderingEngine.getActiveShader().shaderProgram); - } - } - - if(renderPipelineState.getUseMaterial() && textureMask == null){ - if(material == null){ - Globals.materialDefault.apply_material(0,1); - GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasTransparency"), 0); - } else { - material.apply_material(); - if(material.hasTransparency){ - GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasTransparency"), 1); - } else { - GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasTransparency"), 0); - } - } - } - - - - - - glBindVertexArray(vertexArrayObject); - - - - if(textureMask != null){ - int i = 0; -// glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures"), 5); -// for(int j = 1; j < 15; j++){ -// textureList.get(0).bind(j); -// } - for(Texture texture : textureMask.getTextures()){ -// System.out.println(texture.getPath() + " => groundTextures[" + i + "]" + "=>" + (i)); - if(texture != null){ - texture.bind(5+i); - } - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, textureMask.getUniformNames().get(i)),5+i); - i++; - } - // for(int j = i; j < 10; j++){ - // glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures[" + j + "]"),6+j); - // } -// glActiveTexture(GL_TEXTURE0); - } - - if(renderPipelineState.getUseShadowMap()){ - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, Globals.shadowMapTextureLoc); - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "shadowMap"), 3); - } - - - if(renderPipelineState.getUseBones()){ - // - //Handle bones - // - if(bones != null && !bones.isEmpty()){ - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasBones"), 1); - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "numBones"), bones.size()); - Iterator boneIterator = bone_id_list.iterator(); - float bufferarray[] = new float[16]; - int incrementer = 0; - while (boneIterator.hasNext()){ - String boneName = boneIterator.next(); - Bone currentBone = parent.boneMap.get(boneName); - String currentUniform = "bones[" + incrementer + "]"; - if(currentBone != null){ - Matrix4d currentMat = new Matrix4d(currentBone.final_transform); - currentMat.get(bufferarray); - // if(boneName.equals("Torso")){ - // System.out.println("Found torso bone"); - // System.out.println(currentUniform); - // System.out.println(currentMat); - // } - GL45.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, bufferarray); - } else { - // System.out.println("Bonename: " + boneName); - // System.exit(1); - GL45.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, new float[16]); - } - incrementer++; - } - } else { - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasBones"), 0); - } - } else { - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasBones"), 0); - } - - - if(renderPipelineState.getBufferStandardUniforms()){ - //buffer model/view/proj matrices - GL45.glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16])); - glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexViewLoc, false, Globals.viewMatrix.get(new float[16])); - glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16])); - glUniform3fv(Globals.renderingEngine.getActiveShader().shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3))); - glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16])); - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "frame"), (int)Globals.timekeeper.getNumberOfRenderFramesElapsed()); - glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "time"), (float)Globals.timekeeper.getCurrentRendererTime()); - } - - if(renderPipelineState.getBufferNonStandardUniforms()){ - bufferAllUniforms(); - } - - if(renderPipelineState.getInstanced()){ - InstanceData instanceData = renderPipelineState.getInstanceData(); - Map buffers = instanceData.getCpuBufferMap(); - Map glBufferMap = instanceData.getGlBufferMap(); - bufferInstanceData(renderPipelineState, buffers, glBufferMap); - } - - - if(renderPipelineState.getInstanced()){ - GL45.glDrawElementsInstanced(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0, renderPipelineState.getInstanceData().getDrawCount()); - } else { - GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0); - } - glBindVertexArray(0); - } - - /** - * Updates the bounding sphere of the mesh - * @param x - * @param y - * @param z - * @param r - */ - public void updateBoundingSphere(float x, float y, float z, float r){ - this.boundingSphere.x = x; - this.boundingSphere.y = y; - this.boundingSphere.z = z; - this.boundingSphere.r = r; - } - - /** - * Gets the bounding sphere of this mesh - * @return The bounding sphere - */ - public Sphered getBoundingSphere(){ - return this.boundingSphere; - } -} diff --git a/src/main/java/electrosphere/renderer/ModelUtils.java b/src/main/java/electrosphere/renderer/ModelUtils.java deleted file mode 100644 index a8851860..00000000 --- a/src/main/java/electrosphere/renderer/ModelUtils.java +++ /dev/null @@ -1,210 +0,0 @@ -package electrosphere.renderer; - -import electrosphere.engine.Globals; -import electrosphere.engine.assetmanager.AssetDataStrings; -import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.texture.Texture; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import org.joml.Vector3f; -import org.lwjgl.BufferUtils; -import static org.lwjgl.opengl.GL30.glBindVertexArray; -import static org.lwjgl.opengl.GL30.glGenVertexArrays; - -/** - * - * @author satellite - */ -public class ModelUtils { -// public static Model createTerrainModel(float[][] heightfield, int stride){ -// Model rVal = new Model(); -// rVal.meshes = new ArrayList(); -// Mesh m = new Mesh(); -// int width = heightfield.length; -// int height = heightfield[0].length; -// -// int actualWidth = (int)Math.ceil(1.0 * width / stride); -// int actualHeight = (int)Math.ceil(1.0 * height / stride); -// -//// System.out.println(actualWidth + " " + actualHeight); -// -//// System.out.println((actualWidth - 1) * (actualHeight - 1)); -// -// FloatBuffer vertices = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 3); -// FloatBuffer normals = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 3); -// IntBuffer faces = BufferUtils.createIntBuffer((actualWidth - 1) * (actualHeight - 1) * 2 * 3); -// FloatBuffer texture_coords = BufferUtils.createFloatBuffer(actualWidth * actualHeight * 2); -// for(int x = 0; x < width; x = x + stride){ -// for(int y = 0; y < height; y = y + stride){ -// //deal with vertex -// vertices.put(x); -// vertices.put(heightfield[x][y]); -// vertices.put(y); -// //deal with normal -// if(x / stride < actualWidth - 1){ -// if(y / stride < actualHeight - 1){ -// float hL; -// if(x > 0){ -// hL = heightfield[x-1][y]; -// } else { -// hL = heightfield[x][y]; -// } -// float hR = heightfield[x+1][y]; -// float hD = heightfield[x][y+1]; -// float hU; -// if(y > 0){ -// hU = heightfield[x][y-1]; -// } else { -// hU = heightfield[x][y]; -// } -// Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU); -// Normal.normalize(); -// normals.put(Normal.x); -// normals.put(Normal.y); -// normals.put(Normal.z); -// } else { -// float hL; -// if(x > 0){ -// hL = heightfield[x-1][y]; -// } else { -// hL = heightfield[x][y]; -// } -// float hR = heightfield[x+1][y]; -// float hD = heightfield[x][y]; -// float hU = heightfield[x][y-1]; -// Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU); -// Normal.normalize(); -// normals.put(Normal.x); -// normals.put(Normal.y); -// normals.put(Normal.z); -// } -// } else { -// if(y / stride < actualHeight - 1){ -// float hL = heightfield[x-1][y]; -// float hR = heightfield[x][y]; -// float hD = heightfield[x][y+1]; -// float hU; -// if(y > 0){ -// hU = heightfield[x][y-1]; -// } else { -// hU = heightfield[x][y]; -// } -// Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU); -// Normal.normalize(); -// normals.put(Normal.x); -// normals.put(Normal.y); -// normals.put(Normal.z); -// } else { -// float hL = heightfield[x-1][y]; -// float hR = heightfield[x][y]; -// float hD = heightfield[x][y]; -// float hU = heightfield[x][y-1]; -// Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU); -// Normal.normalize(); -// normals.put(Normal.x); -// normals.put(Normal.y); -// normals.put(Normal.z); -// } -// } -// //deal with texture coordinates -// if(x / stride % 2 == 0){ -// if(y / stride % 2 == 0){ -// texture_coords.put(0); -// texture_coords.put(0); -// } else { -// texture_coords.put(0); -// texture_coords.put(1); -// } -// } else { -// if(y / stride % 2 == 0){ -// texture_coords.put(1); -// texture_coords.put(0); -// } else { -// texture_coords.put(1); -// texture_coords.put(1); -// } -// } -// //deal with faces -// if(x / stride < actualWidth - 1 && y / stride < actualHeight - 1){ -// faces.put((x / stride + 0) * actualHeight + (y / stride + 0)); -// faces.put((x / stride + 0) * actualHeight + (y / stride + 1)); -// faces.put((x / stride + 1) * actualHeight + (y / stride + 0)); -// faces.put((x / stride + 1) * actualHeight + (y / stride + 0)); -// faces.put((x / stride + 0) * actualHeight + (y / stride + 1)); -// faces.put((x / stride + 1) * actualHeight + (y / stride + 1)); -// } -// } -// } -// vertices.flip(); -// normals.flip(); -// faces.flip(); -// texture_coords.flip(); -// -// m.vertexArrayObject = glGenVertexArrays(); -// glBindVertexArray(m.vertexArrayObject); -// //buffer vertices -// m.buffer_vertices(vertices, 3); -// //buffer normals -// m.buffer_normals(normals, 3); -// //buffer faces -// m.buffer_faces(faces); -// //buffer texture coords -// m.buffer_texture_coords(texture_coords, 2); -// m.shader = ShaderProgram.loadSpecificShader("/Shaders/terrain/terrain.vs", "/Shaders/terrain/terrain.fs"); -// glBindVertexArray(0); -// m.parent = rVal; -// -// Material groundMat = new Material(); -// Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png"); -// groundMat.set_diffuse("/Textures/Ground/Dirt1.png"); -// groundMat.set_specular("/Textures/Ground/Dirt1.png"); -// m.set_material(groundMat); -// -// rVal.meshes.add(m); -// return rVal; -// } - - - public static void printModelDimension(Model m){ - float minX = 0; - float maxX = 0; - float minY = 0; - float maxY = 0; - float minZ = 0; - float maxZ = 0; - boolean initiated = false; - - for(Mesh currentMesh : m.meshes){ - if(initiated){ - if(currentMesh.vertexMinX < minX){ minX = currentMesh.vertexMinX; } - if(currentMesh.vertexMaxX > maxX){ maxX = currentMesh.vertexMaxX; } - if(currentMesh.vertexMinY < minY){ minY = currentMesh.vertexMinY; } - if(currentMesh.vertexMaxY > maxY){ maxY = currentMesh.vertexMaxY; } - if(currentMesh.vertexMinZ < minZ){ minZ = currentMesh.vertexMinZ; } - if(currentMesh.vertexMaxZ > maxZ){ maxZ = currentMesh.vertexMaxZ; } - } else { - initiated = true; - minX = currentMesh.vertexMinX; - maxX = currentMesh.vertexMaxX; - minY = currentMesh.vertexMinY; - maxY = currentMesh.vertexMaxY; - minZ = currentMesh.vertexMinZ; - maxZ = currentMesh.vertexMaxZ; - } - } - LoggerInterface.loggerRenderer.INFO("dimensions: " + (maxX - minX) + "," + (maxY - minY) + "," + (maxZ-minZ)); - } - - - - - - - - - - -} diff --git a/src/main/java/electrosphere/renderer/OpenGLState.java b/src/main/java/electrosphere/renderer/OpenGLState.java new file mode 100644 index 00000000..f75872d2 --- /dev/null +++ b/src/main/java/electrosphere/renderer/OpenGLState.java @@ -0,0 +1,164 @@ +package electrosphere.renderer; + +import java.util.HashMap; +import java.util.Map; + +import org.joml.Vector2i; +import org.lwjgl.opengl.GL40; + +import electrosphere.renderer.shader.ShaderProgram; + +/** + * Encapsulates the state of opengl. + * The main function of this class is to sit between any consuming classes and opengl. + * It can then deduplicate calls based on the state that is already set. + */ +public class OpenGLState { + + //the current viewport dimensions + private Vector2i viewport = new Vector2i(0,0); + + //whether depth test is enabled or not + boolean depthTest = false; + + //the current depth function + int depthFunction = -1; + + //the currently bound texture + int boundTexturePointer = 0; + int boundTextureType = 0; + + //the currently active texture + int activeTexture = 0; + + //the currently bound framebuffer + int framebufferType = 0; + int framebufferPointer = 0; + + //active shader + ShaderProgram activeShader = null; + + //map of texture units and their corresponding texture pointers + Map unitToPointerMap = new HashMap(); + + /** + * Sets the viewport + * @param x the width + * @param y the height + */ + public void glViewport(int x, int y){ + if(x != viewport.x || y != viewport.y){ + viewport.x = x; + viewport.y = y; + GL40.glViewport(0, 0, viewport.x, viewport.y); + } + } + + /** + * Sets the depth test + * @param depthTest the depth test state + */ + public void glDepthTest(boolean depthTest){ + // if(this.depthTest != depthTest){ + this.depthTest = depthTest; + if(this.depthTest){ + GL40.glEnable(GL40.GL_DEPTH_TEST); + } else { + GL40.glDisable(GL40.GL_DEPTH_TEST); + } + // } + } + + /** + * Sets the depth function + * @param depthFunction The depth function + */ + public void glDepthFunc(int depthFunction){ + if(this.depthFunction != depthFunction){ + this.depthFunction = depthFunction; + GL40.glDepthFunc(this.depthFunction); + } + } + + /** + * Sets the active texture + * @param texture The active texture + */ + public void glActiveTexture(int texture){ + if(this.activeTexture != texture){ + this.activeTexture = texture; + GL40.glActiveTexture(this.activeTexture); + } + } + + /** + * Binds a texture + * @param textureType The type of texture + * @param textureValue The texture pointer + */ + public void glBindTexture(int textureType, int texturePointer){ + if(this.boundTexturePointer != texturePointer || this.boundTextureType != textureType){ + this.boundTextureType = textureType; + this.boundTexturePointer = texturePointer; + GL40.glBindTexture(this.boundTextureType,this.boundTexturePointer); + } + } + + /** + * Binds a texture to a given texture unit if the texture hasn't already been bound to that unit + * @param textureUnit The texture unit + * @param texturePointer The texture pointer + * @param textureType the type of texture (2d, 3d, etc) + */ + public void glBindTextureUnit(int textureUnit, int texturePointer, int textureType){ + if(!unitToPointerMap.containsKey(textureUnit) || unitToPointerMap.get(textureUnit)!=texturePointer){ + unitToPointerMap.put(textureUnit,texturePointer); + GL40.glActiveTexture(textureUnit); + GL40.glBindTexture(textureType,texturePointer); + } + } + + /** + * Binds a framebuffer + * @param framebufferType the type of framebuffer (vanilla, renderbuffer, etc) + * @param framebufferPointer the pointer to the framebuffer + */ + public void glBindFramebuffer(int framebufferType, int framebufferPointer){ + if(this.framebufferType != framebufferType || this.framebufferPointer != framebufferPointer){ + this.framebufferType = framebufferType; + this.framebufferPointer = framebufferPointer; + GL40.glBindFramebuffer(this.framebufferType,this.framebufferPointer); + } + } + + /** + * 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){ + if(program != activeShader){ + activeShader = program; + GL40.glUseProgram(activeShader.getShaderId()); + renderPipelineState.setCurrentShaderPointer(activeShader.getShaderId()); + } + } + + /** + * Gets the active shader program + * @return The active shader + */ + public ShaderProgram getActiveShader(){ + return activeShader; + } + + /** + * Checks whether the provided shader program is the active shader program + * @param program The program to check + * @return true if the provided program is the active program, false otherwise + */ + public boolean isCurrentShader(ShaderProgram program){ + return this.activeShader == program; + } + +} diff --git a/src/main/java/electrosphere/renderer/RenderUtils.java b/src/main/java/electrosphere/renderer/RenderUtils.java index 92014a8b..79e5c820 100644 --- a/src/main/java/electrosphere/renderer/RenderUtils.java +++ b/src/main/java/electrosphere/renderer/RenderUtils.java @@ -12,6 +12,10 @@ import java.util.LinkedList; import java.util.List; import electrosphere.renderer.actor.ActorTextureMask; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.texture.Texture; import org.joml.Matrix4d; @@ -136,264 +140,19 @@ public class RenderUtils { - public static Model createSkyboxModel(Material optionalMaterial){ - Model skyboxModel = new Model(); - skyboxModel.meshes = new ArrayList(); - - skyboxModel.modelMatrix = new Matrix4d(); - - - - // boolean apply_lighting = false; - // boolean has_bones = false; - - Mesh skyboxmesh = new Mesh(){ - @Override - public void complexDraw(RenderPipelineState renderPipelineState){ - if(renderPipelineState.getUseMeshShader()){ - GL11.glDepthFunc(GL_LEQUAL); - glUseProgram(shader.shaderProgram); - } - - if(renderPipelineState.getUseMaterial()){ - if(material == null){ - Globals.materialDefault.apply_material(0,1); - Iterator 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); - - - - if(renderPipelineState.getBufferStandardUniforms()){ - //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); - - if(renderPipelineState.getUseMeshShader()){ - GL11.glDepthFunc(GL_LESS); - } - } - }; - - - skyboxmesh.mesh = null; - - // - // VAO - // - skyboxmesh.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(skyboxmesh.vertexArrayObject); - - - - - - - - - - - float[] vertexcoords = { - 100.0f, 100.0f, 100.0f, - 100.0f, 100.0f,-100.0f, - 100.0f,-100.0f, 100.0f, - 100.0f,-100.0f,-100.0f, - -100.0f, 100.0f, 100.0f, - -100.0f, 100.0f,-100.0f, - -100.0f,-100.0f, 100.0f, - -100.0f,-100.0f,-100.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 Model createParticleModel(){ Model particleModel = new Model(); - particleModel.meshes = new ArrayList(); - particleModel.modelMatrix = new Matrix4d(); - Mesh particleMesh = new Mesh(); + Mesh particleMesh = new Mesh("particleBillboard"); - particleMesh.mesh = null; - // // VAO // - particleMesh.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(particleMesh.vertexArrayObject); + particleMesh.generateVAO(); @@ -417,17 +176,17 @@ public class RenderUtils { // try { - particleMesh.vertexCount = vertexcoords.length / 3; - FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(particleMesh.vertexCount * 3); + int vertexCount = vertexcoords.length / 3; + FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(vertexCount * 3); float[] temp = new float[3]; - for (int i = 0; i < particleMesh.vertexCount; i++) { + for (int i = 0; i < 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(); - particleMesh.buffer_vertices(VertexArrayBufferData, 3); + particleMesh.bufferVertices(VertexArrayBufferData, 3); } catch (NullPointerException ex){ ex.printStackTrace(); } @@ -440,10 +199,10 @@ public class RenderUtils { // // FACES // - particleMesh.faceCount = facedata.length / 3; - particleMesh.elementCount = facedata.length; - IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(particleMesh.elementCount); - for(int i = 0; i < particleMesh.faceCount; i++){ + int faceCount = facedata.length / 3; + int elementCount = facedata.length; + IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(elementCount); + for(int i = 0; i < faceCount; i++){ int[] temp = new int[3]; temp[0] = facedata[i * 3 + 0]; temp[1] = facedata[i * 3 + 1]; @@ -451,7 +210,7 @@ public class RenderUtils { elementArrayBufferData.put(temp); } elementArrayBufferData.flip(); - particleMesh.buffer_faces(elementArrayBufferData); + particleMesh.bufferFaces(elementArrayBufferData,elementCount); // // TEXTURE COORDS @@ -465,13 +224,12 @@ public class RenderUtils { }; texture_coords.put(texturedata); texture_coords.flip(); - particleMesh.buffer_texture_coords(texture_coords, 2); + particleMesh.bufferTextureCoords(texture_coords, 2); - particleMesh.shader = ShaderProgram.loadSpecificShader("Shaders/particleBillboard/particleBillboard.vs", "Shaders/particleBillboard/particleBillboard.fs"); - particleMesh.hasBones = false; + particleMesh.setShader(ShaderProgram.loadSpecificShader("Shaders/particleBillboard/particleBillboard.vs", "Shaders/particleBillboard/particleBillboard.fs")); @@ -486,12 +244,10 @@ public class RenderUtils { - particleMesh.nodeID = "particleBillboard"; - - particleMesh.parent = particleModel; + particleMesh.setParent(particleModel); - particleModel.meshes.add(particleMesh); + particleModel.getMeshes().add(particleMesh); return particleModel; @@ -500,21 +256,16 @@ public class RenderUtils { public static Model createPlaneModel(String vertexShader, String fragmentShader){ Model rVal = new Model(); + - rVal.meshes = new ArrayList(); - rVal.modelMatrix = new Matrix4d(); + Mesh planeMesh = new Mesh("plane"); - Mesh planeMesh = new Mesh(); - - - planeMesh.mesh = null; // // VAO // - planeMesh.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(planeMesh.vertexArrayObject); + planeMesh.generateVAO(); @@ -538,17 +289,17 @@ public class RenderUtils { // try { - planeMesh.vertexCount = vertexcoords.length / 3; - FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(planeMesh.vertexCount * 3); + int vertexCount = vertexcoords.length / 3; + FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(vertexCount * 3); float[] temp = new float[3]; - for (int i = 0; i < planeMesh.vertexCount; i++) { + for (int i = 0; i < 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(); - planeMesh.buffer_vertices(VertexArrayBufferData, 3); + planeMesh.bufferVertices(VertexArrayBufferData, 3); } catch (NullPointerException ex){ ex.printStackTrace(); } @@ -561,10 +312,10 @@ public class RenderUtils { // // FACES // - planeMesh.faceCount = facedata.length / 3; - planeMesh.elementCount = facedata.length; - IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(planeMesh.elementCount); - for(int i = 0; i < planeMesh.faceCount; i++){ + int faceCount = facedata.length / 3; + int elementCount = facedata.length; + IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(elementCount); + for(int i = 0; i < faceCount; i++){ int[] temp = new int[3]; temp[0] = facedata[i * 3 + 0]; temp[1] = facedata[i * 3 + 1]; @@ -572,7 +323,7 @@ public class RenderUtils { elementArrayBufferData.put(temp); } elementArrayBufferData.flip(); - planeMesh.buffer_faces(elementArrayBufferData); + planeMesh.bufferFaces(elementArrayBufferData,elementCount); // // TEXTURE COORDS @@ -586,13 +337,12 @@ public class RenderUtils { }; texture_coords.put(texturedata); texture_coords.flip(); - planeMesh.buffer_texture_coords(texture_coords, 2); + planeMesh.bufferTextureCoords(texture_coords, 2); - planeMesh.shader = ShaderProgram.loadSpecificShader(vertexShader,fragmentShader); - planeMesh.hasBones = false; + planeMesh.setShader(ShaderProgram.loadSpecificShader(vertexShader,fragmentShader)); @@ -607,12 +357,10 @@ public class RenderUtils { - planeMesh.nodeID = "plane"; - - planeMesh.parent = rVal; + planeMesh.setParent(rVal); - rVal.meshes.add(planeMesh); + rVal.getMeshes().add(planeMesh); return rVal; @@ -623,10 +371,8 @@ public class RenderUtils { public static Model createBitmapDisplay(){ Model rVal = new Model(); - rVal.meshes = new ArrayList(); - Mesh m = new Mesh(); - m.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(m.vertexArrayObject); + Mesh m = new Mesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME); + m.generateVAO(); //vertices FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(12); VertexArrayBufferData.put( 0); @@ -684,31 +430,29 @@ public class RenderUtils { //buffer vertices - m.buffer_vertices(VertexArrayBufferData, 2); + m.bufferVertices(VertexArrayBufferData, 2); //buffer normals - m.buffer_normals(VertexArrayBufferData, 2); + m.bufferNormals(VertexArrayBufferData, 2); //buffer faces - m.buffer_faces(faceArrayBufferData); + m.bufferFaces(faceArrayBufferData, 2); //buffer texture coords - m.buffer_texture_coords(TextureArrayBufferData, 2); + m.bufferTextureCoords(TextureArrayBufferData, 2); - m.shader = ShaderProgram.loadSpecificShader("/Shaders/font/basicbitmap/basicbitmap.vs", "/Shaders/font/basicbitmap/basicbitmap.fs"); + m.setShader(ShaderProgram.loadSpecificShader("/Shaders/font/basicbitmap/basicbitmap.vs", "/Shaders/font/basicbitmap/basicbitmap.fs")); glBindVertexArray(0); - m.parent = rVal; - m.nodeID = AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME; + m.setParent(rVal); Material uiMat = new Material(); Globals.assetManager.addTexturePathtoQueue("/Textures/Fonts/myfont1-harsher.png"); uiMat.set_diffuse("/Textures/Fonts/myfont1-harsher.png"); uiMat.set_specular("/Textures/Fonts/myfont1-harsher.png"); m.setMaterial(uiMat); - rVal.materials = new ArrayList(); - rVal.materials.add(uiMat); + rVal.getMaterials().add(uiMat); - rVal.meshes.add(m); + rVal.getMeshes().add(m); return rVal; } @@ -724,10 +468,8 @@ public class RenderUtils { public static Model createBitmapCharacter(){ Model rVal = new Model(); - rVal.meshes = new ArrayList(); - Mesh m = new Mesh(); - m.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(m.vertexArrayObject); + Mesh m = new Mesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME); + m.generateVAO(); //vertices FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(12); VertexArrayBufferData.put(-1); @@ -785,23 +527,22 @@ public class RenderUtils { //buffer vertices - m.buffer_vertices(VertexArrayBufferData, 2); + m.bufferVertices(VertexArrayBufferData, 2); //buffer normals - m.buffer_normals(VertexArrayBufferData, 2); + m.bufferNormals(VertexArrayBufferData, 2); //buffer faces - m.buffer_faces(faceArrayBufferData); + m.bufferFaces(faceArrayBufferData, 6); //buffer texture coords - m.buffer_texture_coords(TextureArrayBufferData, 2); + m.bufferTextureCoords(TextureArrayBufferData, 2); - m.shader = ShaderProgram.loadSpecificShader("/Shaders/font/bitmapchar/bitmapchar.vs", "/Shaders/font/bitmapchar/bitmapchar.fs"); + m.setShader(ShaderProgram.loadSpecificShader("/Shaders/font/bitmapchar/bitmapchar.vs", "/Shaders/font/bitmapchar/bitmapchar.fs")); glBindVertexArray(0); - m.parent = rVal; - m.nodeID = AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME; + m.setParent(rVal); - rVal.meshes.add(m); + rVal.getMeshes().add(m); return rVal; } @@ -811,10 +552,8 @@ public class RenderUtils { public static Model createInWindowPanel(String vertexShader, String fragmentShader){ Model rVal = new Model(); - rVal.meshes = new ArrayList(); - Mesh m = new Mesh(); - m.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(m.vertexArrayObject); + Mesh m = new Mesh("plane"); + m.generateVAO(); //vertices FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(12); VertexArrayBufferData.put(-1); @@ -872,23 +611,22 @@ public class RenderUtils { //buffer vertices - m.buffer_vertices(VertexArrayBufferData, 2); + m.bufferVertices(VertexArrayBufferData, 2); //buffer normals - m.buffer_normals(VertexArrayBufferData, 2); + m.bufferNormals(VertexArrayBufferData, 2); //buffer faces - m.buffer_faces(faceArrayBufferData); + m.bufferFaces(faceArrayBufferData, 2); //buffer texture coords - m.buffer_texture_coords(TextureArrayBufferData, 2); + m.bufferTextureCoords(TextureArrayBufferData, 2); - m.shader = ShaderProgram.loadSpecificShader(vertexShader, fragmentShader); + m.setShader(ShaderProgram.loadSpecificShader(vertexShader, fragmentShader)); glBindVertexArray(0); - m.parent = rVal; - m.nodeID = "plane"; + m.setParent(rVal); - rVal.meshes.add(m); + rVal.getMeshes().add(m); return rVal; } @@ -898,8 +636,7 @@ public class RenderUtils { public static Model createTerrainModelPrecomputedShader(float[][] heightfield, float[][] texturemap, ShaderProgram program, int stride){ Model rVal = new Model(); - rVal.meshes = new ArrayList(); - Mesh m = new Mesh(); + Mesh m = new Mesh("terrain"); int width = heightfield.length; int height = heightfield[0].length; @@ -1044,23 +781,20 @@ public class RenderUtils { texture_coords.flip(); textureIndices.flip(); - m.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(m.vertexArrayObject); + m.generateVAO(); //buffer vertices - m.buffer_vertices(vertices, 3); + m.bufferVertices(vertices, 3); //buffer normals - m.buffer_normals(normals, 3); + m.bufferNormals(normals, 3); //buffer faces - m.buffer_faces(faces); + m.bufferFaces(faces,incrementer*2); //buffer texture coords - m.buffer_texture_coords(texture_coords, 2); + m.bufferTextureCoords(texture_coords, 2); //texture indices m.bufferCustomFloatAttribArray(textureIndices, 4, 5); - m.shader = program; + m.setShader(program); glBindVertexArray(0); - m.parent = rVal; - - m.hasBones = false; + m.setParent(rVal); Material groundMat = new Material(); Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png"); @@ -1068,7 +802,7 @@ public class RenderUtils { groundMat.set_specular("/Textures/Ground/Dirt1.png"); m.setMaterial(groundMat); - rVal.meshes.add(m); + rVal.getMeshes().add(m); return rVal; } @@ -1105,9 +839,7 @@ public class RenderUtils { Model rVal = new Model(); - rVal.meshes = new ArrayList(); - Mesh m = new Mesh(); - m.nodeID = "terrain"; + Mesh m = new Mesh("terrain"); int width = heightfield.length; int height = heightfield[0].length; @@ -1609,23 +1341,20 @@ public class RenderUtils { texture_coords.flip(); textureIndices.flip(); - m.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(m.vertexArrayObject); + m.generateVAO(); //buffer vertices - m.buffer_vertices(vertices, 3); + m.bufferVertices(vertices, 3); //buffer normals - m.buffer_normals(normals, 3); + m.bufferNormals(normals, 3); //buffer faces - m.buffer_faces(faces); + m.bufferFaces(faces,incrementer*2); //buffer texture coords - m.buffer_texture_coords(texture_coords, 2); + m.bufferTextureCoords(texture_coords, 2); //texture indices m.bufferCustomFloatAttribArray(textureIndices, 4, 5); - m.shader = program; + m.setShader(program); glBindVertexArray(0); - m.parent = rVal; - - m.hasBones = false; + m.setParent(rVal); Material groundMat = new Material(); Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png"); @@ -1633,7 +1362,7 @@ public class RenderUtils { groundMat.set_specular("/Textures/Ground/Dirt1.png"); m.setMaterial(groundMat); - rVal.meshes.add(m); + rVal.getMeshes().add(m); return rVal; } @@ -1698,8 +1427,7 @@ public class RenderUtils { public static Model createUnitCube(){ Model rVal = new Model(); - rVal.meshes = new ArrayList(); - Mesh m = new Mesh(); + Mesh m = new Mesh("cube"); // System.out.println(actualWidth + " " + actualHeight); @@ -1839,19 +1567,18 @@ public class RenderUtils { faces.flip(); texture_coords.flip(); - m.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(m.vertexArrayObject); + m.generateVAO(); //buffer vertices - m.buffer_vertices(vertices, 3); + m.bufferVertices(vertices, 3); //buffer normals - m.buffer_normals(normals, 3); + m.bufferNormals(normals, 3); //buffer faces - m.buffer_faces(faces); + m.bufferFaces(faces,12); //buffer texture coords - m.buffer_texture_coords(texture_coords, 2); - m.shader = ShaderProgram.smart_assemble_shader(false,true); + m.bufferTextureCoords(texture_coords, 2); + m.setShader(ShaderProgram.smart_assemble_shader(false,true)); glBindVertexArray(0); - m.parent = rVal; + m.setParent(rVal); Material groundMat = new Material(); Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png"); @@ -1859,7 +1586,7 @@ public class RenderUtils { groundMat.set_specular("/Textures/Ground/Dirt1.png"); m.setMaterial(groundMat); - rVal.meshes.add(m); + rVal.getMeshes().add(m); return rVal; } diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index 44bf57d3..6b808b0c 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -73,6 +73,7 @@ import org.joml.Vector3d; import org.joml.Vector3f; import org.lwjgl.BufferUtils; import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.GLFWWindowSizeCallbackI; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; @@ -99,6 +100,18 @@ import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; import electrosphere.renderer.framebuffer.Renderbuffer; import electrosphere.renderer.light.LightManager; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.pipelines.CompositePipeline; +import electrosphere.renderer.pipelines.DebugContentPipeline; +import electrosphere.renderer.pipelines.MainContentNoOITPipeline; +import electrosphere.renderer.pipelines.MainContentPipeline; +import electrosphere.renderer.pipelines.NormalsForOutlinePipeline; +import electrosphere.renderer.pipelines.PostProcessingPipeline; +import electrosphere.renderer.pipelines.RenderScreenPipeline; +import electrosphere.renderer.pipelines.ShadowMapPipeline; +import electrosphere.renderer.pipelines.UIPipeline; +import electrosphere.renderer.pipelines.VolumeBufferPipeline; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.DrawableElement; import electrosphere.renderer.ui.Element; @@ -120,13 +133,13 @@ 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; + public static Texture screenTextureColor; + public static Texture screenTextureDepth; + public static Framebuffer screenFramebuffer; + public static Renderbuffer screenRenderbuffer; + public static int screenTextureVAO; + public static ShaderProgram screenTextureShaders; + public static ShaderProgram drawChannel; @@ -151,42 +164,42 @@ public class RenderingEngine { //depth framebuffer/shader for shadow mapping - static ShaderProgram lightDepthShaderProgram; - static Framebuffer lightDepthBuffer; + public static ShaderProgram lightDepthShaderProgram; + public 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; + public static float[] transparencyAccumulatorClear; + public static Texture transparencyAccumulatorTexture; + public static float[] transparencyRevealageClear; + public static Texture transparencyRevealageTexture; + public static Framebuffer transparencyBuffer; + public static ShaderProgram oitCompositeProgram; /* render normals */ - static Texture gameImageNormalsTexture; - static Framebuffer gameImageNormalsFramebuffer; - static ShaderProgram renderNormalsShader; + public static Texture gameImageNormalsTexture; + public static Framebuffer gameImageNormalsFramebuffer; + public 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; + public static Matrix4f nearVolumeProjectionMatrix = new Matrix4f(); + public static Matrix4f midVolumeProjectionMatrix = new Matrix4f(); + public static Matrix4f farVolumeProjectionMatrix = new Matrix4f(); + public static ShaderProgram volumeDepthShaderProgram; + public static Framebuffer volumeDepthBackfaceFramebuffer; + public static Texture volumeDepthBackfaceTexture; + public static Framebuffer volumeDepthFrontfaceFramebuffer; + public static Texture volumeDepthFrontfaceTexture; + public static float volumeDepthLinearCoef = 0.1f; + public static float volumeDepthQuadCoef = 0.01f; /* Necessary static variables for drawing */ - static Matrix4d modelTransformMatrix = new Matrix4d(); + public static Matrix4d modelTransformMatrix = new Matrix4d(); /* Vertical volumetrics @@ -200,14 +213,14 @@ public class RenderingEngine { /* Post processing effects (ie kernels) textures, framebuffers, shaders */ - static Texture normalsOutlineTexture; - static Framebuffer normalsOutlineFrambuffer; - static ShaderProgram normalsOutlineShader; + public static Texture normalsOutlineTexture; + public static Framebuffer normalsOutlineFrambuffer; + public static ShaderProgram normalsOutlineShader; /* compositing functions */ - static ShaderProgram compositeAnimeOutline; + public static ShaderProgram compositeAnimeOutline; // public static boolean renderHitboxes = false; @@ -215,9 +228,7 @@ public class RenderingEngine { LightManager lightManager; - ShaderProgram activeProgram; - - static int outputFramebuffer = 0; + public static int outputFramebuffer = 0; //used in calculating projection matrix static float aspectRatio = 1.0f; @@ -225,6 +236,21 @@ public class RenderingEngine { //the current state of the rendering pipeline static RenderPipelineState renderPipelineState = new RenderPipelineState(); + + //the opengl state + static OpenGLState openGLState = new OpenGLState(); + + //render pipelines + MainContentPipeline mainContentPipeline = new MainContentPipeline(); + MainContentNoOITPipeline mainContentNoOITPipeline = new MainContentNoOITPipeline(); + DebugContentPipeline debugContentPipeline = new DebugContentPipeline(); + ShadowMapPipeline shadowMapPipeline = new ShadowMapPipeline(); + VolumeBufferPipeline volumeBufferPipeline = new VolumeBufferPipeline(); + NormalsForOutlinePipeline normalsForOutlinePipeline = new NormalsForOutlinePipeline(); + PostProcessingPipeline postProcessingPipeline = new PostProcessingPipeline(); + CompositePipeline compositePipeline = new CompositePipeline(); + UIPipeline uiPipeline = new UIPipeline(); + RenderScreenPipeline renderScreenPipeline = new RenderScreenPipeline(); public void createOpenglContext(){ @@ -251,13 +277,14 @@ public class RenderingEngine { 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; -// } -// }); + GLFWWindowSizeCallbackI windowSizeCallback = new GLFWWindowSizeCallbackI(){ + @Override + public void invoke(long window, int width, int height){ + Globals.WINDOW_HEIGHT = height; + Globals.WINDOW_WIDTH = width; + } + }; + GLFW.glfwSetWindowSizeCallback(Globals.window, windowSizeCallback); //Makes the window that was just created the current OS-level window context glfwMakeContextCurrent(Globals.window); //Maximize it @@ -339,7 +366,7 @@ public class RenderingEngine { //create light depth framebuffer/shader for shadowmapping // lightDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/lightDepth/lightDepth.vs", "/Shaders/lightDepth/lightDepth.fs"); - Globals.depthMapShaderProgramLoc = lightDepthShaderProgram.shaderProgram; + Globals.depthMapShaderProgramLoc = lightDepthShaderProgram.getShaderId(); lightDepthBuffer = FramebufferUtils.generateDepthBuffer(); Globals.shadowMapTextureLoc = lightDepthBuffer.getTexturePointer(); // glEnable(GL_CULL_FACE); // enabled for shadow mapping @@ -436,25 +463,6 @@ public class RenderingEngine { 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 @@ -466,39 +474,31 @@ public class RenderingEngine { updateFrustumBox(); } - // - //first pass: generate depth map - // + //generate depth map if(Globals.RENDER_FLAG_RENDER_SHADOW_MAP){ - renderShadowMapContent(); + shadowMapPipeline.render(openGLState, renderPipelineState); } - /* - render volume buffer - */ + //render volume buffer if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){ - updateVolumeBuffer(); + volumeBufferPipeline.render(openGLState, renderPipelineState); } - /* - Update light buffer - */ + //Update light buffer lightManager.updateData(); - /* - Render content to the game framebuffer - */ + //Render content to the game framebuffer if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){ if(Globals.userSettings.getGraphicsPerformanceOIT()){ - renderGameContent(); + mainContentPipeline.render(openGLState, renderPipelineState); } else { - renderGameContentNoOIT(); + mainContentNoOITPipeline.render(openGLState, renderPipelineState); } - renderDebugContent(); - renderNormalsForOutline(); - applyKernelsAndPostprocessing(); - compositeGameImage(); + debugContentPipeline.render(openGLState, renderPipelineState); + normalsForOutlinePipeline.render(openGLState, renderPipelineState); + postProcessingPipeline.render(openGLState, renderPipelineState); + compositePipeline.render(openGLState, renderPipelineState); } @@ -510,37 +510,15 @@ public class RenderingEngine { glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); - /* - Render the game framebuffer texture to a quad - */ + //Render the game framebuffer texture to a quad if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER){ - renderScreenFramebuffer(); + renderScreenPipeline.render(openGLState, renderPipelineState); } - /* - Render black background - */ - if(Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND){ - renderBlackBackground(); - } + //render ui + uiPipeline.render(openGLState, renderPipelineState); - /* - 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 - */ + //Render boundaries of ui elements if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){ DebugRendering.drawUIBoundsWireframe(); } @@ -567,980 +545,12 @@ public class RenderingEngine { 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 + * Updates the frustum box of the render pipeline */ - public void setActiveShader(RenderPipelineState renderPipelineState, ShaderProgram program){ - glUseProgram(program.shaderProgram); - activeProgram = program; - renderPipelineState.setCurrentShaderPointer(program.shaderProgram); - } - - public ShaderProgram getActiveShader(){ - return activeProgram; + void updateFrustumBox(){ + renderPipelineState.updateFrustumIntersection(Globals.projectionMatrix, Globals.viewMatrix); } public void bindFramebuffer(int framebufferPointer){ @@ -1622,6 +632,14 @@ public class RenderingEngine { return renderPipelineState; } + /** + * Gets the current opengl state + * @return + */ + public OpenGLState getOpenGLState(){ + return openGLState; + } + /** * Tries to recapture the screen */ diff --git a/src/main/java/electrosphere/renderer/actor/Actor.java b/src/main/java/electrosphere/renderer/actor/Actor.java index 9ae9d554..c0dd927a 100644 --- a/src/main/java/electrosphere/renderer/actor/Actor.java +++ b/src/main/java/electrosphere/renderer/actor/Actor.java @@ -1,9 +1,10 @@ package electrosphere.renderer.actor; import electrosphere.engine.Globals; -import electrosphere.renderer.Bone; -import electrosphere.renderer.Model; +import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.model.Bone; +import electrosphere.renderer.model.Model; import electrosphere.renderer.texture.Texture; import java.util.HashMap; @@ -123,7 +124,7 @@ public class Actor { if(model != null && model.getAnimation(animationName) != null){ double length = model.getAnimation(animationName).duration; ActorAnimationMask animMask = new ActorAnimationMask(priority, animationName, 0, length); - for(Bone bone : model.bones){ + for(Bone bone : model.getBones()){ animMask.addBone(bone.boneID); } toRemoveMasks.clear(); @@ -188,7 +189,7 @@ public class Actor { public void applyModelMatrix(Matrix4d modelMatrix){ Model model = Globals.assetManager.fetchModel(modelPath); if(model != null){ - model.modelMatrix = modelMatrix; + model.setModelMatrix(modelMatrix); } } @@ -196,7 +197,7 @@ public class Actor { * Draws an actor * @param renderPipelineState The render pipeline state to draw within */ - public void draw(RenderPipelineState renderPipelineState){ + public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState){ Model model = Globals.assetManager.fetchModel(modelPath); boolean hasDrawn = false; if(model != null && isWithinFrustumBox(renderPipelineState,model)){ @@ -223,13 +224,13 @@ public class Actor { if(textureOverride != null){ Texture overrideTextureObject = Globals.assetManager.fetchTexture(textureOverride); if(overrideTextureObject != null){ - overrideTextureObject.bind(); + overrideTextureObject.bind(openGLState); hasDrawn = true; - model.draw(renderPipelineState); + model.draw(renderPipelineState,openGLState); } } if(!hasDrawn){ - model.draw(renderPipelineState); + model.draw(renderPipelineState,openGLState); } model.getShaderMask().clear(); model.setTextureMask(null); @@ -257,7 +258,7 @@ public class Actor { // model.playAnimation(animation); // model.incrementTime(animationTime); // model.updateNodeTransform(); - Bone currentBone = model.boneMap.get(boneName); + Bone currentBone = model.getBoneMap().get(boneName); if(currentBone != null){ Vector4d result = currentBone.final_transform.transform(new Matrix4d(currentBone.inverseBindPoseMatrix).invert().transform(new Vector4d(rVal.x,rVal.y,rVal.z,1))); // currentBone.inverseBindPoseMatrix @@ -279,7 +280,7 @@ public class Actor { // if(animation != null){ // model.playAnimation(animation); // model.incrementTime(animationTime); - Bone currentBone = model.boneMap.get(boneName); + Bone currentBone = model.getBoneMap().get(boneName); if(currentBone != null){ AxisAngle4f axisAngle = new AxisAngle4f(); new Matrix4f(currentBone.final_transform).getRotation(axisAngle); @@ -301,7 +302,7 @@ public class Actor { // model.playAnimation(animation); // model.incrementTime(animationTime); // model.updateNodeTransform(); - Bone currentBone = model.boneMap.get(boneName); + Bone currentBone = model.getBoneMap().get(boneName); if(currentBone != null){ rVal = currentBone.final_transform; // currentBone.inverseBindPoseMatrix @@ -372,7 +373,7 @@ public class Actor { */ static boolean isWithinFrustumBox(RenderPipelineState renderPipelineState, Model model){ Sphered sphere = model.getBoundingSphere(); - Vector3d modelPosition = model.modelMatrix.getTranslation(new Vector3d()); + Vector3d modelPosition = model.getModelMatrix().getTranslation(new Vector3d()); return renderPipelineState.getFrustumIntersection().testSphere((float)(sphere.x + modelPosition.x), (float)(sphere.y + modelPosition.y), (float)(sphere.z + modelPosition.z), (float)sphere.r); } diff --git a/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java b/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java index a4dc8b1d..4c506155 100644 --- a/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java +++ b/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java @@ -8,8 +8,8 @@ import java.util.concurrent.Semaphore; import java.util.stream.Collectors; import electrosphere.engine.Globals; -import electrosphere.renderer.Mesh; -import electrosphere.renderer.Model; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.model.Model; public class ActorMeshMask { @@ -45,7 +45,7 @@ public class ActorMeshMask { for(MeshDrawQueueItem item : queuedMeshes){ if((model = Globals.assetManager.fetchModel(item.getModelName())) != null){ if((mesh = model.getMesh(item.getMeshName())) != null){ - toDrawMesh.put(mesh.nodeID,mesh); + toDrawMesh.put(mesh.getMeshName(),mesh); toRemove.add(item); } } diff --git a/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java b/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java index 8998bfef..e813d31b 100644 --- a/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java +++ b/src/main/java/electrosphere/renderer/actor/instance/InstanceManager.java @@ -7,11 +7,12 @@ import java.util.Map; import electrosphere.engine.Globals; -import electrosphere.renderer.Model; +import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.ShaderProgram; import electrosphere.renderer.buffer.ShaderAttribute; import electrosphere.renderer.buffer.HomogenousUniformBuffer.HomogenousBufferTypes; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.shader.ShaderProgram; /** * Manages all instanced actors. This is what actually does the draw call in opengl. @@ -69,7 +70,7 @@ public class InstanceManager { /** * Draws all models that are queued in this instance manager */ - public void draw(RenderPipelineState renderPipelineState){ + public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState){ renderPipelineState.setInstanced(true); renderPipelineState.setUseMeshShader(false); for(String modelPath : modelsToDraw){ @@ -84,8 +85,8 @@ public class InstanceManager { ShaderProgram shader = Globals.assetManager.fetchShader(data.vertexShaderPath, null, data.fragmentShaderPath); Model model = Globals.assetManager.fetchModel(modelPath); if(model != null && shader != null){ - Globals.renderingEngine.setActiveShader(renderPipelineState, shader); - model.draw(renderPipelineState); + openGLState.setActiveShader(renderPipelineState, shader); + model.draw(renderPipelineState,openGLState); } data.flip(); diff --git a/src/main/java/electrosphere/renderer/actor/instance/InstancedActor.java b/src/main/java/electrosphere/renderer/actor/instance/InstancedActor.java index ae737393..0d93db53 100644 --- a/src/main/java/electrosphere/renderer/actor/instance/InstancedActor.java +++ b/src/main/java/electrosphere/renderer/actor/instance/InstancedActor.java @@ -15,9 +15,9 @@ import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Model; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.buffer.ShaderAttribute; +import electrosphere.renderer.model.Model; /** * An instanced actor is a static (not bone animated) actor for an instanced model (eg grass, trees, leaves, rocks, etc) diff --git a/src/main/java/electrosphere/renderer/anim/Animation.java b/src/main/java/electrosphere/renderer/anim/Animation.java index ba4e1b6a..fbb52622 100644 --- a/src/main/java/electrosphere/renderer/anim/Animation.java +++ b/src/main/java/electrosphere/renderer/anim/Animation.java @@ -19,6 +19,7 @@ import org.lwjgl.assimp.AINodeAnim; import org.lwjgl.assimp.AIQuatKey; import org.lwjgl.assimp.AIVectorKey; +import electrosphere.logger.LoggerInterface; import electrosphere.renderer.loading.ModelPretransforms; /** @@ -204,32 +205,32 @@ public class Animation { meshChannelData = null; } public void describeAnimation(){ - System.out.println("====================="); - System.out.println("Name: \"" + name + "\""); - System.out.println("ID: " + ID); - System.out.println("Duration: " + duration); - System.out.println("Ticks per second: " + ticksPerSecond); + LoggerInterface.loggerRenderer.DEBUG("====================="); + LoggerInterface.loggerRenderer.DEBUG("Name: \"" + name + "\""); + LoggerInterface.loggerRenderer.DEBUG("ID: " + ID); + LoggerInterface.loggerRenderer.DEBUG("Duration: " + duration); + LoggerInterface.loggerRenderer.DEBUG("Ticks per second: " + ticksPerSecond); Iterator channelIterator = channels.iterator(); while(channelIterator.hasNext()){ AnimChannel channelCurrent = channelIterator.next(); - System.out.println("====================="); + LoggerInterface.loggerRenderer.DEBUG("====================="); channelCurrent.describeChannel(); } - System.out.println("====================="); + LoggerInterface.loggerRenderer.DEBUG("====================="); } public void fullDescribeAnimation(){ - System.out.println("====================="); - System.out.println("Name: " + name); - System.out.println("ID: " + ID); - System.out.println("Duration: " + duration); - System.out.println("Ticks per second: " + ticksPerSecond); + LoggerInterface.loggerRenderer.DEBUG("====================="); + LoggerInterface.loggerRenderer.DEBUG("Name: " + name); + LoggerInterface.loggerRenderer.DEBUG("ID: " + ID); + LoggerInterface.loggerRenderer.DEBUG("Duration: " + duration); + LoggerInterface.loggerRenderer.DEBUG("Ticks per second: " + ticksPerSecond); Iterator channelIterator = channels.iterator(); while(channelIterator.hasNext()){ AnimChannel channelCurrent = channelIterator.next(); - System.out.println("====================="); + LoggerInterface.loggerRenderer.DEBUG("====================="); channelCurrent.fullDescribeChannel(); } - System.out.println("====================="); + LoggerInterface.loggerRenderer.DEBUG("====================="); } public boolean incrementTime(double time){ diff --git a/src/main/java/electrosphere/renderer/debug/DebugRendering.java b/src/main/java/electrosphere/renderer/debug/DebugRendering.java index 7a5cb241..fb1015be 100644 --- a/src/main/java/electrosphere/renderer/debug/DebugRendering.java +++ b/src/main/java/electrosphere/renderer/debug/DebugRendering.java @@ -11,9 +11,9 @@ import org.joml.Vector3f; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Model; import electrosphere.renderer.RenderingEngine; -import electrosphere.renderer.ShaderProgram; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.ui.ContainerElement; import electrosphere.renderer.ui.DrawableElement; import electrosphere.renderer.ui.Element; @@ -61,7 +61,7 @@ public class DebugRendering { } if(elementDrawDebugProgram != null && planeModel != null){ Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); - Globals.renderingEngine.setActiveShader(Globals.renderingEngine.getRenderPipelineState(), elementDrawDebugProgram); + Globals.renderingEngine.getOpenGLState().setActiveShader(Globals.renderingEngine.getRenderPipelineState(), elementDrawDebugProgram); planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "color", color); @@ -70,7 +70,7 @@ public class DebugRendering { // Globals.renderingEngine.setActiveShader(Globals.assetManager.fetchShader("Shaders/plane/plane.vs", null, "Shaders/plane/plane.fs")); // } //drawUI sets shader so overriding window bound shader - planeModel.draw(Globals.renderingEngine.getRenderPipelineState()); + planeModel.draw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState()); } } } @@ -85,7 +85,7 @@ public class DebugRendering { } if(windowDrawDebugProgram != null && planeModel != null){ Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); - Globals.renderingEngine.setActiveShader(Globals.renderingEngine.getRenderPipelineState(), windowDrawDebugProgram); + Globals.renderingEngine.getOpenGLState().setActiveShader(Globals.renderingEngine.getRenderPipelineState(), windowDrawDebugProgram); planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "color", color); @@ -94,7 +94,7 @@ public class DebugRendering { // Globals.renderingEngine.setActiveShader(Globals.assetManager.fetchShader("Shaders/plane/plane.vs", null, "Shaders/plane/plane.fs")); // } //drawUI sets shader so overriding window bound shader - planeModel.draw(Globals.renderingEngine.getRenderPipelineState()); + planeModel.draw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState()); } } } diff --git a/src/main/java/electrosphere/renderer/loading/ModelLoader.java b/src/main/java/electrosphere/renderer/loading/ModelLoader.java index cca666ca..21063834 100644 --- a/src/main/java/electrosphere/renderer/loading/ModelLoader.java +++ b/src/main/java/electrosphere/renderer/loading/ModelLoader.java @@ -3,9 +3,9 @@ package electrosphere.renderer.loading; import electrosphere.engine.Globals; import electrosphere.engine.Main; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Material; -import electrosphere.renderer.Mesh; -import electrosphere.renderer.Model; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.model.Model; import electrosphere.renderer.texture.Texture; import electrosphere.renderer.texture.TextureMap; import electrosphere.util.FileUtils; @@ -65,18 +65,18 @@ public class ModelLoader { //if it exists.. if(mesh_map != null){ //iterate through each mesh in the model that was provided as input - Iterator mesh_iterator = m.meshes.iterator(); + Iterator mesh_iterator = m.getMeshes().iterator(); while(mesh_iterator.hasNext()){ Mesh current_mesh = mesh_iterator.next(); - LoggerInterface.loggerRenderer.DEBUG(current_mesh.nodeID); + LoggerInterface.loggerRenderer.DEBUG(current_mesh.getMeshName()); //if the current iteration is contained within the mesh map we procured from above - if(mesh_map.containsKey(current_mesh.nodeID)){ + if(mesh_map.containsKey(current_mesh.getMeshName())){ //we create a new material, check if the diffuse or specular is not null, //and if they aren't we add that path as a new texture of respective type to the material Material final_material = new Material(); - List texture_path_list = mesh_map.get(current_mesh.nodeID); + List texture_path_list = mesh_map.get(current_mesh.getMeshName()); String diffuse_path = TextureMap.get_diffuse_path(texture_path_list); - LoggerInterface.loggerRenderer.DEBUG(current_mesh.nodeID + "->" + diffuse_path); + LoggerInterface.loggerRenderer.DEBUG(current_mesh.getMeshName() + "->" + diffuse_path); if(diffuse_path != null){ LoggerInterface.loggerRenderer.DEBUG(diffuse_path); // Texture diffuse = new Texture(diffuse_path); @@ -99,7 +99,7 @@ public class ModelLoader { //set the current mesh's material to this new one current_mesh.setMaterial(final_material); } else { - LoggerInterface.loggerRenderer.WARNING("Failed to load texture for node " + current_mesh.nodeID + " of model " + path); + LoggerInterface.loggerRenderer.WARNING("Failed to load texture for node " + current_mesh.getMeshName() + " of model " + path); } } } diff --git a/src/main/java/electrosphere/renderer/meshgen/FluidChunkModelGeneration.java b/src/main/java/electrosphere/renderer/meshgen/FluidChunkModelGeneration.java index 05851ed4..a4fe24f8 100644 --- a/src/main/java/electrosphere/renderer/meshgen/FluidChunkModelGeneration.java +++ b/src/main/java/electrosphere/renderer/meshgen/FluidChunkModelGeneration.java @@ -13,10 +13,10 @@ import org.lwjgl.BufferUtils; import electrosphere.engine.Globals; import electrosphere.entity.types.fluid.FluidChunkModelData; -import electrosphere.renderer.Material; -import electrosphere.renderer.Mesh; -import electrosphere.renderer.Model; -import electrosphere.renderer.ShaderProgram; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.shader.ShaderProgram; import static org.lwjgl.opengl.GL30.glBindVertexArray; import static org.lwjgl.opengl.GL30.glGenVertexArrays; @@ -677,16 +677,14 @@ public class FluidChunkModelGeneration { */ protected static Mesh generateFluidMesh(FluidChunkModelData data){ - Mesh mesh = new Mesh(); + Mesh mesh = new Mesh("fluidChunk"); - mesh.mesh = null; // // VAO // - mesh.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(mesh.vertexArrayObject); + mesh.generateVAO(); @@ -698,14 +696,14 @@ public class FluidChunkModelGeneration { // try { - mesh.vertexCount = data.getVertices().size() / 3; - FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(mesh.vertexCount * 3); + int vertexCount = data.getVertices().size() / 3; + FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(vertexCount * 3); float[] temp = new float[3]; for(float vertValue : data.getVertices()){ VertexArrayBufferData.put(vertValue); } VertexArrayBufferData.flip(); - mesh.buffer_vertices(VertexArrayBufferData, 3); + mesh.bufferVertices(VertexArrayBufferData, 3); } catch (NullPointerException ex){ ex.printStackTrace(); } @@ -715,16 +713,16 @@ public class FluidChunkModelGeneration { // // FACES // - mesh.faceCount = data.getFaceElements().size() / 3; - mesh.elementCount = data.getFaceElements().size(); + int faceCount = data.getFaceElements().size() / 3; + int elementCount = data.getFaceElements().size(); try { - IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(mesh.elementCount); + IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(elementCount); int[] temp = new int[3]; for(int element : data.getFaceElements()){ elementArrayBufferData.put(element); } elementArrayBufferData.flip(); - mesh.buffer_faces(elementArrayBufferData); + mesh.bufferFaces(elementArrayBufferData,elementCount); } catch (NullPointerException ex){ ex.printStackTrace(); } @@ -736,16 +734,16 @@ public class FluidChunkModelGeneration { // NORMALS // try { - mesh.normalCount = data.getNormals().size() / 3; + int normalCount = data.getNormals().size() / 3; FloatBuffer NormalArrayBufferData; - if(mesh.normalCount > 0){ - NormalArrayBufferData = BufferUtils.createFloatBuffer(mesh.normalCount * 3); + if(normalCount > 0){ + NormalArrayBufferData = BufferUtils.createFloatBuffer(normalCount * 3); float[] temp = new float[3]; for(float normalValue : data.getNormals()){ NormalArrayBufferData.put(normalValue); } NormalArrayBufferData.flip(); - mesh.buffer_normals(NormalArrayBufferData, 3); + mesh.bufferNormals(NormalArrayBufferData, 3); } } catch (NullPointerException ex){ ex.printStackTrace(); @@ -755,16 +753,16 @@ public class FluidChunkModelGeneration { // TEXTURE COORDINATES // try { - mesh.textureCoordCount = data.getUVs().size() / 2; + int textureCoordCount = data.getUVs().size() / 2; FloatBuffer TextureArrayBufferData; - if(mesh.textureCoordCount > 0){ - TextureArrayBufferData = BufferUtils.createFloatBuffer(mesh.textureCoordCount * 2); + if(textureCoordCount > 0){ + TextureArrayBufferData = BufferUtils.createFloatBuffer(textureCoordCount * 2); float[] temp = new float[2]; for(float uvValue : data.getUVs()){ TextureArrayBufferData.put(uvValue); } TextureArrayBufferData.flip(); - mesh.buffer_texture_coords(TextureArrayBufferData, 2); + mesh.bufferTextureCoords(TextureArrayBufferData, 2); } } catch (NullPointerException ex){ ex.printStackTrace(); @@ -774,7 +772,6 @@ public class FluidChunkModelGeneration { glBindVertexArray(0); - mesh.nodeID = "fluidChunk"; return mesh; } @@ -786,7 +783,6 @@ public class FluidChunkModelGeneration { */ public static Model generateFluidModel(FluidChunkModelData data){ Model rVal = new Model(); - rVal.meshes = new ArrayList(); Mesh m = generateFluidMesh(data); @@ -797,9 +793,9 @@ public class FluidChunkModelGeneration { m.setMaterial(groundMat); m.setShader(FluidChunkModelGeneration.fluidChunkShaderProgram); - m.parent = rVal; + m.setParent(rVal); - rVal.meshes.add(m); + rVal.getMeshes().add(m); return rVal; } diff --git a/src/main/java/electrosphere/renderer/meshgen/MeshLoader.java b/src/main/java/electrosphere/renderer/meshgen/MeshLoader.java new file mode 100644 index 00000000..2975d557 --- /dev/null +++ b/src/main/java/electrosphere/renderer/meshgen/MeshLoader.java @@ -0,0 +1,330 @@ +package electrosphere.renderer.meshgen; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.HashMap; +import java.util.Iterator; + +import org.joml.Matrix4d; +import org.joml.Vector4d; +import org.lwjgl.BufferUtils; +import org.lwjgl.PointerBuffer; +import org.lwjgl.assimp.AIBone; +import org.lwjgl.assimp.AIFace; +import org.lwjgl.assimp.AIMesh; +import org.lwjgl.assimp.AIVector3D; +import org.lwjgl.assimp.AIVertexWeight; + +import electrosphere.engine.Globals; +import electrosphere.logger.LoggerInterface; +import electrosphere.renderer.loading.ModelPretransforms; +import electrosphere.renderer.model.Bone; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.shader.ShaderProgram; + +/** + * Main class for loading meshes from assimp scenes + */ +public class MeshLoader { + + public static Mesh createMeshFromAIScene(AIMesh mesh, ModelPretransforms.MeshMetadata metadata){ + boolean has_bones = false; + boolean apply_lighting = true; + + Mesh rVal = new Mesh(mesh.mName().dataString()); + + // + // VAO + // + //Check for headless to not call gl functions when not running with gpu + if(!Globals.HEADLESS){ + rVal.generateVAO(); + } + + + + //Basic checks + //check num vertices + int numVertices = mesh.mNumVertices(); + AIVector3D.Buffer vertexData = mesh.mVertices(); + // while(vertexData.hasRemaining()){ + // vertexData.get(); + // numVertices++; + // } + // vertexData = vertexData.rewind(); + //check num normals + int numNormals = mesh.mNumVertices(); + // AIVector3D.Buffer normalData = mesh.mNormals(); + // while(normalData.hasRemaining()){ + // normalData.get(); + // numNormals++; + // } + // normalData.rewind(); + if(numVertices != numNormals){ + LoggerInterface.loggerNetworking.ERROR("Catastrophic failure: Number of vertices =/= Number of normals", new Exception("Catastrophic failure: Number of vertices =/= Number of normals")); + } + + + + + + + + + Matrix4d vertexPretransform = new Matrix4d().identity(); + if(metadata != null){ + LoggerInterface.loggerRenderer.DEBUG("Pretransforming"); + vertexPretransform.translationRotateScale(metadata.getOffset(), metadata.getRotation(), metadata.getScale()); + } + + // + //Buffer data to GPU + // + vertexData.rewind(); + + int vertexCount = 0; + try { + vertexCount = mesh.mNumVertices(); + FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(vertexCount * 3); + float[] temp = new float[3]; + boolean definedDimensions = false; + float minX = 0, maxX = 0, minY = 0, maxY = 0, minZ = 0, maxZ = 0; + for (int i = 0; i < vertexCount; i++) { + AIVector3D vertex = vertexData.get(); + float x = vertex.x(); + float y = vertex.y(); + float z = vertex.z(); + //store dimensions of the model + if(definedDimensions){ + if(x < minX){ minX = x; } + if(x > maxX){ maxX = x; } + if(y < minY){ minY = y; } + if(y > maxY){ maxY = y; } + if(z < minZ){ minZ = z; } + if(z > maxZ){ maxZ = z; } + } else { + definedDimensions = true; + minX = maxX = x; + minY = maxY = y; + minZ = maxZ = z; + } + //update bounding sphere + double dist = Math.sqrt(x*x+y*y+z*z); + if(dist > rVal.getBoundingSphere().r){ + rVal.getBoundingSphere().r = dist; + } + //store vertex data + Vector4d transformedVertex = vertexPretransform.transform(new Vector4d(x,y,z,1.0)); + transformedVertex.w = 1.0; + temp[0] = (float)transformedVertex.x; + temp[1] = (float)transformedVertex.y; + temp[2] = (float)transformedVertex.z; + VertexArrayBufferData.put(temp); + } + + VertexArrayBufferData.flip(); + rVal.bufferVertices(VertexArrayBufferData, 3); + } catch (NullPointerException ex){ + ex.printStackTrace(); + } + // + // NORMALS + // + AIVector3D.Buffer normals = mesh.mNormals(); + try { + int normalCount = mesh.mNumVertices(); + FloatBuffer NormalArrayBufferData; + if(normalCount > 0){ + NormalArrayBufferData = BufferUtils.createFloatBuffer(normalCount * 3); + float[] temp = new float[3]; + for (int i = 0; i < normalCount; i++) { + AIVector3D normal = normals.get(i); + temp[0] = normal.x(); + temp[1] = normal.y(); + temp[2] = normal.z(); + NormalArrayBufferData.put(temp); + } + NormalArrayBufferData.flip(); + rVal.bufferNormals(NormalArrayBufferData, 3); + } + } catch (NullPointerException ex){ + ex.printStackTrace(); + } + // + // FACES + // + int faceCount = mesh.mNumFaces(); + int elementCount = faceCount * 3; + IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(elementCount); + AIFace.Buffer facesBuffer = mesh.mFaces(); + for(int i = 0; i < faceCount; i++){ + AIFace face = facesBuffer.get(i); + if(face.mNumIndices() != 3){ + throw new IllegalStateException("AIFace.mNumIndices() != 3"); + } + elementArrayBufferData.put(face.mIndices()); + } + elementArrayBufferData.flip(); + rVal.bufferFaces(elementArrayBufferData,elementCount); + + + + + + // + // TEXTURE COORDINATES + // + if(mesh.mTextureCoords().capacity() > 0){ + AIVector3D.Buffer texturecoords = mesh.mTextureCoords(0); + try { + int textureCoordCount = mesh.mTextureCoords(0).capacity(); + FloatBuffer TextureArrayBufferData; + if(textureCoordCount > 0){ + TextureArrayBufferData = BufferUtils.createFloatBuffer(textureCoordCount * 2); + float[] temp = new float[2]; + for (int i = 0; i < textureCoordCount; i++) { + AIVector3D normal = texturecoords.get(i); + temp[0] = normal.x(); + temp[1] = normal.y(); +// temp[2] = normal.z(); + TextureArrayBufferData.put(temp); + } + TextureArrayBufferData.flip(); + rVal.bufferTextureCoords(TextureArrayBufferData, 2); + } + } catch (NullPointerException ex){ + ex.printStackTrace(); + } + //System.out.println("Enabled texture coordinates"); + } + + + + + + + + + + + + + + // + //Read in bones + //AND buffer data (weights) to GPU + // + PointerBuffer boneBuffer = mesh.mBones(); + if(boneBuffer != null){ + has_bones = true; + while(boneBuffer.hasRemaining()){ + long currentAddr = boneBuffer.get(); + AIBone currentBoneData = AIBone.createSafe(currentAddr); +// System.out.println("Num weights: " + currentBoneData.mNumWeights()); + Bone currentBone = new Bone(currentBoneData); + currentBone.boneID = currentBoneData.mName().dataString(); + currentBone.inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrixd(currentBoneData.mOffsetMatrix()); + Iterator weightIterator = currentBoneData.mWeights().iterator(); + while(weightIterator.hasNext()){ + AIVertexWeight currentWeightData = weightIterator.next(); + currentBone.putWeight(currentWeightData.mVertexId(), currentWeightData.mWeight()); + } + rVal.getBones().add(currentBone); + rVal.registerBoneId(currentBone.boneID); + } + FloatBuffer boneWeightDataBuffer = BufferUtils.createFloatBuffer(4 * vertexCount);//FloatBuffer.allocate(4 * vertexCount); + FloatBuffer boneIndexDataBuffer = BufferUtils.createFloatBuffer(4 * vertexCount);//IntBuffer.allocate(4 * vertexCount); + Iterator boneIterator; + for(int i = 0; i < vertexCount; i++){ + float[] weight = new float[4]; + float[] index = new float[4]; + int boneCounter = 0; + boneIterator = rVal.getBones().iterator(); + while(boneIterator.hasNext()){ + Bone currentBone = boneIterator.next(); + float boneVal = 0; + if(currentBone.getWeights().get(i) != null){ + boneVal = currentBone.getWeights().get(i); + } + if(boneVal > 0){ + if(boneVal > weight[0]){ + weight[3] = weight[2]; + weight[2] = weight[1]; + weight[1] = weight[0]; + weight[0] = boneVal; + index[3] = index[2]; + index[2] = index[1]; + index[1] = index[0]; + index[0] = boneCounter; + // if(rVal.nodeID.equals("Torso")){ + // System.out.println(index[3] + " " + index[2] + " " + index[1] + " " + index[0]); + // } + } else if(boneVal > weight[1]){ + weight[3] = weight[2]; + weight[2] = weight[1]; + weight[1] = boneVal; + index[3] = index[2]; + index[2] = index[1]; + index[1] = boneCounter; + } else if(boneVal > weight[2]){ + weight[3] = weight[2]; + weight[2] = boneVal; + index[3] = index[2]; + index[2] = boneCounter; + } else if(boneVal > weight[3]){ + weight[3] = boneVal; + index[3] = boneCounter; + } + } + boneCounter++; + } + float total = weight[0] + weight[1] + weight[2] + weight[3]; + if(total != 1.0f){ + weight[0] = weight[0] * (1.0f / total); + weight[1] = weight[1] * (1.0f / total); + weight[2] = weight[2] * (1.0f / total); + weight[3] = weight[3] * (1.0f / total); + } + //If all are 0 (for instance the vertex doesn't have any bones with any weight > 0), the values for each weight will be NaN after the divide immediately above + //If NaN, set all to 0 + if(Float.isNaN(weight[0])){ + weight[0] = 0; + weight[1] = 0; + weight[2] = 0; + weight[3] = 0; + } + boneIndexDataBuffer.put(index); + boneWeightDataBuffer.put(weight); + } + boneIndexDataBuffer.flip(); + boneWeightDataBuffer.flip(); + + if(!Globals.HEADLESS){ + rVal.bufferBoneIndices(boneIndexDataBuffer); + + rVal.bufferBoneWeights(boneWeightDataBuffer); + } + } + + + + + + + + + + + + if(!Globals.HEADLESS){ + rVal.setShader(ShaderProgram.smart_assemble_shader(has_bones, apply_lighting)); + rVal.setShader(ShaderProgram.smart_assemble_shader(has_bones, apply_lighting)); + rVal.setOITShader(ShaderProgram.smartAssembleOITProgram(has_bones, apply_lighting)); + } + + + + return rVal; + } + +} diff --git a/src/main/java/electrosphere/renderer/meshgen/SkyboxMeshgen.java b/src/main/java/electrosphere/renderer/meshgen/SkyboxMeshgen.java new file mode 100644 index 00000000..7d8269c7 --- /dev/null +++ b/src/main/java/electrosphere/renderer/meshgen/SkyboxMeshgen.java @@ -0,0 +1,245 @@ +package electrosphere.renderer.meshgen; + +/** + * Utilities for generating and managing skyboxes + */ +public class SkyboxMeshgen { + + + // public static Model createSkyboxModel(Material optionalMaterial){ + // Model skyboxModel = new Model(); + // skyboxModel.meshes = new ArrayList(); + + // skyboxModel.modelMatrix = new Matrix4d(); + + + + // // boolean apply_lighting = false; + // // boolean has_bones = false; + + // Mesh skyboxmesh = new Mesh("skybox"){ + // @Override + // public void complexDraw(RenderPipelineState renderPipelineState){ + // if(renderPipelineState.getUseMeshShader()){ + // GL11.glDepthFunc(GL_LEQUAL); + // glUseProgram(shader.getShaderId()); + // } + + // if(renderPipelineState.getUseMaterial()){ + // if(this.getMaterial() == null){ + // Globals.materialDefault.apply_material(0,1); + // Iterator 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.getShaderId(), "colors[" + counter + "]"), temp); + // counter++; + // } + // } + // } + + // glBindVertexArray(vertexArrayObject); + + + + // if(renderPipelineState.getBufferStandardUniforms()){ + // //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); + + // if(renderPipelineState.getUseMeshShader()){ + // GL11.glDepthFunc(GL_LESS); + // } + // } + // }; + + + + // // + // // VAO + // // + // skyboxmesh.generateVAO(); + + + + + + + + + + + // float[] vertexcoords = { + // 100.0f, 100.0f, 100.0f, + // 100.0f, 100.0f,-100.0f, + // 100.0f,-100.0f, 100.0f, + // 100.0f,-100.0f,-100.0f, + // -100.0f, 100.0f, 100.0f, + // -100.0f, 100.0f,-100.0f, + // -100.0f,-100.0f, 100.0f, + // -100.0f,-100.0f,-100.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.setHasBones(false); + + + + + // glBindVertexArray(0); + + + + + + + + + + // skyboxmesh.setParent(skyboxModel); + + + // skyboxModel.meshes.add(skyboxmesh); + + + // return skyboxModel; + // } + +} diff --git a/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java b/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java index 51af068a..f3d87a4c 100644 --- a/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java +++ b/src/main/java/electrosphere/renderer/meshgen/TerrainChunkModelGeneration.java @@ -21,10 +21,10 @@ import static org.lwjgl.opengl.GL30.glGenVertexArrays; import electrosphere.engine.Globals; import electrosphere.entity.types.terrain.TerrainChunkData; -import electrosphere.renderer.Material; -import electrosphere.renderer.Mesh; -import electrosphere.renderer.Model; -import electrosphere.renderer.ShaderProgram; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.server.terrain.manager.ServerTerrainChunk; public class TerrainChunkModelGeneration { @@ -683,16 +683,13 @@ public class TerrainChunkModelGeneration { */ protected static Mesh generateTerrainMesh(TerrainChunkData data){ - Mesh mesh = new Mesh(); + Mesh mesh = new Mesh("terrainChunk"); - mesh.mesh = null; - // // VAO // - mesh.vertexArrayObject = glGenVertexArrays(); - glBindVertexArray(mesh.vertexArrayObject); + mesh.generateVAO(); @@ -704,14 +701,14 @@ public class TerrainChunkModelGeneration { // try { - mesh.vertexCount = data.getVertices().size() / 3; - FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(mesh.vertexCount * 3); + int vertexCount = data.getVertices().size() / 3; + FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(vertexCount * 3); float[] temp = new float[3]; for(float vertValue : data.getVertices()){ VertexArrayBufferData.put(vertValue); } VertexArrayBufferData.flip(); - mesh.buffer_vertices(VertexArrayBufferData, 3); + mesh.bufferVertices(VertexArrayBufferData, 3); } catch (NullPointerException ex){ ex.printStackTrace(); } @@ -721,16 +718,16 @@ public class TerrainChunkModelGeneration { // // FACES // - mesh.faceCount = data.getFaceElements().size() / 3; - mesh.elementCount = data.getFaceElements().size(); + int faceCount = data.getFaceElements().size() / 3; + int elementCount = data.getFaceElements().size(); try { - IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(mesh.elementCount); + IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(elementCount); int[] temp = new int[3]; for(int element : data.getFaceElements()){ elementArrayBufferData.put(element); } elementArrayBufferData.flip(); - mesh.buffer_faces(elementArrayBufferData); + mesh.bufferFaces(elementArrayBufferData,elementCount); } catch (NullPointerException ex){ ex.printStackTrace(); } @@ -742,16 +739,16 @@ public class TerrainChunkModelGeneration { // NORMALS // try { - mesh.normalCount = data.getNormals().size() / 3; + int normalCount = data.getNormals().size() / 3; FloatBuffer NormalArrayBufferData; - if(mesh.normalCount > 0){ - NormalArrayBufferData = BufferUtils.createFloatBuffer(mesh.normalCount * 3); + if(normalCount > 0){ + NormalArrayBufferData = BufferUtils.createFloatBuffer(normalCount * 3); float[] temp = new float[3]; for(float normalValue : data.getNormals()){ NormalArrayBufferData.put(normalValue); } NormalArrayBufferData.flip(); - mesh.buffer_normals(NormalArrayBufferData, 3); + mesh.bufferNormals(NormalArrayBufferData, 3); } } catch (NullPointerException ex){ ex.printStackTrace(); @@ -761,16 +758,16 @@ public class TerrainChunkModelGeneration { // TEXTURE COORDINATES // try { - mesh.textureCoordCount = data.getUVs().size() / 2; + int textureCoordCount = data.getUVs().size() / 2; FloatBuffer TextureArrayBufferData; - if(mesh.textureCoordCount > 0){ - TextureArrayBufferData = BufferUtils.createFloatBuffer(mesh.textureCoordCount * 2); + if(textureCoordCount > 0){ + TextureArrayBufferData = BufferUtils.createFloatBuffer(textureCoordCount * 2); float[] temp = new float[2]; for(float uvValue : data.getUVs()){ TextureArrayBufferData.put(uvValue); } TextureArrayBufferData.flip(); - mesh.buffer_texture_coords(TextureArrayBufferData, 2); + mesh.bufferTextureCoords(TextureArrayBufferData, 2); } } catch (NullPointerException ex){ ex.printStackTrace(); @@ -787,7 +784,6 @@ public class TerrainChunkModelGeneration { glBindVertexArray(0); - mesh.nodeID = "terrainChunk"; return mesh; } @@ -799,7 +795,6 @@ public class TerrainChunkModelGeneration { */ public static Model generateTerrainModel(TerrainChunkData data){ Model rVal = new Model(); - rVal.meshes = new ArrayList(); Mesh m = generateTerrainMesh(data); @@ -810,9 +805,9 @@ public class TerrainChunkModelGeneration { m.setMaterial(groundMat); m.setShader(TerrainChunkModelGeneration.terrainChunkShaderProgram); - m.parent = rVal; + m.setParent(rVal); - rVal.meshes.add(m); + rVal.getMeshes().add(m); rVal.setBoundingSphere(m.getBoundingSphere()); return rVal; diff --git a/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java b/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java index 6da72f6b..1450278b 100644 --- a/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java +++ b/src/main/java/electrosphere/renderer/meshgen/TransvoxelModelGeneration.java @@ -13,11 +13,11 @@ import org.lwjgl.BufferUtils; import electrosphere.engine.Globals; import electrosphere.entity.types.terrain.TerrainChunkData; -import electrosphere.renderer.Material; -import electrosphere.renderer.Mesh; -import electrosphere.renderer.Model; import electrosphere.renderer.meshgen.TerrainChunkModelGeneration.GridCell; import electrosphere.renderer.meshgen.TerrainChunkModelGeneration.Triangle; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.model.Model; /** * Utility functions for generating transvoxel based meshes diff --git a/src/main/java/electrosphere/renderer/Bone.java b/src/main/java/electrosphere/renderer/model/Bone.java similarity index 58% rename from src/main/java/electrosphere/renderer/Bone.java rename to src/main/java/electrosphere/renderer/model/Bone.java index 64ba5650..b4892932 100644 --- a/src/main/java/electrosphere/renderer/Bone.java +++ b/src/main/java/electrosphere/renderer/model/Bone.java @@ -1,22 +1,19 @@ -package electrosphere.renderer; +package electrosphere.renderer.model; -import java.util.ArrayList; import java.util.HashMap; +import java.util.Map; import org.joml.Matrix4d; -import org.joml.Matrix4f; import org.lwjgl.assimp.AIBone; -import electrosphere.renderer.loading.ModelPretransforms; /** - * - * @author satellite + * Keeps track of bone data */ public class Bone { public String boneID; int numWeights; - HashMap weights; + Map weights = new HashMap(); public Matrix4d inverseBindPoseMatrix; public Matrix4d deform; public Matrix4d transform; @@ -33,6 +30,23 @@ public class Bone { final_transform = new Matrix4d(); boneID = raw_data.mName().dataString(); inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrixd(raw_data.mOffsetMatrix()); + numWeights = raw_data.mNumWeights(); this.raw_data = raw_data; } + + /** + * Stores a bone weight + * @param index the index of the bone in the bone array in shader + * @param weight the weight for the given bone + */ + public void putWeight(int index, float weight){ + weights.put(index,weight); + } + + /** + * Returns the weight map + */ + public Map getWeights(){ + return weights; + } } diff --git a/src/main/java/electrosphere/renderer/Material.java b/src/main/java/electrosphere/renderer/model/Material.java similarity index 82% rename from src/main/java/electrosphere/renderer/Material.java rename to src/main/java/electrosphere/renderer/model/Material.java index aed16bb6..c6fc3d6c 100644 --- a/src/main/java/electrosphere/renderer/Material.java +++ b/src/main/java/electrosphere/renderer/model/Material.java @@ -1,6 +1,7 @@ -package electrosphere.renderer; +package electrosphere.renderer.model; import electrosphere.engine.Globals; +import electrosphere.renderer.OpenGLState; import electrosphere.renderer.texture.Texture; import org.lwjgl.assimp.AIMaterial; import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; @@ -68,32 +69,31 @@ public class Material { /** * Applies the material */ - public void apply_material(){ + public void apply_material(OpenGLState openGLState){ //Controls whether the texturePointer should be resolved by looking up the diffuse in asset manager or using the texture pointer already set in this material if(usesFetch){ Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse); if(diffuseTexture != null){ - diffuseTexture.bind(0); - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "material.diffuse"), 0); + diffuseTexture.bind(openGLState,0); + glUniform1i(glGetUniformLocation(Globals.renderingEngine.getOpenGLState().getActiveShader().getShaderId(), "material.diffuse"), 0); } Texture specularTexture = Globals.assetManager.fetchTexture(specular); if(specularTexture != null){ - specularTexture.bind(1); - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "material.specular"), 1); + specularTexture.bind(openGLState,1); + glUniform1i(glGetUniformLocation(Globals.renderingEngine.getOpenGLState().getActiveShader().getShaderId(), "material.specular"), 1); } } else { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texturePointer); + openGLState.glBindTextureUnit(GL_TEXTURE0, texturePointer, GL_TEXTURE_2D); } } - public void apply_material(int diffuse_channel, int specular_channel){ + public void apply_material(OpenGLState openGLState, int diffuse_channel, int specular_channel){ Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse); if(diffuseTexture != null){ - diffuseTexture.bind(diffuse_channel); + diffuseTexture.bind(openGLState,diffuse_channel); } Texture specularTexture = Globals.assetManager.fetchTexture(specular); if(specularTexture != null){ - specularTexture.bind(specular_channel); + specularTexture.bind(openGLState,specular_channel); } } diff --git a/src/main/java/electrosphere/renderer/model/Mesh.java b/src/main/java/electrosphere/renderer/model/Mesh.java new file mode 100644 index 00000000..b599c33b --- /dev/null +++ b/src/main/java/electrosphere/renderer/model/Mesh.java @@ -0,0 +1,543 @@ +package electrosphere.renderer.model; + +import electrosphere.engine.Globals; +import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum; +import electrosphere.renderer.actor.ActorTextureMask; +import electrosphere.renderer.actor.instance.InstanceData; +import electrosphere.renderer.buffer.HomogenousInstancedArray; +import electrosphere.renderer.buffer.ShaderAttribute; +import electrosphere.renderer.light.LightManager; +import electrosphere.renderer.shader.ShaderProgram; +import electrosphere.renderer.texture.Texture; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.joml.Matrix4d; +import org.joml.Matrix4f; +import org.joml.Sphered; +import org.joml.Vector3f; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL15; + +import org.lwjgl.opengl.GL20; +import static org.lwjgl.opengl.GL40.*; + +import org.lwjgl.opengl.GL45; + +/** + * A mesh, a collection of buffer data on the GPU + */ +public class Mesh { + + //the name of the mesh + private String meshName; + + //THIS IS NOT GUARANTEED TO BE THE PARENT MODEL THAT THIS WAS LOADED IN + //THIS CAN BE POST-LOAD SET IN MODEL VIA MODELMASK BEHAVIOR + private Model parent; + + //various buffers that may or may not be allocated + private int vertexBuffer; + private int normalBuffer; + private int elementArrayBuffer; + private int elementCount; + private int vertexArrayObject; + private int boneWeightBuffer; + private int boneIndexBuffer; + private int textureCoordBuffer; + + + + //THIS IS NOT GUARANTEED TO BE THE PARENT MODEL THAT THIS WAS LOADED IN + //THIS CAN BE POST-LOAD SET IN MODEL VIA MODELMASK BEHAVIOR + private List bones = new ArrayList(); + private ArrayList boneIdList = new ArrayList(); + + //the texture mask that may or may not be masking the mesh + private ActorTextureMask textureMask; + + //the shaders currently associated with the mesh + private ShaderProgram shader; + private ShaderProgram oitShader; + + //the uniforms to be sent to the gpu + private HashMap uniforms = new HashMap(); + + //the material currently associated with the mesh + private Material material; + + //the bounding sphere for this mesh + private Sphered boundingSphere; + + /** + * Creates a mesh (does not initialize any data) + * @param name The name of the mesh + */ + public Mesh(String name){ + this.meshName = name; + this.boundingSphere = new Sphered(); + } + + /** + * Generates the VAO for this mesh + */ + public void generateVAO(){ + vertexArrayObject = glGenVertexArrays(); + glBindVertexArray(vertexArrayObject); + } + + /** + * Buffers vertex data to the gpu under this mesh container + * @param verticies the vertex buffer + * @param vertexDimension the dimensionality of the data (2d vectors, 3d vectors, 4d vectors, etc) + */ + public void bufferVertices(FloatBuffer verticies, int vertexDimension){ + if(!Globals.HEADLESS){ + vertexBuffer = bufferCustomFloatAttribArray(verticies,vertexDimension,0); + } + } + + /** + * Buffers normals to the gpu under this mesh container + * @param normals the normal data + * @param normalDimension the dimensionality of the data (2d vector, 3d vector, 4d vector) + */ + public void bufferNormals(FloatBuffer normals, int normalDimension){ + if(!Globals.HEADLESS){ + normalBuffer = bufferCustomFloatAttribArray(normals,normalDimension,1); + } + } + + /** + * Buffers faces to the GPU + * @param faces The face data + * @param elementCount The number of faces + */ + public void bufferFaces(IntBuffer faces, int elementCount){ + if(!Globals.HEADLESS){ + elementArrayBuffer = glGenBuffers(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer); + GL15.glBufferData(GL_ELEMENT_ARRAY_BUFFER, faces, GL_STATIC_DRAW); + this.elementCount = elementCount; + } + } + + /** + * Buffers texture coordinates to the gpu + * @param coords the texture coordinates data + * @param textureDimension The dimensionality of the texture coordinate data (3d vec, 4d vec, etc) + */ + public void bufferTextureCoords(FloatBuffer coords, int textureDimension){ + if(!Globals.HEADLESS){ + textureCoordBuffer = bufferCustomFloatAttribArray(coords, textureDimension, 4); + } + } + + /** + * Buffers bone indices to the GPU + * @param buffer The buffer containing the bone indices + */ + public void bufferBoneIndices(FloatBuffer buffer){ + boneIndexBuffer = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, boneIndexBuffer); + GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW); + glVertexAttribPointer(3, 4, GL_FLOAT, false, 0, 0); + glEnableVertexAttribArray(3); + } + + /** + * Buffers bone weights to the gpu + * @param buffer The buffer containing the bone weights + */ + public void bufferBoneWeights(FloatBuffer buffer){ + boneWeightBuffer = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, boneWeightBuffer); + GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW); + glVertexAttribPointer(2, 4, GL_FLOAT, false, 0, 0); + glEnableVertexAttribArray(2); + } + + /** + * Sends a float buffer to the gpu + * @param buffer The buffer + * @param bufferDimension The dimensionality of the buffer (2d vector, 3d vector, 4d vector) + * @param attribIndex The attribute index of the buffer (ie what number will it show up as in the shader) + * @return The pointer to the opengl buffer created + */ + public int bufferCustomFloatAttribArray(FloatBuffer buffer, int bufferDimension, int attribIndex){ + int bufferPointer = 0; + if(!Globals.HEADLESS){ + bufferPointer = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, bufferPointer); + GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW); + glVertexAttribPointer(attribIndex, bufferDimension, GL_FLOAT, false, 0, 0); + glEnableVertexAttribArray(attribIndex); + } + return bufferPointer; + } + + /** + * Sends an int buffer to the gpu + * @param buffer The buffer + * @param bufferDimension The dimensionality of the buffer (2d vector, 3d vector, 4d vector) + * @param attribIndex The attribute index of the buffer (ie what number will it show up as in the shader) + * @return The pointer to the opengl buffer created + */ + public int bufferCustomIntAttribArray(IntBuffer buffer, int bufferDimension, int attribIndex){ + int bufferPointer = 0; + if(!Globals.HEADLESS){ + bufferPointer = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, bufferPointer); + GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW); + glVertexAttribPointer(attribIndex, bufferDimension, GL_INT, false, 0, 0); + glEnableVertexAttribArray(attribIndex); + } + return bufferPointer; + } + + + /** + * Sends an unsigned int buffer to the gpu + * @param buffer The buffer + * @param bufferDimension The dimensionality of the buffer (2d vector, 3d vector, 4d vector) + * @param attribIndex The attribute index of the buffer (ie what number will it show up as in the shader) + * @return The pointer to the opengl buffer created + */ + public int bufferCustomUIntAttribArray(IntBuffer buffer, int bufferDimension, int attribIndex){ + int bufferPointer = 0; + if(!Globals.HEADLESS){ + bufferPointer = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, bufferPointer); + GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW); + glVertexAttribPointer(attribIndex, bufferDimension, GL_UNSIGNED_INT, false, 0, 0); + glEnableVertexAttribArray(attribIndex); + } + return bufferPointer; + } + + /** + * Sets the texture mask for the mesh + * @param textureMask the texture mask + */ + public void setTextureMask(ActorTextureMask textureMask){ + this.textureMask = textureMask; + } + + /** + * Sets the material for the mesh + * @param material the material + */ + public void setMaterial(Material material){ + this.material = material; + } + + /** + * Sets the shader of this mesh + * @param shader The shader + */ + public void setShader(ShaderProgram shader){ + this.shader = shader; + } + + /** + * Gets the shader of this mesh + * @return The shader + */ + public ShaderProgram getShader(){ + return shader; + } + + /** + * Sets the order independent transparency shader + * @param shader The shader + */ + public void setOITShader(ShaderProgram shader){ + this.oitShader = shader; + } + + + /** + * Sets a uniform on the mesh + * @param key the uniform key + * @param o the value to set the uniform to + */ + public void setUniform(String key, Object o){ + uniforms.put(key, o); + } + + void bufferAllUniforms(OpenGLState openGLState){ + for(String key : uniforms.keySet()){ + Object currentUniformRaw = uniforms.get(key); + if(currentUniformRaw instanceof Matrix4f){ + Matrix4f currentUniform = (Matrix4f)currentUniformRaw; + glUniformMatrix4fv(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), key), false, currentUniform.get(new float[16])); + } + if(currentUniformRaw instanceof Vector3f){ + Vector3f currentUniform = (Vector3f)currentUniformRaw; + glUniform3fv(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), key), currentUniform.get(BufferUtils.createFloatBuffer(3))); + } + if(currentUniformRaw instanceof Integer){ + int currentInform = (Integer)currentUniformRaw; + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), key), currentInform); + } + } + } + + /** + * Sends a buffer to the gpu + * @param uniformTypeMap The type of the buffer + * @param buffers The buffer + */ + void bufferInstanceData( + RenderPipelineState renderPipelineState, + Map buffers, + Map uniformGlBufferMap + ){ + for(ShaderAttribute attribute : buffers.keySet()){ + HomogenousInstancedArray buffer = uniformGlBufferMap.get(attribute); + buffer.updateBuffer(buffers.get(attribute), 0); + buffer.bind(renderPipelineState); + } + } + + + /** + * Draws the mesh + * @param renderPipelineState The state of the render pipeline + */ + public void complexDraw(RenderPipelineState renderPipelineState, OpenGLState openGLState){ + + if(renderPipelineState.getUseMeshShader()){ + ShaderProgram selectedProgram = null; + switch(renderPipelineState.getSelectedShader()){ + case PRIMARY: { + selectedProgram = shader; + } break; + case OIT: { + selectedProgram = oitShader; + } break; + } + if(selectedProgram == null){ + selectedProgram = shader; + } + openGLState.setActiveShader(renderPipelineState, selectedProgram); + } + + if(renderPipelineState.getUseLight()){ + //Until we switch to uniform buffer objects we will have to buffer lighting data here manually each time we draw + //side note: :( + if(Globals.renderingEngine.getLightManager() == null){ + //don't buffer as the light manager hasn't initialized + } else { + LightManager lightManager = Globals.renderingEngine.getLightManager(); + lightManager.bindBuffer(openGLState.getActiveShader().getShaderId()); + } + } + + if(renderPipelineState.getUseMaterial() && textureMask == null){ + if(material == null){ + Globals.materialDefault.apply_material(openGLState,0,1); + GL20.glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasTransparency"), 0); + } else { + material.apply_material(openGLState); + if(material.hasTransparency){ + GL20.glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasTransparency"), 1); + } else { + GL20.glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasTransparency"), 0); + } + } + } + + + + + + glBindVertexArray(vertexArrayObject); + + + + if(textureMask != null){ + int i = 0; +// glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures"), 5); +// for(int j = 1; j < 15; j++){ +// textureList.get(0).bind(j); +// } + for(Texture texture : textureMask.getTextures()){ +// System.out.println(texture.getPath() + " => groundTextures[" + i + "]" + "=>" + (i)); + if(texture != null){ + texture.bind(openGLState,5+i); + } + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), textureMask.getUniformNames().get(i)),5+i); + i++; + } + // for(int j = i; j < 10; j++){ + // glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures[" + j + "]"),6+j); + // } +// glActiveTexture(GL_TEXTURE0); + } + + if(renderPipelineState.getUseShadowMap()){ + openGLState.glActiveTexture(GL_TEXTURE3); + openGLState.glBindTexture(GL_TEXTURE_2D, Globals.shadowMapTextureLoc); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "shadowMap"), 3); + } + + + if(renderPipelineState.getUseBones()){ + // + //Handle bones + // + if(bones != null && !bones.isEmpty()){ + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasBones"), 1); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "numBones"), bones.size()); + Iterator boneIterator = boneIdList.iterator(); + // float bufferarray[] = new float[16]; + int incrementer = 0; + while (boneIterator.hasNext()){ + String boneName = boneIterator.next(); + Bone currentBone = parent.getBoneMap().get(boneName); + String currentUniform = "bones[" + incrementer + "]"; + if(currentBone != null){ + Matrix4d currentMat = new Matrix4d(currentBone.final_transform); + // currentMat.get(bufferarray); + // if(boneName.equals("Torso")){ + // System.out.println("Found torso bone"); + // System.out.println(currentUniform); + // System.out.println(currentMat); + // } + openGLState.getActiveShader().setUniform(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), currentUniform), currentMat); + // GL45.glUniformMatrix4fv(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), currentUniform), false, bufferarray); + } else { + // System.out.println("Bonename: " + boneName); + // System.exit(1); + GL45.glUniformMatrix4fv(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), currentUniform), false, new float[16]); + } + incrementer++; + } + } else { + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasBones"), 0); + } + } else { + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasBones"), 0); + } + + + if(renderPipelineState.getBufferStandardUniforms()){ + //buffer model/view/proj matrices + GL45.glUniformMatrix4fv(openGLState.getActiveShader().shaderVertexModelLoc, false, parent.getModelMatrix().get(new float[16])); + glUniformMatrix4fv(openGLState.getActiveShader().shaderVertexViewLoc, false, Globals.viewMatrix.get(new float[16])); + glUniformMatrix4fv(openGLState.getActiveShader().shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16])); + glUniform3fv(openGLState.getActiveShader().shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3))); + glUniformMatrix4fv(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16])); + glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "frame"), (int)Globals.timekeeper.getNumberOfRenderFramesElapsed()); + glUniform1f(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "time"), (float)Globals.timekeeper.getCurrentRendererTime()); + } + + if(renderPipelineState.getBufferNonStandardUniforms()){ + bufferAllUniforms(openGLState); + } + + if(renderPipelineState.getInstanced()){ + InstanceData instanceData = renderPipelineState.getInstanceData(); + Map buffers = instanceData.getCpuBufferMap(); + Map glBufferMap = instanceData.getGlBufferMap(); + bufferInstanceData(renderPipelineState, buffers, glBufferMap); + } + + + if(renderPipelineState.getInstanced()){ + GL45.glDrawElementsInstanced(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0, renderPipelineState.getInstanceData().getDrawCount()); + } else { + GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0); + } + glBindVertexArray(0); + } + + /** + * Updates the bounding sphere of the mesh + * @param x + * @param y + * @param z + * @param r + */ + public void updateBoundingSphere(float x, float y, float z, float r){ + this.boundingSphere.x = x; + this.boundingSphere.y = y; + this.boundingSphere.z = z; + this.boundingSphere.r = r; + } + + /** + * Gets the bounding sphere of this mesh + * @return The bounding sphere + */ + public Sphered getBoundingSphere(){ + return this.boundingSphere; + } + + /** + * Gets the material of the mesh + * @return The material + */ + public Material getMaterial(){ + return material; + } + + /** + * Gets whether this mesh has bones or not + * @return true if has bones + */ + public boolean hasBones(){ + return bones.size() > 0; + } + + /** + * Gets the name of this mesh + * @return The name of the mesh + */ + public String getMeshName(){ + return meshName; + } + + /** + * Sets the parent model of this mesh + * @param parent The parent + */ + public void setParent(Model parent){ + this.parent = parent; + } + + /** + * Gets the bones for this mesh + * @return The list of bones + */ + public List getBones(){ + return bones; + } + + /** + * Sets the bones for this mesh + * @param bones The list of bones + */ + public void setBones(List bones){ + this.bones = bones; + } + + /** + * Registers a bone id + * @param boneId the bone id + */ + public void registerBoneId(String boneId){ + this.boneIdList.add(boneId); + } + +} diff --git a/src/main/java/electrosphere/renderer/Model.java b/src/main/java/electrosphere/renderer/model/Model.java similarity index 53% rename from src/main/java/electrosphere/renderer/Model.java rename to src/main/java/electrosphere/renderer/model/Model.java index f3afcd98..b2cf671a 100644 --- a/src/main/java/electrosphere/renderer/Model.java +++ b/src/main/java/electrosphere/renderer/model/Model.java @@ -1,6 +1,7 @@ -package electrosphere.renderer; +package electrosphere.renderer.model; -import electrosphere.renderer.actor.ActorAnimationMask; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.actor.ActorBoneRotator; import electrosphere.renderer.actor.ActorMeshMask; import electrosphere.renderer.actor.ActorShaderMask; @@ -9,41 +10,24 @@ import electrosphere.renderer.actor.ActorTextureMask; import electrosphere.renderer.anim.AnimChannel; import electrosphere.renderer.anim.Animation; import electrosphere.renderer.loading.ModelPretransforms; -import electrosphere.renderer.loading.ModelPretransforms.MeshMetadata; +import electrosphere.renderer.meshgen.MeshLoader; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.anim.AnimNode; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; -import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.ListIterator; import org.joml.Matrix4d; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.lwjgl.BufferUtils; import org.lwjgl.PointerBuffer; import org.lwjgl.assimp.AIMaterial; import org.lwjgl.assimp.AIMesh; import org.lwjgl.assimp.AIScene; -import static org.lwjgl.assimp.Assimp.*; -import static org.lwjgl.opengl.ARBVertexBufferObject.*; -import static org.lwjgl.opengl.ARBVertexProgram.*; -import org.lwjgl.opengl.GL11; -import static org.lwjgl.opengl.GL11.*; -import static org.lwjgl.opengl.GL13.*; -import static org.lwjgl.opengl.GL15.*; -import static org.lwjgl.opengl.GL20.*; -import static org.lwjgl.opengl.GL30.*; -import electrosphere.renderer.texture.TextureMap; -import java.nio.FloatBuffer; +import org.lwjgl.assimp.Assimp; import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedList; import java.util.Map; -import java.util.Stack; -import org.joml.Quaternionf; import org.joml.Sphered; import org.joml.Vector3d; import org.lwjgl.assimp.AIAnimation; @@ -51,31 +35,54 @@ import org.lwjgl.assimp.AIBone; import org.lwjgl.assimp.AINode; /** - * - * @author satellite + * A model + * Contains a list of meshes to draw + * Contains animations to apply to those meshes */ public class Model { - boolean is_Ready_To_Display = false; - AIScene scene; - public List meshes; - public ArrayList animations; - public ArrayList bones; - public HashMap boneMap; - HashMap animMap; - public HashMap node_map; - public ArrayList materials; - public Matrix4d modelMatrix = new Matrix4d(); - ShaderProgram program; - Matrix4d globalInverseTransform; + + //the model matrix for this model + private Matrix4d modelMatrix = new Matrix4d(); + + //an optional global transform applied to the parent bone. Typically found in models loaded from files + private Matrix4d globalInverseTransform = new Matrix4d(); + + //the meshes in the model + private List meshes = new ArrayList(); + + //the materials in the model + private List materials = new ArrayList(); + + //bone data for the model + private List bones = new ArrayList(); + private Map boneMap = new HashMap(); - AnimNode root_anim_node; - ActorMeshMask meshMask; - Map shaderMask = new HashMap(); - Map textureMap = null; + //these structures are used to parse the tree of bones of the model + private AnimNode rootAnimNode; + private Map nodeMap = new HashMap(); + + //animation data for the model + private List animations = new ArrayList(); + private Map animMap = new HashMap(); + + + //these are masks that can be applied to the model to overwrite meshes, shaders, and textures of it + private ActorMeshMask meshMask; + private Map shaderMask = new HashMap(); + private Map textureMap = new HashMap(); //The bounding sphere for this particular model - Sphered boundingSphere; + private Sphered boundingSphere = new Sphered(); + + + + /** + * Constructor + */ + public Model(){ + } + /** * Loads a model from an ai scene object * @param path The path of the model @@ -84,10 +91,6 @@ public class Model { */ public static Model createModelFromAiscene(String path, AIScene s){ Model rVal = new Model(); - // - //set the scene - // - rVal.scene = s; ModelPretransforms.ModelMetadata modelMetadata = Globals.modelPretransforms.getModel(path); ModelPretransforms.GlobalTransform globalTransform = null; @@ -107,12 +110,12 @@ public class Model { if(modelMetadata != null){ meshMetadata = modelMetadata.getMesh(aiMesh.mName().dataString()); } - Mesh currentMesh = Mesh.create_mesh_from_aimesh(aiMesh, meshMetadata); + Mesh currentMesh = MeshLoader.createMeshFromAIScene(aiMesh, meshMetadata); rVal.meshes.add(currentMesh); - currentMesh.parent = rVal; + currentMesh.setParent(rVal); //update model bounding sphere - if(currentMesh.boundingSphere.r > rVal.boundingSphere.r){ - rVal.boundingSphere.r = currentMesh.boundingSphere.r; + if(currentMesh.getBoundingSphere().r > rVal.boundingSphere.r){ + rVal.boundingSphere.r = currentMesh.getBoundingSphere().r; } } // @@ -138,10 +141,10 @@ public class Model { Iterator meshIterator = rVal.meshes.iterator(); rVal.bones = new ArrayList(); rVal.boneMap = new HashMap(); - rVal.node_map = new HashMap(); + rVal.nodeMap = new HashMap(); while(meshIterator.hasNext()){ Mesh currentMesh = meshIterator.next(); - Iterator boneIterator = currentMesh.bones.iterator(); + Iterator boneIterator = currentMesh.getBones().iterator(); ArrayList to_remove_queue = new ArrayList(); ArrayList to_add_queue = new ArrayList(); while(boneIterator.hasNext()){ @@ -153,11 +156,11 @@ public class Model { } boneIterator = to_remove_queue.iterator(); while(boneIterator.hasNext()){ - currentMesh.bones.remove(boneIterator.next()); + currentMesh.getBones().remove(boneIterator.next()); } boneIterator = to_add_queue.iterator(); while(boneIterator.hasNext()){ - currentMesh.bones.add(boneIterator.next()); + currentMesh.getBones().add(boneIterator.next()); } } // @@ -168,9 +171,9 @@ public class Model { if(globalTransform != null){ rVal.globalInverseTransform.scale(globalTransform.getScale()); } -// System.out.println("Global inverse transform"); -// System.out.println(globalInverseTransform); - rVal.root_anim_node = rVal.build_anim_node_map(s.mRootNode(),null); + LoggerInterface.loggerRenderer.DEBUG("Global Inverse Transform"); + LoggerInterface.loggerRenderer.DEBUG(rVal.globalInverseTransform + ""); + rVal.rootAnimNode = rVal.buildAnimNodeMap(s.mRootNode(),null); // //load animations // @@ -198,116 +201,70 @@ public class Model { return rVal; } - - - public Model(){ - /* - public boolean is_Ready_To_Display = false; - public AIScene scene; - public ArrayList meshes; - public ArrayList animations; - public ArrayList bones; - public HashMap boneMap; - public HashMap node_map = new HashMap(); - public ArrayList materials; - public Matrix4f modelMatrix = new Matrix4f().translation(new Vector3f(0,0,0)); - ShaderProgram program; - public Animation currentAnimation; - public Matrix4f globalInverseTransform; - */ - scene = null; - meshes = null; - animations = null; - bones = null; - boneMap = null; - node_map = null; - materials = null; - modelMatrix = new Matrix4d(); - program = null; - globalInverseTransform = null; - this.boundingSphere = new Sphered(); - } - - public void free() { - aiReleaseImport(scene); - scene = null; - meshes = null; - } - - public void draw(RenderPipelineState renderPipelineState){ - // if(node_map != null && !node_map.isEmpty()){ - // update_node_transform(root_anim_node); - // } + /** + * Draws the model + * @param renderPipelineState the render pipeline state + */ + public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState){ Iterator mesh_Iterator = meshes.iterator(); while(mesh_Iterator.hasNext()){ Mesh currentMesh = mesh_Iterator.next(); - if(meshMask == null || (meshMask != null && !meshMask.isBlockedMesh(currentMesh.nodeID))){ + if(meshMask == null || (meshMask != null && !meshMask.isBlockedMesh(currentMesh.getMeshName()))){ //set shader - ShaderProgram original = currentMesh.shader; - ShaderProgram shader = getCorrectShader(shaderMask, currentMesh, currentMesh.shader); - currentMesh.shader = shader; + ShaderProgram original = currentMesh.getShader(); + ShaderProgram shader = getCorrectShader(shaderMask, currentMesh, currentMesh.getShader()); + currentMesh.setShader(shader); //set texture mask - if(this.textureMap != null && textureMap.containsKey(currentMesh.nodeID)){ - currentMesh.setTextureMask(textureMap.get(currentMesh.nodeID)); + if(this.textureMap != null && textureMap.containsKey(currentMesh.getMeshName())){ + currentMesh.setTextureMask(textureMap.get(currentMesh.getMeshName())); } //draw - currentMesh.complexDraw(renderPipelineState); + currentMesh.complexDraw(renderPipelineState, openGLState); //reset texture mask currentMesh.setTextureMask(null); //reset shader - currentMesh.shader = original; + currentMesh.setShader(original); } } if(meshMask != null){ for(Mesh toDraw : meshMask.getToDrawMeshes()){ - toDraw.bones = bones; - toDraw.parent = this; - ShaderProgram original = toDraw.shader; - ShaderProgram shader = getCorrectShader(shaderMask, toDraw, toDraw.shader); - toDraw.shader = shader; - toDraw.complexDraw(renderPipelineState); - toDraw.shader = original; + toDraw.setBones(bones); + toDraw.setParent(this); + ShaderProgram original = toDraw.getShader(); + ShaderProgram shader = getCorrectShader(shaderMask, toDraw, toDraw.getShader()); + toDraw.setShader(shader); + toDraw.complexDraw(renderPipelineState, openGLState); + toDraw.setShader(original); } } } + /** + * Determines the correct shader to use for a given mesh + * @param shaderMask The shader mask + * @param mesh The mesh + * @param oldShader The original shader on the mesh + * @return The correct shader program to use for this mesh + */ ShaderProgram getCorrectShader(Map shaderMask, Mesh mesh, ShaderProgram oldShader){ ShaderProgram rVal = oldShader; - if(shaderMask.containsKey(mesh.nodeID)){ - ActorShaderMask specificMask = shaderMask.get(mesh.nodeID); + if(shaderMask.containsKey(mesh.getMeshName())){ + ActorShaderMask specificMask = shaderMask.get(mesh.getMeshName()); ShaderProgram overwriteShader = null; if((overwriteShader = Globals.assetManager.fetchShader(specificMask.getVertexShaderPath(), specificMask.getGeometryShaderPath(), specificMask.getFragmentShaderPath())) != null){ - // ShaderProgram oldProgram = mesh.shader; rVal = overwriteShader; } } return rVal; } - -// public void playAnimation(String s){ -// this.currentAnimation = null; -// Iterator animationIterator = animations.iterator(); -// while(animationIterator.hasNext()){ -// Animation current_iterator_item = animationIterator.next(); -// if(current_iterator_item.name.equals(s)){ -// this.currentAnimation = current_iterator_item; -// } -// } -// if(currentAnimation != null){ -// // if(s.contains("Walk")){ -// // currentAnimation.describeAnimation(); -// //// currentAnimation.fullDescribeAnimation(); -// // } -// currentAnimation.timeCurrent = 0; -// Iterator channelIterator = currentAnimation.channels.iterator(); -// while(channelIterator.hasNext()){ -// AnimChannel currentChannel = channelIterator.next(); -// currentChannel.rewind(); -// } -// } -// } + /** + * Applies an animation mask to the model + * @param animationName The name of the animation + * @param time The temporal location in the animation to mask + * @param mask The mask + */ public void applyAnimationMask(String animationName, double time, List mask){ Animation animationCurrent = animMap.get(animationName); if(animationCurrent != null){ @@ -328,53 +285,13 @@ public class Model { } } - // public void incrementTime(double time){ - // if(currentAnimation != null){ - // boolean isDone = currentAnimation.incrementTime(time); - // if(isDone){ - // currentAnimation.timeCurrent = 0; - // Iterator channelIterator = currentAnimation.channels.iterator(); - // while(channelIterator.hasNext()){ - // AnimChannel currentChannel = channelIterator.next(); - // currentChannel.rewind(); - // } - // Iterator boneIterator = bones.iterator(); - // while(boneIterator.hasNext()){ - // Bone currentBone = boneIterator.next(); - // currentBone.transform = new Matrix4f(); - // } - // currentAnimation = null; - // } else { - // //First we push transformFromParent into deform so that later in the pipeline bones without a current animation take on transformFromParent as their transformation to the hierarchy - // //I BELIEVE this is so that control bones still apply their offset to the hierarchy even when they're not animated :tm: - // //4/5/20 - // // Iterator boneIterator = bones.iterator(); - // // while(boneIterator.hasNext()){ - // // Bone currentBone = boneIterator.next(); - // //// currentBone.deform = currentBone.transformFromParent; - // // } - // //Once that's done, for every channel we set the corresponding bone's deform to the channels TRS - // Iterator channelIterator = currentAnimation.channels.iterator(); - // while(channelIterator.hasNext()){ - // AnimChannel currentChannel = channelIterator.next(); - // currentChannel.incrementTime(time); - // Bone currentBone = boneMap.get(currentChannel.getNodeID()); - // if(currentBone != null){ - // //T * S * R - // currentBone.deform = new Matrix4f(); - // currentBone.deform.translate(currentChannel.getCurrentPosition()); - // currentBone.deform.rotate(currentChannel.getCurrentRotation()); - // currentBone.deform.scale(currentChannel.getCurrentScale()); - // } - // } - // } - // } - // } - + /** + * Logs all animations for a given model + */ public void describeAllAnimations(){ if(animations.size() > 0){ - System.out.println("====================="); - System.out.println(animations.size() + " animations available in model!"); + LoggerInterface.loggerRenderer.DEBUG("====================="); + LoggerInterface.loggerRenderer.DEBUG(animations.size() + " animations available in model!"); Iterator animIterator = animations.iterator(); while(animIterator.hasNext()){ Animation currentAnim = animIterator.next(); @@ -383,50 +300,50 @@ public class Model { } } - public final AnimNode build_anim_node_map(AINode node, AnimNode parent){ + /** + * Recursively builds the bone tree + * @param node The current assimp bone to operate on + * @param parent The parent bone + * @return The current bone + */ + public final AnimNode buildAnimNodeMap(AINode node, AnimNode parent){ AnimNode node_object = new AnimNode(node.mName().dataString(), parent, node); - node_map.put(node_object.id, node_object); + nodeMap.put(node_object.id, node_object); if(boneMap.containsKey(node_object.id)){ node_object.is_bone = true; } int num_children = node.mNumChildren(); for(int i = 0; i < num_children; i++){ - AnimNode temp_child = build_anim_node_map(AINode.create(node.mChildren().get(i)),node_object); -// if(boneMap.containsKey(node_object.id)){ -// Bone parent_bone = boneMap.get(node_object.id); -// node_object.children.add(temp_child); -// if(boneMap.containsKey(temp_child.id)){ -// Bone child_bone = boneMap.get(temp_child.id); -// parent_bone.children.add(child_bone); -// child_bone.parent = parent_bone; -// } -// } + AnimNode temp_child = buildAnimNodeMap(AINode.create(node.mChildren().get(i)),node_object); node_object.children.add(temp_child); } return node_object; } + /** + * Updates the position of all bones to their correct locations given bone rotators, static morph, and current animation + * @param boneRotators The bone rotators to apply + * @param staticMorph The static morph to apply + */ public void updateNodeTransform(Map boneRotators, ActorStaticMorph staticMorph){ - if(this.root_anim_node != null){ - update_node_transform(this.root_anim_node,boneRotators,staticMorph); + if(this.rootAnimNode != null){ + updateNodeTransform(this.rootAnimNode,boneRotators,staticMorph); } } - void update_node_transform(AnimNode n, Map boneRotators, ActorStaticMorph staticMorph){ + /** + * Recursively updates the position of all bones to their correct locations given bone rotators, static morph, and current animation + * @param n the current node to operate on + * @param boneRotators The bone rotators to apply + * @param staticMorph The static morph to apply + */ + void updateNodeTransform(AnimNode n, Map boneRotators, ActorStaticMorph staticMorph){ if(n.parent != null){ n.transform = new Matrix4d(n.parent.transform); } else { n.transform = new Matrix4d(); } if(n.is_bone){ - /* - Bone bone = boneList.get(j); - Node node = rootNode.findByName(bone.getBoneName()); - Matrix4f boneMatrix = Node.getParentTransforms(node, i); - boneMatrix.mul(bone.getOffsetMatrix()); - boneMatrix = new Matrix4f(rootTransformation).mul(boneMatrix); - frame.setMatrix(j, boneMatrix); - */ // //bone rotators (turrets, hair, etc) Bone target_bone = boneMap.get(n.id); @@ -446,97 +363,170 @@ public class Model { bone_matrix.mul(target_bone.inverseBindPoseMatrix); bone_matrix = new Matrix4d(globalInverseTransform).mul(bone_matrix); target_bone.final_transform = bone_matrix; -// if(!toggled){ -// System.out.println(n.id); -// System.out.println("Transform:"); -// System.out.println(n.parent.transform); -// System.out.println(target_bone.deform); -// System.out.println(n.transform); -// System.out.println("Final transform:"); -// System.out.println(globalInverseTransform); -// System.out.println(n.transform); -// System.out.println(target_bone.inverseBindPoseMatrix); -// System.out.println(target_bone.final_transform); -// System.out.println("\n\n\n\n"); -// } } else { n.transform = n.transform.mul(electrosphere.util.Utilities.convertAIMatrix(n.raw_data.mTransformation())); } Iterator node_iterator = n.children.iterator(); while(node_iterator.hasNext()){ AnimNode current_node = node_iterator.next(); - update_node_transform(current_node,boneRotators,staticMorph); + updateNodeTransform(current_node,boneRotators,staticMorph); } } - + + /** + * Draws a ui model + */ public void drawUI(){ for(Mesh m : meshes){ - m.complexDraw(Globals.renderingEngine.getRenderPipelineState()); + m.complexDraw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState()); } } + + /** + * Pushes a uniform to a given mesh + * @param meshName The name of the mesh + * @param uniformKey The uniform key + * @param uniform The value of the uniform + */ public void pushUniformToMesh(String meshName, String uniformKey, Object uniform){ for(Mesh m : meshes){ - if(m.nodeID.equals(meshName)){ + if(m.getMeshName().equals(meshName)){ m.setUniform(uniformKey, uniform); } } } + /** + * Logs all bone IDs (names) + */ public void listAllBoneIDs(){ for(String id : boneMap.keySet()){ - System.out.println(id); + LoggerInterface.loggerRenderer.DEBUG(id); } } + /** + * Gets a given mesh by its name + * @param meshName the name of the mesh + * @return The mesh if it exists, or null + */ public Mesh getMesh(String meshName){ for(Mesh mesh : meshes){ - if(mesh.nodeID.matches(meshName)){ + if(mesh.getMeshName().matches(meshName)){ return mesh; } } return null; } + /** + * Gets an animation by its name + * @param animName The name of the animation + * @return the animation if it exists, or null + */ public Animation getAnimation(String animName){ return animMap.get(animName); } - - public Map getShaderMask(){ - return shaderMask; - } + /** + * Describes the model at a high level + */ public void describeHighLevel(){ - System.out.println("Meshes: "); + LoggerInterface.loggerRenderer.DEBUG("Meshes: "); for(Mesh mesh : meshes){ - System.out.println(mesh.nodeID); + LoggerInterface.loggerRenderer.DEBUG(mesh.getMeshName()); } - System.out.println("Animations: "); + LoggerInterface.loggerRenderer.DEBUG("Animations: "); for(Animation anim : animations){ - System.out.println(anim.name); + LoggerInterface.loggerRenderer.DEBUG(anim.name); } - System.out.println("Bones:"); + LoggerInterface.loggerRenderer.DEBUG("Bones:"); for(Bone bone : bones){ - System.out.println(bone.boneID); + LoggerInterface.loggerRenderer.DEBUG(bone.boneID); } } + + + // + // Pure getters and setters + // + + + /** + * Gets the meshes in this model + * @return the list of meshes + */ + public List getMeshes(){ + return meshes; + } + + /** + * Sets the model matrix for this model + * @param modelMatrix the model matrix + */ + public void setModelMatrix(Matrix4d modelMatrix){ + this.modelMatrix = modelMatrix; + } + + /** + * Gets the model matrix for this model + * @return the model matrix + */ + public Matrix4d getModelMatrix(){ + return modelMatrix; + } + + /** + * Gets the list of bones + * @return the list of bones + */ + public List getBones(){ + return bones; + } + + /** + * Gets the map of bone name -> bone + * @return the map + */ + public Map getBoneMap(){ + return boneMap; + } + + /** + * Gets the list of materials in this model + * @return The list of materials + */ + public List getMaterials(){ + return materials; + } + + /** + * Sets the mesh mask + * @param meshMask the mesh mask to set + */ public void setMeshMask(ActorMeshMask meshMask){ this.meshMask = meshMask; } + /** + * Sets the texture mask + * @param textureMask the texture mask + */ public void setTextureMask(Map textureMask){ this.textureMap = textureMask; } /** - * Sets the shader program to use drawing the modal - * @param program The shader program + * Gets the shader mask map + * @return The shader mask map */ - public void setProgram(ShaderProgram program){ - this.program = program; + public Map getShaderMask(){ + return shaderMask; } + /** * Utility method to attempt overwriting the model's meshes with a new material * @param material The material diff --git a/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java b/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java new file mode 100644 index 00000000..33ae9423 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java @@ -0,0 +1,69 @@ +package electrosphere.renderer.pipelines; + +import org.lwjgl.opengl.GL40; + +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; + +public class CompositePipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + // + //Setup to render screen textures & bind screen framebuffer + // + openGLState.glDepthFunc(GL40.GL_ALWAYS); + // glDepthMask(false); + GL40.glEnable(GL40.GL_BLEND); + GL40.glBlendFunc(GL40.GL_SRC_ALPHA, GL40.GL_ONE_MINUS_SRC_ALPHA); + + RenderingEngine.screenFramebuffer.bind(); + + GL40.glBindVertexArray(RenderingEngine.screenTextureVAO); + + + // + //Draw anime outline + // + openGLState.setActiveShader(renderPipelineState, RenderingEngine.compositeAnimeOutline); + + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE1); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE2); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE3); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.normalsOutlineTexture.getTexturePointer()); + + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + + // + //Composite transparency on top of solids + // + openGLState.setActiveShader(renderPipelineState, RenderingEngine.oitCompositeProgram); + + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE1); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE2); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE3); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyAccumulatorTexture.getTexturePointer()); + openGLState.glActiveTexture(GL40.GL_TEXTURE1); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyRevealageTexture.getTexturePointer()); + + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + GL40.glBindVertexArray(0); + + + + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java new file mode 100644 index 00000000..9483e291 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java @@ -0,0 +1,207 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Matrix4d; +import org.joml.Quaterniond; +import org.joml.Quaternionf; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +import electrosphere.collision.collidable.Collidable; +import electrosphere.engine.Globals; +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.collidable.CollidableTemplate; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.model.Model; +import electrosphere.server.pathfinding.navmesh.NavCube; +import electrosphere.server.pathfinding.navmesh.NavMesh; +import electrosphere.server.pathfinding.navmesh.NavShape; + +public class DebugContentPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + //bind screen fbo + RenderingEngine.screenFramebuffer.bind(); + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + openGLState.glViewport(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.setModelMatrix(modelTransformMatrix); + hitboxModel.draw(renderPipelineState,openGLState); + } + } 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.setModelMatrix(modelTransformMatrix); + hitboxModel.draw(renderPipelineState,openGLState); + } + } + } 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.setModelMatrix(modelTransformMatrix); + hitboxModel.draw(renderPipelineState,openGLState); + } + } + } + } + } + + 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.setModelMatrix(modelTransformMatrix); + physicsGraphicsModel.draw(renderPipelineState,openGLState); + } + 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.setModelMatrix(modelTransformMatrix); + physicsGraphicsModel.draw(renderPipelineState,openGLState); + } + 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.setModelMatrix(modelTransformMatrix); + physicsGraphicsModel.draw(renderPipelineState,openGLState); + } + } 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.setModelMatrix(modelTransformMatrix); + physicsGraphicsModel.draw(renderPipelineState,openGLState); + } + } + } + } + } + + 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.setModelMatrix(modelTransformMatrix); + shapeGraphicsModel.draw(renderPipelineState,openGLState); + } + } + } + } + } + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java b/src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java new file mode 100644 index 00000000..b8f63421 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java @@ -0,0 +1,80 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +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.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.actor.Actor; + +/** + * The main content render pipeline without oit passes + */ +public class MainContentNoOITPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + //bind screen fbo + RenderingEngine.screenFramebuffer.bind(); + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + openGLState.glViewport(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); + + GL40.glEnable(GL40.GL_BLEND); + GL40.glBlendFunci(0, GL40.GL_ONE, GL40.GL_ONE); + GL40.glBlendFunci(1, GL40.GL_ZERO, GL40.GL_ONE_MINUS_SRC_COLOR); + GL40.glBlendEquation(GL40.GL_FUNC_ADD); + + /// + /// R E N D E R I N G S T U F F + /// + //Sets the background color. + GL40.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + GL40.glClear(GL40.GL_COLOR_BUFFER_BIT | GL40.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 + // + 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 + RenderingEngine.modelTransformMatrix.identity(); + RenderingEngine.modelTransformMatrix.translate(cameraModifiedPosition); + RenderingEngine.modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + RenderingEngine.modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity))); + currentActor.applyModelMatrix(RenderingEngine.modelTransformMatrix); + //draw + currentActor.draw(renderPipelineState,openGLState); + } + } + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java new file mode 100644 index 00000000..db561da6 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java @@ -0,0 +1,218 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Matrix4d; +import org.joml.Matrix4f; +import org.joml.Quaterniond; +import org.joml.Quaternionf; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +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.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum; +import electrosphere.renderer.actor.Actor; +import electrosphere.renderer.actor.instance.InstancedActor; +import electrosphere.renderer.buffer.ShaderAttribute; + +/** + * The main render pipeline with OIT pass + */ +public class MainContentPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + + Matrix4d modelTransformMatrix = new Matrix4d(); + + //bind screen fbo + RenderingEngine.screenFramebuffer.bind(); + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + openGLState.glViewport(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); + + /// + /// R E N D E R I N G S T U F F + /// + //Sets the background color. + GL40.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + GL40.glClear(GL40.GL_COLOR_BUFFER_BIT | GL40.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 + // + 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,openGLState); + } + } + 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,openGLState); + + // + // Pass Two: Transparency Accumulator + Revealage + // + // glDisable(GL_DEPTH_TEST); + GL40.glDepthMask(false); + GL40.glEnable(GL40.GL_BLEND); + GL40.glBlendFunci(0, GL40.GL_ONE, GL40.GL_ONE); + GL40.glBlendFunci(1, GL40.GL_ZERO, GL40.GL_ONE_MINUS_SRC_COLOR); + GL40.glBlendEquation(GL40.GL_FUNC_ADD); + + RenderingEngine.transparencyBuffer.bind(); + GL40.glClearBufferfv(GL40.GL_COLOR,0,RenderingEngine.transparencyAccumulatorClear); + GL40.glClearBufferfv(GL40.GL_COLOR,1,RenderingEngine.transparencyRevealageClear); + + // + // Set render pipeline state + // + renderPipelineState.setUseMeshShader(true); + renderPipelineState.setSelectedShader(SelectedShaderEnum.OIT); + openGLState.glDepthFunc(GL40.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,openGLState); + } + } + 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,openGLState); + + + // + // Set render pipeline state + // + renderPipelineState.setSelectedShader(SelectedShaderEnum.PRIMARY); + + + +// glBindVertexArray(0); + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java b/src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java new file mode 100644 index 00000000..177dffcf --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java @@ -0,0 +1,88 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Matrix4d; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +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.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.actor.Actor; + +public class NormalsForOutlinePipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + /* + gameImageNormalsTexture; + static Framebuffer gameImageNormalsFramebuffer; + static ShaderProgram renderNormalsShader; + */ + + //bind screen fbo + RenderingEngine.gameImageNormalsFramebuffer.bind(); + openGLState.glDepthTest(true); + GL40.glDisable(GL40.GL_BLEND); + GL40.glBlendFunc(GL40.GL_SRC_ALPHA, GL40.GL_ONE_MINUS_SRC_ALPHA); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + + openGLState.glViewport(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY()); + + /// + /// R E N D E R I N G S T U F F + /// + //Sets the background color. + GL40.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + GL40.glClear(GL40.GL_COLOR_BUFFER_BIT | GL40.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(); + + openGLState.setActiveShader(renderPipelineState, RenderingEngine.renderNormalsShader); + + 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,openGLState); + } + } + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java b/src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java new file mode 100644 index 00000000..bfb44292 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java @@ -0,0 +1,45 @@ +package electrosphere.renderer.pipelines; + +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.shader.ShaderProgram; + +/** + * Post processing pipeline + */ +public class PostProcessingPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + // + // Outline normals + // + + RenderingEngine.normalsOutlineFrambuffer.bind(); + ShaderProgram program = Globals.assetManager.fetchShader("Shaders/anime/outlineNormals.vs", null, "Shaders/anime/outlineNormals.fs"); + if(program != null){ + openGLState.setActiveShader(renderPipelineState, program); + + GL40.glBindVertexArray(RenderingEngine.screenTextureVAO); + + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE1); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE2); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE3); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.gameImageNormalsTexture.getTexturePointer()); + + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + GL40.glBindVertexArray(0); + } + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/RenderPipeline.java b/src/main/java/electrosphere/renderer/pipelines/RenderPipeline.java new file mode 100644 index 00000000..acd5db18 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/RenderPipeline.java @@ -0,0 +1,17 @@ +package electrosphere.renderer.pipelines; + +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; + +/** + * A render pipeline + */ +public interface RenderPipeline { + + /** + * Executes the pipeline + * @param renderPipelineState the current state of the rendering engine + */ + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState); + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java b/src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java new file mode 100644 index 00000000..d547b473 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java @@ -0,0 +1,76 @@ +package electrosphere.renderer.pipelines; + +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; + +/** + * Renders the screen + */ +public class RenderScreenPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + // + //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 + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE1); + GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE2); + GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE3); + GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + + openGLState.glDepthTest(false); + openGLState.glViewport(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + + + + //render full screen quad + openGLState.setActiveShader(renderPipelineState, RenderingEngine.screenTextureShaders); + GL40.glBindVertexArray(RenderingEngine.screenTextureVAO); + //aaa + switch(RenderingEngine.outputFramebuffer){ + case 0: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.screenFramebuffer.getTexturePointer()); + break; + case 1: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.lightDepthBuffer.getTexturePointer()); + break; + case 2: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.volumeDepthBackfaceTexture.getTexturePointer()); + break; + case 3: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.volumeDepthFrontfaceTexture.getTexturePointer()); + break; + case 4: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyAccumulatorTexture.getTexturePointer()); + break; + case 5: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.gameImageNormalsTexture.getTexturePointer()); + break; + case 6: + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.normalsOutlineTexture.getTexturePointer()); + break; + case 7: + openGLState.setActiveShader(renderPipelineState, RenderingEngine.drawChannel); + GL40.glUniform1f(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "channel"),4); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.screenTextureDepth.getTexturePointer()); + break; + } + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + GL40.glBindVertexArray(0); + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java b/src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java new file mode 100644 index 00000000..c677a36a --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java @@ -0,0 +1,110 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Matrix4d; +import org.joml.Matrix4f; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +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.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.actor.Actor; + +/** + * Shadow map pipeline + */ +public class ShadowMapPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Matrix4d modelTransformMatrix = new Matrix4d(); + + //set the viewport to shadow map size + openGLState.glViewport(4096, 4096); + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_ALWAYS); + + openGLState.setActiveShader(renderPipelineState, RenderingEngine.lightDepthShaderProgram); + + RenderingEngine.lightDepthBuffer.bind(); + GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT); + openGLState.glActiveTexture(GL40.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); + + GL40.glUniformMatrix4fv(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "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 + // + 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,openGLState); + } + } + + + + //reset texture + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + //bind default framebuffer + openGLState.glBindFramebuffer(GL40.GL_FRAMEBUFFER,0); + //reset the viewport to screen size + openGLState.glViewport(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + //resume culling backface +// glCullFace(GL_BACK); + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java b/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java new file mode 100644 index 00000000..24a47669 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java @@ -0,0 +1,78 @@ +package electrosphere.renderer.pipelines; + +import org.lwjgl.opengl.GL40; + +import electrosphere.engine.Globals; +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.texture.Texture; +import electrosphere.renderer.ui.DrawableElement; +import electrosphere.renderer.ui.Element; + +/** + * Main ui rendering pipeline + */ +public class UIPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + + // + //Black background + // + if(Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND){ + GL40.glUseProgram(RenderingEngine.screenTextureShaders.getShaderId()); + openGLState.glDepthTest(false); + GL40.glBindVertexArray(RenderingEngine.screenTextureVAO); + Texture blackTexture = Globals.assetManager.fetchTexture(Globals.blackTexture); + if(blackTexture != null){ + blackTexture.bind(openGLState); + } + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + GL40.glBindVertexArray(0); + } + + + // + //White background + // + if(Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND){ + GL40.glUseProgram(RenderingEngine.screenTextureShaders.getShaderId()); + openGLState.glDepthTest(false); + GL40.glBindVertexArray(RenderingEngine.screenTextureVAO); + Texture blackTexture = Globals.assetManager.fetchTexture(Globals.offWhiteTexture); + if(blackTexture != null){ + blackTexture.bind(openGLState); + } + GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); + GL40.glBindVertexArray(0); + } + + + // + // Set render pipeline state + // + if(Globals.RENDER_FLAG_RENDER_UI){ + renderPipelineState.setUseMeshShader(true); + renderPipelineState.setBufferStandardUniforms(false); + renderPipelineState.setBufferNonStandardUniforms(true); + renderPipelineState.setUseMaterial(true); + renderPipelineState.setUseShadowMap(false); + renderPipelineState.setUseBones(false); + renderPipelineState.setUseLight(false); + + openGLState.glDepthTest(false); + for(Element currentElement : Globals.elementManager.getWindowList()){ + if(currentElement instanceof DrawableElement){ + DrawableElement drawable = (DrawableElement) currentElement; + if(drawable.getVisible()){ + drawable.draw(RenderingEngine.GL_DEFAULT_FRAMEBUFFER, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + } + } + } + } + + } + +} diff --git a/src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java b/src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java new file mode 100644 index 00000000..fa876d03 --- /dev/null +++ b/src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java @@ -0,0 +1,194 @@ +package electrosphere.renderer.pipelines; + +import org.joml.Matrix4d; +import org.joml.Vector3d; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL40; + +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.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.actor.Actor; + +/** + * Updates the volume buffer + */ +public class VolumeBufferPipeline implements RenderPipeline { + + @Override + public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Matrix4d modelTransformMatrix = new Matrix4d(); + + //set the viewport to shadow map size + openGLState.glViewport(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + openGLState.glDepthTest(true); + openGLState.glDepthFunc(GL40.GL_LESS); + GL40.glDepthMask(true); + + //stop rendering front faces + GL40.glEnable(GL40.GL_CULL_FACE); + GL40.glCullFace(GL40.GL_FRONT); + + openGLState.setActiveShader(renderPipelineState, RenderingEngine.volumeDepthShaderProgram); + + RenderingEngine.volumeDepthBackfaceFramebuffer.bind(); + GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT); + GL40.glActiveTexture(GL40.GL_TEXTURE0); +// glBindTexture(GL_TEXTURE_2D, woodTexture); +// renderScene(simpleDepthShader); + + GL40.glUniformMatrix4fv(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "view"), false, Globals.viewMatrix.get(new float[16])); + // glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "projection"), false, Globals.projectionMatrix.get(new float[16])); + + + + GL40.glUniform1f(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "linearCoef"), RenderingEngine.volumeDepthLinearCoef); + GL40.glUniform1f(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "quadCoef"), RenderingEngine.volumeDepthQuadCoef); + + GL40.glUniform1f(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "near"), 0.1f); + GL40.glUniform1f(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "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 + // + 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 { + GL40.glUniformMatrix4fv(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "projection"), false, RenderingEngine.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,openGLState); +// System.out.println(currentActor.modelPath); +// } + } + } + + // + //Draw front faces of all non-volumetrics + // + 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 + GL40.glUniformMatrix4fv(GL40.glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "projection"), false, RenderingEngine.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,openGLState); + } + } + + + + //stop rendering front faces + GL40.glEnable(GL40.GL_CULL_FACE); + GL40.glCullFace(GL40.GL_BACK); + + openGLState.setActiveShader(renderPipelineState, RenderingEngine.volumeDepthShaderProgram); + + RenderingEngine.volumeDepthFrontfaceFramebuffer.bind(); + GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT); + openGLState.glActiveTexture(GL40.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,openGLState); +// System.out.println(currentActor.modelPath); +// } + } + } + + GL40.glCullFace(GL40.GL_BACK); + //now cull back faces + + //reset texture + openGLState.glActiveTexture(GL40.GL_TEXTURE0); + openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); + //bind default framebuffer + openGLState.glBindFramebuffer(GL40.GL_FRAMEBUFFER,0); + //resume culling backface + GL40.glDisable(GL40.GL_CULL_FACE); + } + +} diff --git a/src/main/java/electrosphere/renderer/ShaderProgram.java b/src/main/java/electrosphere/renderer/shader/ShaderProgram.java similarity index 88% rename from src/main/java/electrosphere/renderer/ShaderProgram.java rename to src/main/java/electrosphere/renderer/shader/ShaderProgram.java index 73f04677..cbb65ed6 100644 --- a/src/main/java/electrosphere/renderer/ShaderProgram.java +++ b/src/main/java/electrosphere/renderer/shader/ShaderProgram.java @@ -1,4 +1,4 @@ -package electrosphere.renderer; +package electrosphere.renderer.shader; import static org.lwjgl.opengl.GL11.GL_TRUE; import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS; @@ -22,12 +22,19 @@ import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import javax.management.RuntimeErrorException; +import org.joml.Matrix4d; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL40; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; @@ -44,7 +51,7 @@ public class ShaderProgram { int vertexShader; int geometryShader; int fragmentShader; - int shaderProgram; + int shaderId; // @@ -60,16 +67,18 @@ public class ShaderProgram { //Uniforms - //list of names of all uniforms in the shader - // public List uniformList; - //map - //string -> tuple - //tuple: a string describing the type of the data,the current value,location - //ie arrayVec3,[<1,0,0>,<2,0,0>],colors - // Mat4,[Matrix4f],modelMatrix - // public Map uniformMap; + public Map uniformMap = new HashMap(); + + //keeps track of programs that have already been compiled and returns them instead of recompiling from scratch + static Map alreadyCompiledMap = new HashMap(); public static ShaderProgram smart_assemble_shader(boolean ContainsBones, boolean apply_lighting){ + + //return shader if it has already been compiled + String shaderKey = ContainsBones + "-" + apply_lighting; + if(alreadyCompiledMap.containsKey(shaderKey)){ + return alreadyCompiledMap.get(shaderKey); + } String vertex_shader_path = ""; if(ContainsBones){ @@ -153,16 +162,16 @@ public class ShaderProgram { LoggerInterface.loggerRenderer.ERROR("Runtime Exception", new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader))); } //This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram - rVal.shaderProgram = glCreateProgram(); + rVal.shaderId = glCreateProgram(); //This attaches the vertex and fragment shaders to the program - glAttachShader(rVal.shaderProgram, rVal.vertexShader); - glAttachShader(rVal.shaderProgram, rVal.fragmentShader); + glAttachShader(rVal.shaderId, rVal.vertexShader); + glAttachShader(rVal.shaderId, rVal.fragmentShader); //This links the program to the GPU (I think its to the GPU anyway) - glLinkProgram(rVal.shaderProgram); + glLinkProgram(rVal.shaderId); //Tests for the success of the shader program creation - success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS); + success = glGetProgrami(rVal.shaderId, GL_LINK_STATUS); if (success != GL_TRUE) { - throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram)); + throw new RuntimeException(glGetProgramInfoLog(rVal.shaderId)); } //Deletes the individual shader objects to free up memory @@ -174,18 +183,18 @@ public class ShaderProgram { // //Set locations // - rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model"); - rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view"); - rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection"); - rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos"); + rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderId, "model"); + rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderId, "view"); + rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderId, "projection"); + rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderId, "viewPos"); if(ContainsBones){ - rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderProgram, "bones"); - rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderProgram, "numBones"); + rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderId, "bones"); + rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderId, "numBones"); } - rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderProgram, "hasBones"); - + rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderId, "hasBones"); + alreadyCompiledMap.put(shaderKey,rVal); return rVal; } @@ -198,6 +207,12 @@ public class ShaderProgram { * @return The int-pointer to the shader compiled */ public static ShaderProgram smartAssembleOITProgram(boolean ContainsBones, boolean apply_lighting){ + + //return shader if it has already been compiled + String shaderKey = "oit" + ContainsBones + "-" + apply_lighting; + if(alreadyCompiledMap.containsKey(shaderKey)){ + return alreadyCompiledMap.get(shaderKey); + } String vertex_shader_path = ""; if(ContainsBones){ @@ -281,16 +296,16 @@ public class ShaderProgram { LoggerInterface.loggerRenderer.ERROR("Runtime Exception", new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader))); } //This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram - rVal.shaderProgram = glCreateProgram(); + rVal.shaderId = glCreateProgram(); //This attaches the vertex and fragment shaders to the program - glAttachShader(rVal.shaderProgram, rVal.vertexShader); - glAttachShader(rVal.shaderProgram, rVal.fragmentShader); + glAttachShader(rVal.shaderId, rVal.vertexShader); + glAttachShader(rVal.shaderId, rVal.fragmentShader); //This links the program to the GPU (I think its to the GPU anyway) - glLinkProgram(rVal.shaderProgram); + glLinkProgram(rVal.shaderId); //Tests for the success of the shader program creation - success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS); + success = glGetProgrami(rVal.shaderId, GL_LINK_STATUS); if (success != GL_TRUE) { - throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram)); + throw new RuntimeException(glGetProgramInfoLog(rVal.shaderId)); } //Deletes the individual shader objects to free up memory @@ -302,18 +317,18 @@ public class ShaderProgram { // //Set locations // - rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model"); - rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view"); - rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection"); - rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos"); + rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderId, "model"); + rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderId, "view"); + rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderId, "projection"); + rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderId, "viewPos"); if(ContainsBones){ - rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderProgram, "bones"); - rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderProgram, "numBones"); + rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderId, "bones"); + rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderId, "numBones"); } - rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderProgram, "hasBones"); - + rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderId, "hasBones"); + alreadyCompiledMap.put(shaderKey,rVal); return rVal; } @@ -396,16 +411,16 @@ public class ShaderProgram { LoggerInterface.loggerRenderer.ERROR("Runtime Exception", new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader))); } //This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram - rVal.shaderProgram = glCreateProgram(); + rVal.shaderId = glCreateProgram(); //This attaches the vertex and fragment shaders to the program - glAttachShader(rVal.shaderProgram, rVal.vertexShader); - glAttachShader(rVal.shaderProgram, rVal.fragmentShader); + glAttachShader(rVal.shaderId, rVal.vertexShader); + glAttachShader(rVal.shaderId, rVal.fragmentShader); //This links the program to the GPU (I think its to the GPU anyway) - glLinkProgram(rVal.shaderProgram); + glLinkProgram(rVal.shaderId); //Tests for the success of the shader program creation - success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS); + success = glGetProgrami(rVal.shaderId, GL_LINK_STATUS); if (success != GL_TRUE) { - throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram)); + throw new RuntimeException(glGetProgramInfoLog(rVal.shaderId)); } //Deletes the individual shader objects to free up memory @@ -417,13 +432,13 @@ public class ShaderProgram { // //Set locations // - rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model"); - rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view"); - rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection"); - rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos"); - rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderProgram, "bones"); - rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderProgram, "numBones"); - rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderProgram, "hasBones"); + rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderId, "model"); + rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderId, "view"); + rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderId, "projection"); + rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderId, "viewPos"); + rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderId, "bones"); + rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderId, "numBones"); + rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderId, "hasBones"); @@ -587,16 +602,16 @@ public class ShaderProgram { } } //This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram - rVal.shaderProgram = glCreateProgram(); + rVal.shaderId = glCreateProgram(); //This attaches the vertex and fragment shaders to the program - glAttachShader(rVal.shaderProgram, rVal.vertexShader); - glAttachShader(rVal.shaderProgram, rVal.fragmentShader); + glAttachShader(rVal.shaderId, rVal.vertexShader); + glAttachShader(rVal.shaderId, rVal.fragmentShader); //This links the program to the GPU (I think its to the GPU anyway) - glLinkProgram(rVal.shaderProgram); + glLinkProgram(rVal.shaderId); //Tests for the success of the shader program creation - success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS); + success = glGetProgrami(rVal.shaderId, GL_LINK_STATUS); if (success != GL_TRUE) { - LoggerInterface.loggerRenderer.ERROR(glGetProgramInfoLog(rVal.shaderProgram), new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram))); + LoggerInterface.loggerRenderer.ERROR(glGetProgramInfoLog(rVal.shaderId), new RuntimeException(glGetProgramInfoLog(rVal.shaderId))); LoggerInterface.loggerRenderer.WARNING("Shader sources: " + vertexPath + " " + fragmentPath); return Globals.defaultMeshShader; // throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram)); @@ -611,10 +626,10 @@ public class ShaderProgram { // //Set locations // - rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model"); - rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view"); - rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection"); - rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos"); + rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderId, "model"); + rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderId, "view"); + rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderId, "projection"); + rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderId, "viewPos"); @@ -687,17 +702,17 @@ public class ShaderProgram { LoggerInterface.loggerRenderer.ERROR("Runtime Exception", new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader))); } //This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram - rVal.shaderProgram = glCreateProgram(); + rVal.shaderId = glCreateProgram(); //This attaches the vertex and fragment shaders to the program - glAttachShader(rVal.shaderProgram, rVal.vertexShader); - glAttachShader(rVal.shaderProgram, rVal.geometryShader); - glAttachShader(rVal.shaderProgram, rVal.fragmentShader); + glAttachShader(rVal.shaderId, rVal.vertexShader); + glAttachShader(rVal.shaderId, rVal.geometryShader); + glAttachShader(rVal.shaderId, rVal.fragmentShader); //This links the program to the GPU (I think its to the GPU anyway) - glLinkProgram(rVal.shaderProgram); + glLinkProgram(rVal.shaderId); //Tests for the success of the shader program creation - success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS); + success = glGetProgrami(rVal.shaderId, GL_LINK_STATUS); if (success != GL_TRUE) { - throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram)); + throw new RuntimeException(glGetProgramInfoLog(rVal.shaderId)); } //Deletes the individual shader objects to free up memory @@ -710,15 +725,51 @@ public class ShaderProgram { // //Set locations // - rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model"); - rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view"); - rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection"); - rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos"); + rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderId, "model"); + rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderId, "view"); + rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderId, "projection"); + rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderId, "viewPos"); return rVal; } + + /** + * Sets the value of a uniform on this shader + * @param uniformLocation the uniform location + * @param value the value + */ + public void setUniform(int uniformLocation, Object value){ + if(!uniformMap.containsKey(uniformLocation) || !uniformMap.get(uniformLocation).equals(value)){ + uniformMap.put(uniformLocation,value); + if(value instanceof Matrix4f){ + Matrix4f currentUniform = (Matrix4f)value; + GL40.glUniformMatrix4fv(uniformLocation, false, currentUniform.get(new float[16])); + } + if(value instanceof Matrix4d){ + Matrix4d currentUniform = (Matrix4d)value; + GL40.glUniformMatrix4fv(uniformLocation, false, currentUniform.get(new float[16])); + } + if(value instanceof Vector3f){ + Vector3f currentUniform = (Vector3f)value; + GL40.glUniform3fv(uniformLocation, currentUniform.get(BufferUtils.createFloatBuffer(3))); + } + if(value instanceof Integer){ + int currentInform = (Integer)value; + GL40.glUniform1i(uniformLocation, currentInform); + } + } + } + + + /** + * Gets the id of the shader + * @return The shader id + */ + public int getShaderId(){ + return shaderId; + } } diff --git a/src/main/java/electrosphere/renderer/texture/Texture.java b/src/main/java/electrosphere/renderer/texture/Texture.java index 8bae4a3a..f7166ca3 100644 --- a/src/main/java/electrosphere/renderer/texture/Texture.java +++ b/src/main/java/electrosphere/renderer/texture/Texture.java @@ -7,6 +7,7 @@ package electrosphere.renderer.texture; import electrosphere.engine.Globals; import electrosphere.engine.Main; +import electrosphere.renderer.OpenGLState; import electrosphere.util.FileUtils; import java.awt.Color; import java.awt.image.BufferedImage; @@ -201,14 +202,16 @@ public class Texture { } } - public void bind(){ - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texturePointer); + public void bind(OpenGLState openGLState){ + // openGLState.glActiveTexture(GL_TEXTURE0); + // openGLState.glBindTexture(GL_TEXTURE_2D, texturePointer); + openGLState.glBindTextureUnit(GL_TEXTURE0,texturePointer,GL_TEXTURE_2D); } - public void bind(int attrib_val){ - glActiveTexture(GL_TEXTURE0 + attrib_val); - glBindTexture(GL_TEXTURE_2D, texturePointer); + public void bind(OpenGLState openGLState, int attrib_val){ + openGLState.glBindTextureUnit(GL_TEXTURE0 + attrib_val,texturePointer,GL_TEXTURE_2D); + // openGLState.glActiveTexture(GL_TEXTURE0 + attrib_val); + // openGLState.glBindTexture(GL_TEXTURE_2D, texturePointer); } public boolean isTransparent(){ diff --git a/src/main/java/electrosphere/renderer/ui/Window.java b/src/main/java/electrosphere/renderer/ui/Window.java index b435a107..873647b6 100644 --- a/src/main/java/electrosphere/renderer/ui/Window.java +++ b/src/main/java/electrosphere/renderer/ui/Window.java @@ -14,11 +14,11 @@ import org.joml.Vector3f; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Material; -import electrosphere.renderer.Model; import electrosphere.renderer.debug.DebugRendering; import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.events.NavigationEvent; @@ -82,7 +82,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); - planeModel.meshes.get(0).setMaterial(customMat); + planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.drawUI(); } else { LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model!!", new Exception()); diff --git a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java index 0b4cdbcd..ebe20260 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java @@ -22,13 +22,13 @@ import org.joml.Vector3f; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Material; -import electrosphere.renderer.Model; import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.debug.DebugRendering; import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.DraggableElement; import electrosphere.renderer.ui.DrawableElement; import electrosphere.renderer.ui.events.DragEvent; @@ -120,7 +120,7 @@ public class ActorPanel implements DrawableElement, DraggableElement { actor.applyModelMatrix(modelMatrix); - actor.draw(Globals.renderingEngine.getRenderPipelineState()); + actor.draw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState()); RenderingEngine.setFOV(Globals.verticalFOV); RenderingEngine.setAspectRatio(Globals.aspectRatio); @@ -142,7 +142,7 @@ public class ActorPanel implements DrawableElement, DraggableElement { Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); - Globals.renderingEngine.setActiveShader( + Globals.renderingEngine.getOpenGLState().setActiveShader( Globals.renderingEngine.getRenderPipelineState(), Globals.assetManager.fetchShader("Shaders/ui/windowContent/windowContent.vs", null, "Shaders/ui/windowContent/windowContent.fs") ); @@ -172,8 +172,8 @@ public class ActorPanel implements DrawableElement, DraggableElement { planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); - planeModel.meshes.get(0).setMaterial(customMat); - planeModel.draw(Globals.renderingEngine.getRenderPipelineState()); + planeModel.getMeshes().get(0).setMaterial(customMat); + planeModel.draw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState()); } else { LoggerInterface.loggerRenderer.ERROR("Actor Panel unable to find plane model!!", new Exception()); } diff --git a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java index 2bc05883..ea11c8fc 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java @@ -7,9 +7,9 @@ import org.joml.Vector3f; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Material; -import electrosphere.renderer.Model; import electrosphere.renderer.debug.DebugRendering; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Model; import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.DraggableElement; import electrosphere.renderer.ui.DrawableElement; @@ -92,7 +92,7 @@ public class ImagePanel implements DrawableElement, DraggableElement { planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); - planeModel.meshes.get(0).setMaterial(customMat); + planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.drawUI(); } else { LoggerInterface.loggerRenderer.ERROR("Image Panel unable to find plane model!!", new Exception()); diff --git a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java index ab85f94a..53f4c395 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java @@ -8,10 +8,10 @@ import org.joml.Vector3f; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Material; -import electrosphere.renderer.Model; import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.ContainerElement; import electrosphere.renderer.ui.DrawableElement; import electrosphere.renderer.ui.Element; @@ -257,7 +257,7 @@ public class ScrollableContainer implements DrawableElement, ContainerElement { planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); - planeModel.meshes.get(0).setMaterial(customMat); + planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.drawUI(); } else { LoggerInterface.loggerRenderer.ERROR("ScrollableContainer unable to find plane model!!", new Exception()); diff --git a/src/main/java/electrosphere/renderer/ui/elements/Slider.java b/src/main/java/electrosphere/renderer/ui/elements/Slider.java index 6ccbfe9b..6faaf184 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Slider.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Slider.java @@ -4,8 +4,8 @@ import org.joml.Vector3f; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Model; import electrosphere.renderer.debug.DebugRendering; +import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.ClickableElement; import electrosphere.renderer.ui.DraggableElement; import electrosphere.renderer.ui.DrawableElement; @@ -102,7 +102,7 @@ public class Slider implements ClickableElement, DraggableElement, FocusableElem //bounding box/margin planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); - planeModel.pushUniformToMesh(planeModel.meshes.get(0).nodeID, "color", colorBackground); + planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", colorBackground); planeModel.drawUI(); //actual slider @@ -114,7 +114,7 @@ public class Slider implements ClickableElement, DraggableElement, FocusableElem boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); - planeModel.pushUniformToMesh(planeModel.meshes.get(0).nodeID, "color", colorForeground); + planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", colorForeground); planeModel.drawUI(); } else { LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model!!", new Exception()); diff --git a/src/main/java/electrosphere/renderer/ui/elements/TextBox.java b/src/main/java/electrosphere/renderer/ui/elements/TextBox.java index 2b10ea10..029731d9 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/TextBox.java +++ b/src/main/java/electrosphere/renderer/ui/elements/TextBox.java @@ -1,8 +1,8 @@ package electrosphere.renderer.ui.elements; -import electrosphere.renderer.Model; import electrosphere.engine.Globals; import electrosphere.engine.assetmanager.AssetDataStrings; +import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.DrawableElement; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.font.FontUtils; diff --git a/src/main/java/electrosphere/renderer/ui/elements/TextInput.java b/src/main/java/electrosphere/renderer/ui/elements/TextInput.java index abe425df..6fc9ec4c 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/TextInput.java +++ b/src/main/java/electrosphere/renderer/ui/elements/TextInput.java @@ -1,11 +1,11 @@ package electrosphere.renderer.ui.elements; -import electrosphere.renderer.Material; -import electrosphere.renderer.Model; import electrosphere.engine.Globals; import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Model; import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.DrawableElement; import electrosphere.renderer.ui.Element; diff --git a/src/main/java/electrosphere/renderer/ui/font/Font.java b/src/main/java/electrosphere/renderer/ui/font/Font.java index f2c8acc0..11c66d09 100644 --- a/src/main/java/electrosphere/renderer/ui/font/Font.java +++ b/src/main/java/electrosphere/renderer/ui/font/Font.java @@ -4,7 +4,7 @@ import java.util.HashMap; import java.util.List; import org.joml.Vector3f; -import electrosphere.renderer.Material; +import electrosphere.renderer.model.Material; /** * A font diff --git a/src/main/java/electrosphere/renderer/ui/font/FontManager.java b/src/main/java/electrosphere/renderer/ui/font/FontManager.java index 8677aff5..05784e5b 100644 --- a/src/main/java/electrosphere/renderer/ui/font/FontManager.java +++ b/src/main/java/electrosphere/renderer/ui/font/FontManager.java @@ -6,7 +6,7 @@ import java.util.HashMap; import java.util.Map; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Material; +import electrosphere.renderer.model.Material; import electrosphere.util.FileUtils; /** diff --git a/src/main/java/electrosphere/renderer/ui/font/FontUtils.java b/src/main/java/electrosphere/renderer/ui/font/FontUtils.java index a2e335b7..2b1a11ac 100644 --- a/src/main/java/electrosphere/renderer/ui/font/FontUtils.java +++ b/src/main/java/electrosphere/renderer/ui/font/FontUtils.java @@ -1,6 +1,6 @@ package electrosphere.renderer.ui.font; -import electrosphere.renderer.Material; +import electrosphere.renderer.model.Material; import electrosphere.renderer.texture.Texture; import java.awt.image.BufferedImage; diff --git a/src/main/java/electrosphere/renderer/ui/font/bitmapchar/BitmapCharacter.java b/src/main/java/electrosphere/renderer/ui/font/bitmapchar/BitmapCharacter.java index d1c4cecb..311702a5 100644 --- a/src/main/java/electrosphere/renderer/ui/font/bitmapchar/BitmapCharacter.java +++ b/src/main/java/electrosphere/renderer/ui/font/bitmapchar/BitmapCharacter.java @@ -2,8 +2,8 @@ package electrosphere.renderer.ui.font.bitmapchar; import electrosphere.engine.Globals; import electrosphere.engine.assetmanager.AssetDataStrings; -import electrosphere.renderer.Material; -import electrosphere.renderer.Model; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.DrawableElement; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.font.Font; diff --git a/src/main/java/electrosphere/renderer/ui/layout/LayoutSchemeListScrollable.java b/src/main/java/electrosphere/renderer/ui/layout/LayoutSchemeListScrollable.java index bf9c1635..636ed6bb 100644 --- a/src/main/java/electrosphere/renderer/ui/layout/LayoutSchemeListScrollable.java +++ b/src/main/java/electrosphere/renderer/ui/layout/LayoutSchemeListScrollable.java @@ -13,11 +13,11 @@ import java.util.List; import org.joml.Vector3f; import electrosphere.engine.Globals; -import electrosphere.renderer.Material; -import electrosphere.renderer.Model; import electrosphere.renderer.debug.DebugRendering; import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.DrawableElement; import electrosphere.renderer.ui.Element; import electrosphere.renderer.ui.events.Event; @@ -77,7 +77,7 @@ public class LayoutSchemeListScrollable implements DrawableElement,LayoutScheme planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); - planeModel.meshes.get(0).setMaterial(customMat); + planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.drawUI(); if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){ diff --git a/src/main/java/electrosphere/server/datacell/physics/DataCellPhysicsManager.java b/src/main/java/electrosphere/server/datacell/physics/DataCellPhysicsManager.java index ca8fdcf6..59eee272 100644 --- a/src/main/java/electrosphere/server/datacell/physics/DataCellPhysicsManager.java +++ b/src/main/java/electrosphere/server/datacell/physics/DataCellPhysicsManager.java @@ -6,7 +6,7 @@ import electrosphere.client.terrain.manager.ClientTerrainManager; import electrosphere.engine.Globals; import electrosphere.game.terrain.processing.TerrainInterpolator; import electrosphere.net.parser.net.message.TerrainMessage; -import electrosphere.renderer.ShaderProgram; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.server.datacell.Realm; import electrosphere.server.terrain.manager.ServerTerrainManager; diff --git a/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java b/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java index 5f8bcf00..8b90735f 100644 --- a/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java +++ b/src/main/java/electrosphere/server/datacell/physics/PhysicsDataCell.java @@ -12,12 +12,11 @@ import electrosphere.entity.ServerEntityUtils; import electrosphere.entity.types.terrain.TerrainChunk; import electrosphere.game.terrain.processing.TerrainInterpolator; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Mesh; -import electrosphere.renderer.Model; -import electrosphere.renderer.ModelUtils; import electrosphere.renderer.RenderUtils; -import electrosphere.renderer.ShaderProgram; import electrosphere.renderer.actor.ActorTextureMask; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.texture.Texture; import electrosphere.server.datacell.Realm; import electrosphere.server.terrain.manager.ServerTerrainManager; diff --git a/src/main/java/electrosphere/server/poseactor/PoseActor.java b/src/main/java/electrosphere/server/poseactor/PoseActor.java index 1c5123b6..a01f87a4 100644 --- a/src/main/java/electrosphere/server/poseactor/PoseActor.java +++ b/src/main/java/electrosphere/server/poseactor/PoseActor.java @@ -15,11 +15,11 @@ import org.joml.Vector4d; import org.joml.Vector4f; import electrosphere.engine.Globals; -import electrosphere.renderer.Bone; import electrosphere.renderer.actor.ActorAnimationMask; import electrosphere.renderer.actor.ActorBoneRotator; import electrosphere.renderer.actor.ActorStaticMorph; import electrosphere.renderer.actor.ActorStaticMorph.StaticMorphTransforms; +import electrosphere.renderer.model.Bone; /** * An actor that references a posemodel diff --git a/src/main/java/electrosphere/server/poseactor/PoseModel.java b/src/main/java/electrosphere/server/poseactor/PoseModel.java index 4436b81d..586a87c6 100644 --- a/src/main/java/electrosphere/server/poseactor/PoseModel.java +++ b/src/main/java/electrosphere/server/poseactor/PoseModel.java @@ -18,13 +18,13 @@ import org.lwjgl.assimp.AIScene; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Bone; import electrosphere.renderer.actor.ActorBoneRotator; import electrosphere.renderer.actor.ActorStaticMorph; import electrosphere.renderer.anim.AnimChannel; import electrosphere.renderer.anim.AnimNode; import electrosphere.renderer.anim.Animation; import electrosphere.renderer.loading.ModelPretransforms; +import electrosphere.renderer.model.Bone; /** * Used server side to load model data for positioning hitboxes based on animations diff --git a/src/main/java/electrosphere/util/Utilities.java b/src/main/java/electrosphere/util/Utilities.java index ae6aa05c..d6a6f84c 100644 --- a/src/main/java/electrosphere/util/Utilities.java +++ b/src/main/java/electrosphere/util/Utilities.java @@ -3,10 +3,10 @@ package electrosphere.util; import electrosphere.engine.Globals; import electrosphere.engine.Main; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.Material; -import electrosphere.renderer.Mesh; -import electrosphere.renderer.Model; -import electrosphere.renderer.ShaderProgram; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.texture.Texture; import electrosphere.renderer.texture.TextureMap; import com.google.gson.Gson;