From b711111589084db78399381ee36c526015e62695 Mon Sep 17 00:00:00 2001 From: austin Date: Sat, 23 Mar 2024 23:19:06 -0400 Subject: [PATCH] Remotery + extensive profiler usage --- .vscode/launch.json | 4 +- buildNumber.properties | 4 +- docs/src/progress/renderertodo.md | 8 +- pom.xml | 15 +++ .../java/electrosphere/audio/AudioEngine.java | 12 +- .../audio/VirtualAudioSourceManager.java | 13 +- .../client/fluid/cells/FluidCellManager.java | 4 +- .../fluid/manager/ClientFluidManager.java | 2 + .../foliagemanager/ClientFoliageManager.java | 2 + .../client/instancing/InstanceUpdater.java | 18 ++- .../client/scene/ClientSceneWrapper.java | 21 ++-- .../client/sim/ClientFunctions.java | 86 ------------- .../client/sim/ClientSimulation.java | 111 +++++++++++++++++ .../client/terrain/cells/DrawCellManager.java | 4 +- .../terrain/manager/ClientTerrainManager.java | 2 + .../collision/CollisionBodyCreation.java | 10 +- .../collision/CollisionEngine.java | 23 +++- .../collision/PhysicsEntityUtils.java | 14 ++- .../electrosphere/controls/CameraHandler.java | 114 +++++++++--------- .../java/electrosphere/engine/Globals.java | 14 +++ src/main/java/electrosphere/engine/Main.java | 112 +++++++---------- .../engine/assetmanager/AssetManager.java | 3 + .../engine/profiler/Profiler.java | 72 +++++++++++ .../electrosphere/engine/time/Timekeeper.java | 10 +- src/main/java/electrosphere/entity/Scene.java | 2 + .../entity/types/attach/AttachUtils.java | 35 ++++-- .../entity/types/tree/ProceduralTree.java | 6 +- .../net/client/ClientNetworking.java | 4 + .../net/client/protocol/ClientProtocol.java | 2 + .../net/client/protocol/EntityProtocol.java | 2 + .../net/client/protocol/PlayerProtocol.java | 2 + .../protocol/SynchronizationProtocol.java | 2 + .../net/client/protocol/TerrainProtocol.java | 2 + .../renderer/pipelines/CompositePipeline.java | 4 +- .../pipelines/DebugContentPipeline.java | 4 + .../pipelines/MainContentNoOITPipeline.java | 4 + .../pipelines/MainContentPipeline.java | 3 + .../pipelines/NormalsForOutlinePipeline.java | 3 + .../pipelines/PostProcessingPipeline.java | 3 + .../pipelines/RenderScreenPipeline.java | 3 + .../renderer/pipelines/ShadowMapPipeline.java | 3 + .../renderer/pipelines/UIPipeline.java | 2 + .../pipelines/VolumeBufferPipeline.java | 3 + .../server/content/EnvironmentGenerator.java | 2 +- 44 files changed, 501 insertions(+), 268 deletions(-) delete mode 100644 src/main/java/electrosphere/client/sim/ClientFunctions.java create mode 100644 src/main/java/electrosphere/engine/profiler/Profiler.java diff --git a/.vscode/launch.json b/.vscode/launch.json index 98bf68df..a1d58467 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,7 +15,7 @@ "name": "Launch Main", "request": "launch", "mainClass": "electrosphere.engine.Main", - "vmArgs": "-Xmx2G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", + "vmArgs": "-Xmx2G -Xms100m -XX:+UseZGC -XX:+UseDynamicNumberOfGCThreads -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", "projectName": "Renderer" }, { @@ -26,7 +26,7 @@ "env": { "ALSOFT_LOGLEVEL": 4, }, - "vmArgs": "-Xmx2G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", + "vmArgs": "-Xmx2G -Xms100m -XX:+UseZGC -XX:+UseDynamicNumberOfGCThreads -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"", "projectName": "Renderer" }, { diff --git a/buildNumber.properties b/buildNumber.properties index 3887b797..45003335 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sat Mar 23 16:53:49 EDT 2024 -buildNumber=80 +#Sat Mar 23 19:48:52 EDT 2024 +buildNumber=82 diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 7fb9e1a1..7f32ecc8 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -185,6 +185,8 @@ Physics-controlled objects system # TODO +Clean up main method/class + - Include Remotery library Level loading/saving + Basic Editor - Spin up voxel level (think arena mode) @@ -193,6 +195,9 @@ Level loading/saving + Basic Editor - Menu of types of entities to spawn - Button to spawn them at cursor +Revisit first attempt at instancing (its really laggy lol) + - Maybe have draw call happen on top level entity and immediately queue all children recursively + Shader library system - Abiltiy to include the shader library in individual files (ie implement #include) @@ -229,9 +234,6 @@ Light Manager - Eventually support spot lights? - Point shadows ??? -Clean up main method/class - - Include Remotery library - gltf Support - Fix bad data with human mesh textures not mapping - Texture loading from gltf file diff --git a/pom.xml b/pom.xml index 532ba9c8..c36e9944 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,7 @@ 17 17 3.2.3 + 3.3.3 1.9.19 1.5.7 1.86.11 @@ -109,6 +110,20 @@ ${lwjgl.version} ${lwjgl.natives} + + + + + org.lwjgl + lwjgl-remotery + ${lwjgl.remotery.version} + + + org.lwjgl + lwjgl-remotery + ${lwjgl.remotery.version} + ${lwjgl.natives} + diff --git a/src/main/java/electrosphere/audio/AudioEngine.java b/src/main/java/electrosphere/audio/AudioEngine.java index 9dd8dc19..8db799cf 100644 --- a/src/main/java/electrosphere/audio/AudioEngine.java +++ b/src/main/java/electrosphere/audio/AudioEngine.java @@ -142,11 +142,13 @@ public class AudioEngine { * Updates the orientation of the listener based on the global player camera */ private void updateListener(){ - Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); - Vector3f cameraEye = new Vector3f(CameraEntityUtils.getCameraEye(Globals.playerCamera)).mul(-1); - Vector3f cameraUp = new Vector3f(0,1,0); - listener.setPosition(cameraPos); - listener.setOrientation(cameraEye, cameraUp); + if(Globals.playerCamera != null){ + Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); + Vector3f cameraEye = new Vector3f(CameraEntityUtils.getCameraEye(Globals.playerCamera)).mul(-1); + Vector3f cameraUp = new Vector3f(0,1,0); + listener.setPosition(cameraPos); + listener.setOrientation(cameraEye, cameraUp); + } } /** diff --git a/src/main/java/electrosphere/audio/VirtualAudioSourceManager.java b/src/main/java/electrosphere/audio/VirtualAudioSourceManager.java index 0988999d..29ce2174 100644 --- a/src/main/java/electrosphere/audio/VirtualAudioSourceManager.java +++ b/src/main/java/electrosphere/audio/VirtualAudioSourceManager.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; import org.joml.Vector3d; import org.joml.Vector3f; @@ -34,7 +35,7 @@ public class VirtualAudioSourceManager { List categories = new LinkedList(); //The list of all virtual sources - List virtualSourceQueue = new LinkedList(); + List virtualSourceQueue = new CopyOnWriteArrayList(); //the map of virtual source to active source for all active sources Map virtualActiveMap = new HashMap(); @@ -150,10 +151,12 @@ public class VirtualAudioSourceManager { } else { realSource = AudioUtils.playAudioAtLocation(source.filePath, new Vector3f((float)source.position.x,(float)source.position.y,(float)source.position.z),source.loops); } - source.setFadeRate(category.fadeInRate); - realSource.setGain(source.gain); - realSource.setOffset(source.totalTimePlayed); - virtualActiveMap.put(source, realSource); + if(realSource != null){ + source.setFadeRate(category.fadeInRate); + realSource.setGain(source.gain); + realSource.setOffset(source.totalTimePlayed); + virtualActiveMap.put(source, realSource); + } } } } diff --git a/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java b/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java index 05078274..b85be7a1 100644 --- a/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java +++ b/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java @@ -239,9 +239,8 @@ public class FluidCellManager { /** * Calculates whether the position of the player has changed and if so, invalidates and cleans up cells accordingly - * @param position The position of the player entity on current frame */ - public void calculateDeltas(Vector3d position){ + private void calculateDeltas(){ //check if any not requested cells no longer need to be requested clearOutOfBoundsCells(); //check if any cells should be added @@ -320,6 +319,7 @@ public class FluidCellManager { * Updates cells that need updating in this manager */ public void update(){ + calculateDeltas(); if(update){ if(containsUnrequestedCell() && !containsUndrawableCell()){ updateUnrequestedCell(); diff --git a/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java b/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java index de329246..ae280098 100644 --- a/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java +++ b/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java @@ -144,11 +144,13 @@ public class ClientFluidManager { * Pushes all fluid data in queue to the gpu and registers the resulting models */ public static void generateFluidChunkGeometry(){ + Globals.profiler.beginCpuSample("generateFluidChunkGeometry"); for(FluidChunkGenQueueItem queueItem : fluidChunkGenerationQueue){ Model fluidModel = FluidChunkModelGeneration.generateFluidModel(queueItem.getData()); Globals.assetManager.registerModelToSpecificString(fluidModel, queueItem.getPromisedHash()); } fluidChunkGenerationQueue.clear(); + Globals.profiler.endCpuSample(); } /** diff --git a/src/main/java/electrosphere/client/foliagemanager/ClientFoliageManager.java b/src/main/java/electrosphere/client/foliagemanager/ClientFoliageManager.java index f2f1bf8d..973c0b9f 100644 --- a/src/main/java/electrosphere/client/foliagemanager/ClientFoliageManager.java +++ b/src/main/java/electrosphere/client/foliagemanager/ClientFoliageManager.java @@ -134,6 +134,7 @@ public class ClientFoliageManager { * Updates all grass entities */ public void update(){ + Globals.profiler.beginCpuSample("ClientFoliageManager.update"); if(ready){ //for each invalid cell, see if can be revalidated for(String key : locationEvaluationCooldownMap.keySet()){ @@ -161,6 +162,7 @@ public class ClientFoliageManager { //invalidate foliage cells that have had their voxel changed invalidateModifiedPositions(); } + Globals.profiler.endCpuSample(); } /** diff --git a/src/main/java/electrosphere/client/instancing/InstanceUpdater.java b/src/main/java/electrosphere/client/instancing/InstanceUpdater.java index b88fdb1a..a6ce1b84 100644 --- a/src/main/java/electrosphere/client/instancing/InstanceUpdater.java +++ b/src/main/java/electrosphere/client/instancing/InstanceUpdater.java @@ -1,5 +1,7 @@ package electrosphere.client.instancing; +import java.util.Set; + import org.joml.Vector3d; import electrosphere.engine.Globals; @@ -18,12 +20,18 @@ public class InstanceUpdater { * Updates all instanced actors to have priority based on distance from camera */ public static void updateInstancedActorPriority(){ - Vector3d eyePosition = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); - for(Entity entity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){ - //set priority equal to distance - Vector3d entityPosition = EntityUtils.getPosition(entity); - InstancedActor.getInstancedActor(entity).setPriority((int)entityPosition.distance(eyePosition)); + Globals.profiler.beginCpuSample("updateInstancedActorPriority"); + if(Globals.playerCamera != null){ + Vector3d eyePosition = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); + Set instancedEntities = Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED); + for(Entity entity : instancedEntities){ + //set priority equal to distance + Vector3d entityPosition = EntityUtils.getPosition(entity); + int priority = (int)entityPosition.distance(eyePosition); + InstancedActor.getInstancedActor(entity).setPriority(priority); + } } + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java b/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java index 0e3a4c75..df09b9e6 100644 --- a/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java +++ b/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java @@ -1,5 +1,6 @@ package electrosphere.client.scene; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -113,13 +114,19 @@ public class ClientSceneWrapper { * Destroys all entities outside simulation range */ public void destroyEntitiesOutsideSimRange(){ - double cullRadius = Globals.drawCellManager.getDrawRadius() + ServerTerrainChunk.CHUNK_DIMENSION; - for(Entity entity : scene.getEntityList()){ - Vector3d position = EntityUtils.getPosition(entity); - if(Globals.playerEntity != null && EntityUtils.getPosition(Globals.playerEntity).distance(position) > cullRadius){ - EntityUtils.cleanUpEntity(entity); - } - } + Globals.profiler.beginCpuSample("destroyEntitiesOutsideSimRange"); + // if(Globals.drawCellManager != null && Globals.playerEntity != null){ + // double cullRadius = Globals.drawCellManager.getDrawRadius() + ServerTerrainChunk.CHUNK_DIMENSION; + // Vector3d playerPosition = EntityUtils.getPosition(Globals.playerEntity); + // List entityList = scene.getEntityList(); + // for(Entity entity : entityList){ + // Vector3d position = EntityUtils.getPosition(entity); + // if(playerPosition.distance(position) > cullRadius){ + // EntityUtils.cleanUpEntity(entity); + // } + // } + // } + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/client/sim/ClientFunctions.java b/src/main/java/electrosphere/client/sim/ClientFunctions.java deleted file mode 100644 index 3726d5b9..00000000 --- a/src/main/java/electrosphere/client/sim/ClientFunctions.java +++ /dev/null @@ -1,86 +0,0 @@ -package electrosphere.client.sim; - -import electrosphere.client.fluid.manager.ClientFluidManager; -import electrosphere.client.instancing.InstanceUpdater; -import electrosphere.client.terrain.manager.ClientTerrainManager; -import electrosphere.engine.Globals; -import electrosphere.entity.EntityUtils; - -import org.joml.Vector3d; - -/** - * - * @author amaterasu - */ -public class ClientFunctions { - - static Vector3d oldPlayerCharacterPosition = new Vector3d(); - static Vector3d newPlayerCharacterPosition = new Vector3d(); - - public static void runBeforeSimulationFunctions(){ - //cell tracking values - if(Globals.playerEntity != null){ - oldPlayerCharacterPosition = new Vector3d(EntityUtils.getPosition(Globals.playerEntity)); - } - //process all server synchronization messages - Globals.clientSynchronizationManager.processMessages(); - } - - public static void runClientFunctions(){ - ClientTerrainManager.generateTerrainChunkGeometry(); - ClientFluidManager.generateFluidChunkGeometry(); - updateSkyboxPos(); - Globals.clientSceneWrapper.destroyEntitiesOutsideSimRange(); - InstanceUpdater.updateInstancedActorPriority(); - Globals.cameraHandler.updateGlobalCamera(); - // updateCellManager(); - } - - static void updateSkyboxPos(){ - if(Globals.skybox != null && Globals.playerEntity != null){ -// Vector3f skyboxPos = EntityUtils.getPosition(Globals.skybox); -// -// Vector3f playerCameraPos = EntityUtils.getPosition(Globals.playerCamera); -// if(skyboxPos != null && playerCameraPos != null){ -// skyboxPos.set(playerCameraPos); -// } - EntityUtils.getPosition(Globals.skybox).set(EntityUtils.getPosition(Globals.playerEntity)); - } - } - - public static void loadTerrain(){ - if(Globals.clientTerrainManager != null){ - Globals.clientTerrainManager.handleMessages(); - updateTerrainCellManager(); - } - if(Globals.clientFluidManager != null){ - Globals.clientFluidManager.handleMessages(); - updateFluidCellManager(); - } - } - - static void updateTerrainCellManager(){ - /// - /// C L I E N T C E L L M A N A G E R - /// - if(Globals.drawCellManager != null && Globals.clientWorldData != null){ - if(Globals.playerEntity != null){ - newPlayerCharacterPosition = EntityUtils.getPosition(Globals.playerEntity); - } - //Cell manager do your things - Globals.drawCellManager.calculateDeltas(newPlayerCharacterPosition); - Globals.drawCellManager.update(); - } - } - - static void updateFluidCellManager(){ - //fluid work - if(Globals.fluidCellManager != null && Globals.clientWorldData != null){ - if(Globals.playerEntity != null){ - newPlayerCharacterPosition = EntityUtils.getPosition(Globals.playerEntity); - } - Globals.fluidCellManager.calculateDeltas(newPlayerCharacterPosition); - Globals.fluidCellManager.update(); - } - } -} diff --git a/src/main/java/electrosphere/client/sim/ClientSimulation.java b/src/main/java/electrosphere/client/sim/ClientSimulation.java index ac9835e2..c69ac08c 100644 --- a/src/main/java/electrosphere/client/sim/ClientSimulation.java +++ b/src/main/java/electrosphere/client/sim/ClientSimulation.java @@ -1,6 +1,11 @@ package electrosphere.client.sim; +import org.joml.Vector3d; + +import electrosphere.client.fluid.manager.ClientFluidManager; +import electrosphere.client.instancing.InstanceUpdater; import electrosphere.client.targeting.crosshair.Crosshair; +import electrosphere.client.terrain.manager.ClientTerrainManager; import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsUtils; import electrosphere.engine.Globals; @@ -17,35 +22,66 @@ import electrosphere.renderer.actor.Actor; public class ClientSimulation { + //if true, is ready to simulate boolean isReady = false; + + //if true, should load terrain boolean loadTerrain = false; + + //used for tracking different in player position between frames (principally for draw cell manager) + Vector3d newPlayerCharacterPosition = new Vector3d(); + /** + * Constructor + */ public ClientSimulation(){ isReady = false; } + /** + * Main simulation function + */ public void simulate(){ + Globals.profiler.beginCpuSample("simulate"); + + //load terrain + if(isLoadingTerrain()){ + loadTerrain(); + } + + //process all server synchronization messages + Globals.profiler.beginCpuSample("clientSynchronizationManager.processMessages"); + Globals.clientSynchronizationManager.processMessages(); + Globals.profiler.endCpuSample(); + //simulate bullet physics engine step Globals.clientSceneWrapper.getCollisionEngine().simulatePhysics((float)Globals.timekeeper.getSimFrameTime()); Globals.clientSceneWrapper.getCollisionEngine().updateDynamicObjectTransforms(); //update actor animations + Globals.profiler.beginCpuSample("update actor animations"); for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){ Actor currentActor = EntityUtils.getActor(currentEntity); if(currentActor.isPlayingAnimation()){ currentActor.incrementAnimationTime((float)Globals.timekeeper.getSimFrameTime()); } } + Globals.profiler.endCpuSample(); //make items play idle animation + Globals.profiler.beginCpuSample("item animations"); for(Entity item : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM)){ ItemUtils.updateItemActorAnimation(item); } + Globals.profiler.endCpuSample(); //particle state updates + Globals.profiler.beginCpuSample("particle state updates"); for(Entity particle : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){ ParticleUtils.makeParticleBillboardFaceCamera(particle); } + Globals.profiler.endCpuSample(); //update attached entity positions AttachUtils.clientUpdateAttachedEntityPositions(); //update hitbox positions + Globals.profiler.beginCpuSample("Hitbox updates"); for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){ HitboxUtils.clientUpdatePosition(currentHitbox); } @@ -55,11 +91,14 @@ public class ClientSimulation { HitboxUtils.clientCollideEntities(currentHitbox); } } + Globals.profiler.endCpuSample(); //update audio engine + Globals.profiler.beginCpuSample("audio engine update"); if(Globals.audioEngine!=null){ Globals.audioEngine.update(); Globals.virtualAudioSourceManager.update((float)Globals.timekeeper.getSimFrameTime()); } + Globals.profiler.endCpuSample(); //update foliage Globals.clientFoliageManager.update(); //tally collidables and offset position accordingly @@ -68,16 +107,88 @@ public class ClientSimulation { // tree.simulate(Main.deltaFrames); // } //targeting crosshair + Globals.profiler.beginCpuSample("crosshair update"); Crosshair.checkTargetable(); Crosshair.updateTargetCrosshairPosition(); + Globals.profiler.endCpuSample(); //simulate behavior trees Globals.clientSceneWrapper.getScene().simulateBehaviorTrees((float)Globals.timekeeper.getSimFrameTime()); //sum collidable impulses + Globals.profiler.beginCpuSample("collidable logic"); for(Entity collidable : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){ ClientCollidableTree.getClientCollidableTree(collidable).simulate((float)Globals.timekeeper.getSimFrameTime()); } //clear collidable impulse lists Globals.clientSceneWrapper.getCollisionEngine().clearCollidableImpulseLists(); + Globals.profiler.endCpuSample(); + + //wrap up functions + runClientFunctions(); + + Globals.profiler.endCpuSample(); + } + + public void runClientFunctions(){ + Globals.profiler.beginCpuSample("client functions"); + ClientTerrainManager.generateTerrainChunkGeometry(); + ClientFluidManager.generateFluidChunkGeometry(); + updateSkyboxPos(); + Globals.clientSceneWrapper.destroyEntitiesOutsideSimRange(); + InstanceUpdater.updateInstancedActorPriority(); + Globals.cameraHandler.updateGlobalCamera(); + // updateCellManager(); + Globals.profiler.endCpuSample(); + } + + + /** + * Updates the skybox position to center on the player + */ + void updateSkyboxPos(){ + Globals.profiler.beginCpuSample("updateSkyboxPos"); + if(Globals.skybox != null && Globals.playerEntity != null){ + EntityUtils.getPosition(Globals.skybox).set(EntityUtils.getPosition(Globals.playerEntity)); + } + Globals.profiler.endCpuSample(); + } + + /** + * Loads terrain that is in queue + */ + public void loadTerrain(){ + Globals.profiler.beginCpuSample("load terrain"); + if(Globals.clientTerrainManager != null){ + Globals.clientTerrainManager.handleMessages(); + updateTerrainCellManager(); + } + if(Globals.clientFluidManager != null){ + Globals.clientFluidManager.handleMessages(); + updateFluidCellManager(); + } + Globals.profiler.endCpuSample(); + } + + /** + * Updates the terrain cell manager (specifically position handling) + */ + void updateTerrainCellManager(){ + /// + /// C L I E N T C E L L M A N A G E R + /// + if(Globals.drawCellManager != null && Globals.clientWorldData != null){ + //Cell manager do your things + Globals.drawCellManager.update(); + } + } + + /** + * Updates the fluid cell manager (specifically position handling) + */ + void updateFluidCellManager(){ + //fluid work + if(Globals.fluidCellManager != null && Globals.clientWorldData != null){ + Globals.fluidCellManager.update(); + } } /** diff --git a/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java b/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java index ebb2768b..e6bd33e5 100644 --- a/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java +++ b/src/main/java/electrosphere/client/terrain/cells/DrawCellManager.java @@ -260,9 +260,8 @@ public class DrawCellManager { /** * Calculates whether the position of the player has changed and if so, invalidates and cleans up cells accordingly - * @param position The position of the player entity on current frame */ - public void calculateDeltas(Vector3d position){ + private void calculateDeltas(){ //check if any not requested cells no longer need to be requested clearOutOfBoundsCells(); //check if any cells should be added @@ -342,6 +341,7 @@ public class DrawCellManager { * Updates cells that need updating in this manager */ public void update(){ + calculateDeltas(); if(containsUnrequestedCell() && !containsUndrawableCell()){ updateUnrequestedCell(); } else if(containsUndrawableCell()){ diff --git a/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java b/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java index 972d4eec..0b1b53a8 100644 --- a/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java +++ b/src/main/java/electrosphere/client/terrain/manager/ClientTerrainManager.java @@ -155,11 +155,13 @@ public class ClientTerrainManager { * Pushes all terrain data in queue to the gpu and registers the resulting models */ public static void generateTerrainChunkGeometry(){ + Globals.profiler.beginCpuSample("generateTerrainChunkGeometry"); for(TerrainChunkGenQueueItem queueItem : terrainChunkGenerationQueue){ Model terrainModel = TerrainChunkModelGeneration.generateTerrainModel(queueItem.getData()); Globals.assetManager.registerModelToSpecificString(terrainModel, queueItem.getPromisedHash()); } terrainChunkGenerationQueue.clear(); + Globals.profiler.endCpuSample(); } /** diff --git a/src/main/java/electrosphere/collision/CollisionBodyCreation.java b/src/main/java/electrosphere/collision/CollisionBodyCreation.java index 815c7b4f..b1d4434d 100644 --- a/src/main/java/electrosphere/collision/CollisionBodyCreation.java +++ b/src/main/java/electrosphere/collision/CollisionBodyCreation.java @@ -100,8 +100,14 @@ public class CollisionBodyCreation { collisionEngine.setGravityMode(body, gravityMode); } - public static void addMass(CollisionEngine collisionEngine, DBody body){ - + /** + * Sets the offset position of the first geometry in a given body + * @param collisionEngine The collision engine + * @param body The body + * @param offsetPosition The position to offset the first geometry by + */ + public static void setOffsetPosition(CollisionEngine collisionEngine, DBody body, Vector3d offsetPosition){ + collisionEngine.setOffsetPosition(body, offsetPosition); } diff --git a/src/main/java/electrosphere/collision/CollisionEngine.java b/src/main/java/electrosphere/collision/CollisionEngine.java index 6d230da3..1c939179 100644 --- a/src/main/java/electrosphere/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/collision/CollisionEngine.java @@ -24,6 +24,7 @@ import org.joml.Vector3f; import org.joml.Vector4d; import org.ode4j.math.DMatrix3; import org.ode4j.math.DVector3; +import org.ode4j.math.DVector3C; import org.ode4j.math.DVector4; import org.ode4j.ode.DBody; import org.ode4j.ode.DBox; @@ -212,17 +213,22 @@ public class CollisionEngine { * @param time The time to increment the physics simulation by */ public void simulatePhysics(float time){ + Globals.profiler.beginCpuSample("physics"); spaceLock.acquireUninterruptibly(); + Globals.profiler.beginCpuSample("collide"); OdeHelper.spaceCollide(space, 0, nearCallback); + Globals.profiler.endCpuSample(); // space.collide2(space, collisionWorldData, nearCallback); //simulate physics + Globals.profiler.beginCpuSample("step physics"); world.quickStep(ENGINE_STEP_SIZE); + Globals.profiler.endCpuSample(); // remove all contact joints contactgroup.empty(); spaceLock.release(); - + Globals.profiler.endCpuSample(); } /** @@ -373,6 +379,7 @@ public class CollisionEngine { * Main function to resynchronize entity positions with physics object positions after impulses are applied. */ public void updateDynamicObjectTransforms(){ + Globals.profiler.beginCpuSample("updateDynamicObjectTransforms"); spaceLock.acquireUninterruptibly(); for(Collidable collidable : collidableList){ if(collidable.getParentTracksCollidable()){ @@ -387,6 +394,7 @@ public class CollisionEngine { } } spaceLock.release(); + Globals.profiler.endCpuSample(); } public void registerCollisionObject(DBody body, Collidable collidable){ @@ -737,7 +745,20 @@ public class CollisionEngine { * @param gravityMode the gravity mode */ protected void setGravityMode(DBody body, boolean gravityMode){ + spaceLock.acquireUninterruptibly(); body.setGravityMode(gravityMode); + spaceLock.release(); + } + + /** + * Sets the offset position of the first geometry in the body + * @param body The body + * @param offsetVector The offset position + */ + protected void setOffsetPosition(DBody body, Vector3d offsetVector){ + spaceLock.acquireUninterruptibly(); + body.getGeomIterator().next().setOffsetPosition(offsetVector.x,offsetVector.y,offsetVector.z); + spaceLock.release(); } } diff --git a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java index 64601022..928b76d6 100644 --- a/src/main/java/electrosphere/collision/PhysicsEntityUtils.java +++ b/src/main/java/electrosphere/collision/PhysicsEntityUtils.java @@ -45,8 +45,11 @@ public class PhysicsEntityUtils { physicsTemplate.getDimension2(), Collidable.TYPE_CREATURE_BIT ); - DCylinder cylinder = (DCylinder)rigidBody.getGeomIterator().next(); - cylinder.setOffsetPosition(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()); + CollisionBodyCreation.setOffsetPosition( + Globals.clientSceneWrapper.getCollisionEngine(), + rigidBody, + new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()) + ); collidable = new Collidable(rVal, Collidable.TYPE_CREATURE); ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); @@ -114,8 +117,11 @@ public class PhysicsEntityUtils { physicsTemplate.getDimension2(), Collidable.TYPE_CREATURE_BIT ); - DCylinder cylinder = (DCylinder)rigidBody.getGeomIterator().next(); - cylinder.setOffsetPosition(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()); + CollisionBodyCreation.setOffsetPosition( + realm.getCollisionEngine(), + rigidBody, + new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ()) + ); collidable = new Collidable(rVal, Collidable.TYPE_CREATURE); ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); diff --git a/src/main/java/electrosphere/controls/CameraHandler.java b/src/main/java/electrosphere/controls/CameraHandler.java index ef7817ef..3a637ac1 100644 --- a/src/main/java/electrosphere/controls/CameraHandler.java +++ b/src/main/java/electrosphere/controls/CameraHandler.java @@ -44,67 +44,71 @@ public class CameraHandler { } public void updateGlobalCamera(){ - cameraSpeed = 2.5f * (float)Globals.timekeeper.getMostRecentRawFrametime(); + Globals.profiler.beginCpuSample("updateGlobalCamera"); + if(Globals.playerCamera != null){ + cameraSpeed = 2.5f * (float)Globals.timekeeper.getMostRecentRawFrametime(); - if(Crosshair.getCrosshairActive()){ - - // if(Globals.playerCharacter != null){ - // Vector3d charPos = EntityUtils.getPosition(Globals.playerCharacter); - // CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f((float)charPos.x,(float)charPos.y,(float)charPos.z)); - // } - - Vector3d characterPos = EntityUtils.getPosition(Globals.playerEntity); - Vector3d targetPos = Crosshair.getTargetPosition(); - Vector3d diffed = new Vector3d(targetPos).sub(characterPos).mul(-1).normalize(); - cameraRotationVector.set((float)diffed.x, 0.5f, (float)diffed.z).normalize(); - - yaw = (float)Math.toDegrees(Math.atan2(diffed.z, diffed.x)); - - CameraEntityUtils.setCameraPitch(Globals.playerCamera, pitch); - CameraEntityUtils.setCameraYaw(Globals.playerCamera, yaw); - - } else { - CameraEntityUtils.setCameraPitch(Globals.playerCamera, pitch); - CameraEntityUtils.setCameraYaw(Globals.playerCamera, yaw); + if(Crosshair.getCrosshairActive()){ + + // if(Globals.playerCharacter != null){ + // Vector3d charPos = EntityUtils.getPosition(Globals.playerCharacter); + // CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f((float)charPos.x,(float)charPos.y,(float)charPos.z)); + // } + + Vector3d characterPos = EntityUtils.getPosition(Globals.playerEntity); + Vector3d targetPos = Crosshair.getTargetPosition(); + Vector3d diffed = new Vector3d(targetPos).sub(characterPos).mul(-1).normalize(); + cameraRotationVector.set((float)diffed.x, 0.5f, (float)diffed.z).normalize(); + + yaw = (float)Math.toDegrees(Math.atan2(diffed.z, diffed.x)); + + CameraEntityUtils.setCameraPitch(Globals.playerCamera, pitch); + CameraEntityUtils.setCameraYaw(Globals.playerCamera, yaw); + + } else { + CameraEntityUtils.setCameraPitch(Globals.playerCamera, pitch); + CameraEntityUtils.setCameraYaw(Globals.playerCamera, yaw); - // System.out.println(pitch); - // if(Globals.playerCharacter != null){ - // Vector3d charPos = EntityUtils.getPosition(Globals.playerCharacter); - // CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f((float)charPos.x,(float)charPos.y,(float)charPos.z)); - // } + // System.out.println(pitch); + // if(Globals.playerCharacter != null){ + // Vector3d charPos = EntityUtils.getPosition(Globals.playerCharacter); + // CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f((float)charPos.x,(float)charPos.y,(float)charPos.z)); + // } - Quaternionf pitchQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(1,0,0), -pitch); - Quaternionf yawQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(0,1,0), -yaw); - // float yawRad = yaw / 180.0f * (float)Math.PI; - // float pitchRad = pitch / 180.0f * (float)Math.PI; - // float rollRad = 0.0f; - // pitchQuat.mul(yawQuat); - cameraRotationVector = pitchQuat.transform(new Vector3f(0,0,1)); - cameraRotationVector = yawQuat.transform(cameraRotationVector); - cameraRotationVector.normalize(); + Quaternionf pitchQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(1,0,0), -pitch); + Quaternionf yawQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(0,1,0), -yaw); + // float yawRad = yaw / 180.0f * (float)Math.PI; + // float pitchRad = pitch / 180.0f * (float)Math.PI; + // float rollRad = 0.0f; + // pitchQuat.mul(yawQuat); + cameraRotationVector = pitchQuat.transform(new Vector3f(0,0,1)); + cameraRotationVector = yawQuat.transform(cameraRotationVector); + cameraRotationVector.normalize(); - // cameraRotationVector.x = 0 + (float) Math.cos(yaw / 180.0f * Math.PI) * 1; - // cameraRotationVector.y = 0 + (float) Math.sin(pitch / 180.0f * Math.PI) * 1; - // cameraRotationVector.z = 0 + (float) Math.sin(yaw / 180.0f * Math.PI) * 1; - // cameraRotationVector.normalize(); - // System.out.println(yaw + " " + pitch); + // cameraRotationVector.x = 0 + (float) Math.cos(yaw / 180.0f * Math.PI) * 1; + // cameraRotationVector.y = 0 + (float) Math.sin(pitch / 180.0f * Math.PI) * 1; + // cameraRotationVector.z = 0 + (float) Math.sin(yaw / 180.0f * Math.PI) * 1; + // cameraRotationVector.normalize(); + // System.out.println(yaw + " " + pitch); + } + if(trackPlayerEntity && Globals.playerEntity != null){ + Vector3d entityPos = EntityUtils.getPosition(Globals.playerEntity); + CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f((float)entityPos.x,(float)entityPos.y,(float)entityPos.z).add(CameraEntityUtils.getOrbitalCameraRadialOffset(Globals.playerCamera))); + } + //update view matrix offset + float xFactor = (float)Math.cos(yaw / 180.0f * Math.PI); + float yFactor = (float)Math.sin(yaw / 180.0f * Math.PI); + Vector3f radialOffset = CameraEntityUtils.getOrbitalCameraRadialOffset(Globals.playerCamera); + Vector3f trueOffset = new Vector3f(radialOffset).mul(xFactor,1.0f,yFactor); + CameraEntityUtils.setOrbitalCameraRadialOffset(Globals.playerCamera, trueOffset); + // float cam_Player_Orbit_Magnitude = CameraEntityUtils.getCameraOrbitRadius(Globals.playerCamera); + cameraRotationVector.mul(CameraEntityUtils.getOrbitalCameraDistance(Globals.playerCamera)); + CameraEntityUtils.setCameraEye(Globals.playerCamera, cameraRotationVector); + + Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera); } - if(trackPlayerEntity && Globals.playerEntity != null){ - Vector3d entityPos = EntityUtils.getPosition(Globals.playerEntity); - CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f((float)entityPos.x,(float)entityPos.y,(float)entityPos.z).add(CameraEntityUtils.getOrbitalCameraRadialOffset(Globals.playerCamera))); - } - //update view matrix offset - float xFactor = (float)Math.cos(yaw / 180.0f * Math.PI); - float yFactor = (float)Math.sin(yaw / 180.0f * Math.PI); - Vector3f radialOffset = CameraEntityUtils.getOrbitalCameraRadialOffset(Globals.playerCamera); - Vector3f trueOffset = new Vector3f(radialOffset).mul(xFactor,1.0f,yFactor); - CameraEntityUtils.setOrbitalCameraRadialOffset(Globals.playerCamera, trueOffset); - // float cam_Player_Orbit_Magnitude = CameraEntityUtils.getCameraOrbitRadius(Globals.playerCamera); - cameraRotationVector.mul(CameraEntityUtils.getOrbitalCameraDistance(Globals.playerCamera)); - CameraEntityUtils.setCameraEye(Globals.playerCamera, cameraRotationVector); - - Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera); + Globals.profiler.endCpuSample(); } public float getYaw(){ diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index c8871600..5cac0faa 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -30,6 +30,7 @@ import electrosphere.controls.MouseCallback; import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.engine.assetmanager.AssetManager; import electrosphere.engine.loadingthreads.LoadingThread; +import electrosphere.engine.profiler.Profiler; import electrosphere.engine.time.Timekeeper; import electrosphere.entity.Entity; import electrosphere.entity.Scene; @@ -110,6 +111,17 @@ public class Globals { //main debug flag //current enables imgui debug menu or not public static boolean ENGINE_DEBUG = true; + + + // + //Profiler + // + public static Profiler profiler; + + // + //Garbage Collection + // + public static boolean EXPLICIT_GC = true; // @@ -440,6 +452,8 @@ public class Globals { } //client synchronization manager clientSynchronizationManager = new ClientSynchronizationManager(); + //profiler + profiler = new Profiler(); } public static void initDefaultAudioResources(){ diff --git a/src/main/java/electrosphere/engine/Main.java b/src/main/java/electrosphere/engine/Main.java index ca9695aa..92cbbbf9 100644 --- a/src/main/java/electrosphere/engine/Main.java +++ b/src/main/java/electrosphere/engine/Main.java @@ -1,6 +1,5 @@ package electrosphere.engine; -import static org.lwjgl.glfw.GLFW.glfwGetTime; import static org.lwjgl.glfw.GLFW.glfwTerminate; import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose; @@ -11,10 +10,10 @@ import org.ode4j.ode.OdeHelper; import electrosphere.audio.AudioEngine; import electrosphere.audio.VirtualAudioSourceManager; -import electrosphere.client.sim.ClientFunctions; import electrosphere.controls.ControlHandler; import electrosphere.engine.cli.CLIParser; import electrosphere.engine.loadingthreads.LoadingThread; +import electrosphere.engine.time.Timekeeper; import electrosphere.game.config.UserSettings; import electrosphere.game.server.world.MacroData; import electrosphere.logger.LoggerInterface; @@ -214,42 +213,27 @@ public class Main { public static void mainLoop(long maxFrames){ double functionTrackTimeStart = 0; - boolean captureFramerate = false; //main loop while (running) { + Globals.profiler.beginRootCpuSample("frame"); LoggerInterface.loggerEngine.DEBUG("Begin Main Loop Frame"); - //sets whether to capture framerates of current frame - captureFramerate = Globals.timekeeper.getNumberOfRenderFramesElapsed() % 10 == 0; - // //Update timekeeper // Globals.timekeeper.update(); - - - // - // track total frametiime in debug graph - // - if(captureFramerate){ - ImGuiWindowMacros.addGlobalFramerateDatapoint("totalframerate",Globals.timekeeper.getMostRecentRawFrametime() * 1000); - } /// /// A S S E T M A N A G E R S T U F F /// - if(!Globals.HEADLESS && captureFramerate){ - functionTrackTimeStart = glfwGetTime(); - } if(Globals.RUN_CLIENT){ + Globals.profiler.beginCpuSample("Load Assets"); LoggerInterface.loggerEngine.DEBUG("Begin load assets"); Globals.assetManager.loadAssetsInQueue(); - } - if(!Globals.HEADLESS && captureFramerate){ - ImGuiWindowMacros.addGlobalFramerateDatapoint("assetLoad",(glfwGetTime()-functionTrackTimeStart)*1000); + Globals.profiler.endCpuSample(); } @@ -258,23 +242,14 @@ public class Main { /// /// C L I E N T N E T W O R K I N G S T U F F /// - if(!Globals.HEADLESS && captureFramerate){ - functionTrackTimeStart = glfwGetTime(); - } //Why is this its own function? Just to get the networking code out of main() if(Globals.clientConnection != null){ + Globals.profiler.beginCpuSample("Client networking"); LoggerInterface.loggerEngine.DEBUG("Begin parse client messages"); Globals.clientConnection.parseMessages(); + Globals.profiler.endCpuSample(); } - if(!Globals.HEADLESS && captureFramerate){ - ImGuiWindowMacros.addGlobalFramerateDatapoint("clientNetwork",(glfwGetTime()-functionTrackTimeStart)*1000); - } - - //handle framestep - if(framestep == 1){ - framestep = 0; - } /// @@ -282,15 +257,11 @@ public class Main { /// //Poll controls if(Globals.RUN_CLIENT){ - if(!Globals.HEADLESS && captureFramerate){ - functionTrackTimeStart = glfwGetTime(); - } + Globals.profiler.beginCpuSample("Poll Controls"); LoggerInterface.loggerEngine.DEBUG("Begin recapture screen"); Globals.controlHandler.pollControls(); RenderingEngine.recaptureIfNecessary(); - if(!Globals.HEADLESS && captureFramerate){ - ImGuiWindowMacros.addGlobalFramerateDatapoint("controls",(glfwGetTime()-functionTrackTimeStart)*1000); - } + Globals.profiler.endCpuSample(); } @@ -299,28 +270,26 @@ public class Main { /// M A I N S I M U L A T I O N I N N E R L O O P /// - while(Globals.timekeeper.pullFromAccumulator()){ + int simFrameHardcapCounter = 0; + while(Globals.timekeeper.pullFromAccumulator() && framestep > 0 && simFrameHardcapCounter < Timekeeper.SIM_FRAME_HARDCAP){ + + //sim frame hard cap counter increment + simFrameHardcapCounter++; + //handle framestep + if(framestep == 1){ + framestep = 0; + } + + + /// /// C L I E N T S I M U L A T I O N S T U F F /// LoggerInterface.loggerEngine.DEBUG("Begin client simulation"); - if(!Globals.HEADLESS && captureFramerate){ - functionTrackTimeStart = glfwGetTime(); - } - if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){ - ClientFunctions.runBeforeSimulationFunctions(); - } - if(Globals.clientSimulation != null && Globals.clientSimulation.isLoadingTerrain() && framestep > 0){ - ClientFunctions.loadTerrain(); - } - if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){ + if(Globals.clientSimulation != null){ + Globals.profiler.beginCpuSample("Client simulation"); Globals.clientSimulation.simulate(); - } - if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){ - ClientFunctions.runClientFunctions(); - } - if(!Globals.HEADLESS && captureFramerate){ - ImGuiWindowMacros.addGlobalFramerateDatapoint("clientsim",(glfwGetTime()-functionTrackTimeStart)*1000); + Globals.profiler.endCpuSample(); } @@ -336,10 +305,8 @@ public class Main { /// /// S E R V E R M I C R O S I M U L A T I O N /// + Globals.profiler.beginCpuSample("Server simulation"); LoggerInterface.loggerEngine.DEBUG("Begin server micro simulation"); - if(!!Globals.HEADLESS && captureFramerate){ - functionTrackTimeStart = glfwGetTime(); - } if(Globals.realmManager != null){ Globals.realmManager.simulate(); } @@ -348,12 +315,10 @@ public class Main { /// M A C R O S I M U L A T I O N S T U F F /// LoggerInterface.loggerEngine.DEBUG("Begin server macro simulation"); - if(Globals.macroSimulation != null && Globals.macroSimulation.isReady() && framestep > 0){ + if(Globals.macroSimulation != null && Globals.macroSimulation.isReady()){ Globals.macroSimulation.simulate(); } - if(!Globals.HEADLESS && captureFramerate){ - ImGuiWindowMacros.addGlobalFramerateDatapoint("serversim",(glfwGetTime()-functionTrackTimeStart)*1000); - } + Globals.profiler.endCpuSample(); } @@ -363,14 +328,10 @@ public class Main { /// M A I N R E N D E R F U N C T I O N /// LoggerInterface.loggerEngine.DEBUG("Begin rendering call"); - if(!Globals.HEADLESS && captureFramerate){ - functionTrackTimeStart = glfwGetTime(); - } if(Globals.RUN_CLIENT && !Globals.HEADLESS){ + Globals.profiler.beginCpuSample("render"); Globals.renderingEngine.drawScreen(); - } - if(!Globals.HEADLESS && captureFramerate){ - ImGuiWindowMacros.addGlobalFramerateDatapoint("render",(glfwGetTime()-functionTrackTimeStart)*1000); + Globals.profiler.endCpuSample(); } @@ -379,7 +340,11 @@ public class Main { /// /// G A R B A G E C H E C K /// - System.gc(); + Globals.profiler.beginCpuSample("gc"); + if(Globals.EXPLICIT_GC){ + System.gc(); + } + Globals.profiler.endCpuSample(); @@ -407,23 +372,28 @@ public class Main { // // C L E A N U P T I M E V A R I A B L E S // + Globals.profiler.beginCpuSample("sleep"); if(Globals.timekeeper.getMostRecentRawFrametime() < targetFramePeriod){ sleep((int)(1000.0 * (targetFramePeriod - Globals.timekeeper.getMostRecentRawFrametime()))); } else { sleep(1); } + Globals.profiler.endCpuSample(); Globals.timekeeper.numberOfRenderedFrames++; - if(maxFrames > 0 && Globals.timekeeper.numberOfRenderedFrames > maxFrames){ running = false; } + + // + // End main loop + // LoggerInterface.loggerEngine.DEBUG("End Main Loop Frame"); + Globals.profiler.endCpuSample(); } - LoggerInterface.loggerEngine.ERROR("ENGINE SHUTDOWN", new Exception()); - + LoggerInterface.loggerEngine.WARNING("ENGINE SHUTDOWN"); // // S H U T D O W N // diff --git a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java index abb3c1e8..dd9be8a0 100644 --- a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java +++ b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java @@ -5,6 +5,7 @@ import electrosphere.collision.CollisionBodyCreation; import electrosphere.collision.CollisionEngine; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; +import electrosphere.logger.LoggerInterface; import electrosphere.renderer.actor.ActorShaderMask; import electrosphere.renderer.buffer.HomogenousInstancedArray; import electrosphere.renderer.buffer.HomogenousUniformBuffer; @@ -303,6 +304,8 @@ public class AssetManager { AudioBuffer rVal = null; if(audioLoadedIntoMemory.containsKey(path)){ rVal = audioLoadedIntoMemory.get(path); + } else { + LoggerInterface.loggerAudio.WARNING("Failed to find audio " + path); } return rVal; } diff --git a/src/main/java/electrosphere/engine/profiler/Profiler.java b/src/main/java/electrosphere/engine/profiler/Profiler.java new file mode 100644 index 00000000..b6dac7b0 --- /dev/null +++ b/src/main/java/electrosphere/engine/profiler/Profiler.java @@ -0,0 +1,72 @@ +package electrosphere.engine.profiler; + +import java.nio.IntBuffer; + +import org.lwjgl.PointerBuffer; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; +import org.lwjgl.util.remotery.Remotery; + +/** + * A profiler for monitoring engine performance + */ +public class Profiler { + + //controls whether to profile or not + public static final boolean PROFILE = true; + + //pointer to the global instance + long pointer = -1; + + /** + * Creates the profiler + */ + public Profiler(){ + try(MemoryStack stack = MemoryStack.stackPush()){ + PointerBuffer allocBuffer = stack.mallocPointer(1); + Remotery.rmt_CreateGlobalInstance(allocBuffer); + pointer = allocBuffer.get(); + } + } + + /** + * Begins a CPU sample + * @param sampleName The name of the sample + */ + public void beginCpuSample(String sampleName){ + if(PROFILE){ + Remotery.rmt_BeginCPUSample(sampleName, Remotery.RMTSF_None, null); + } + } + + /** + * Begins an aggregate CPU sample (must create a regular cpu sample of same type outside function this is inside of to encapsule all calls to aggregate) + * @param sampleName The name of the sample + */ + public void beginAggregateCpuSample(String sampleName){ + if(PROFILE){ + Remotery.rmt_BeginCPUSample(sampleName, Remotery.RMTSF_Aggregate, null); + } + } + + /** + * Begins a Root CPU sample (will assert if another sample is not ended before this one) + * @param sampleName The name of the root sample + */ + public void beginRootCpuSample(String sampleName){ + if(PROFILE){ + Remotery.rmt_BeginCPUSample(sampleName, Remotery.RMTSF_Root, null); + } + } + + /** + * Ends a CPU sample + * @param sampleName The name of the sample + */ + public void endCpuSample(){ + if(PROFILE){ + Remotery.rmt_EndCPUSample(); + } + } + +} diff --git a/src/main/java/electrosphere/engine/time/Timekeeper.java b/src/main/java/electrosphere/engine/time/Timekeeper.java index 35c6ef99..96b8338e 100644 --- a/src/main/java/electrosphere/engine/time/Timekeeper.java +++ b/src/main/java/electrosphere/engine/time/Timekeeper.java @@ -30,6 +30,12 @@ public class Timekeeper { //the raw (not simulation) frametime of the most recent frame double mostRecentRawFrametime = 0; + //The maximum amount of time that can overflow (ie cause more than one sim frame/render frame) before the sim frames are tossed out + static double overflowMax = 20; + + //the maximum number of simulation frames that can happen in a row before the main loop immediately skips more + public static final int SIM_FRAME_HARDCAP = 3; + @@ -65,8 +71,8 @@ public class Timekeeper { double newTime = getTime(); double frameTime = newTime - currentTime; mostRecentRawFrametime = frameTime; - if(frameTime > 0.25){ - frameTime = 0.25; + if(frameTime > overflowMax){ + frameTime = overflowMax; } currentTime = newTime; //add to accumulator diff --git a/src/main/java/electrosphere/entity/Scene.java b/src/main/java/electrosphere/entity/Scene.java index 2bc49cb8..11b55083 100644 --- a/src/main/java/electrosphere/entity/Scene.java +++ b/src/main/java/electrosphere/entity/Scene.java @@ -146,9 +146,11 @@ public class Scene { * Simulates all behavior trees stored in the entity manager */ public void simulateBehaviorTrees(float deltaTime){ + Globals.profiler.beginCpuSample("Scene.simulateBehaviorTrees"); for(BehaviorTree tree : behaviorTreeList){ tree.simulate(deltaTime); } + Globals.profiler.endCpuSample(); } /** diff --git a/src/main/java/electrosphere/entity/types/attach/AttachUtils.java b/src/main/java/electrosphere/entity/types/attach/AttachUtils.java index 575de76a..1d0495b6 100644 --- a/src/main/java/electrosphere/entity/types/attach/AttachUtils.java +++ b/src/main/java/electrosphere/entity/types/attach/AttachUtils.java @@ -76,6 +76,17 @@ public class AttachUtils { * Client version of attachment update functions */ public static void clientUpdateAttachedEntityPositions(){ + Globals.profiler.beginCpuSample("AttachUtils.clientUpdateAttachedEntityPositions"); + updateBoneAttachments(); + updateNonBoneAttachments(); + Globals.profiler.endCpuSample(); + } + + /** + * Updates entities attached to bones + */ + private static void updateBoneAttachments(){ + Globals.profiler.beginCpuSample("AttachUtils.updateBoneAttachments"); //update entities attached to bones of other entities for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){ Entity parent; @@ -111,13 +122,21 @@ public class AttachUtils { EntityUtils.getPosition(currentEntity).set(new Vector3d(parentPosition).add(positionOffset)); } } + Globals.profiler.endCpuSample(); + } + private static void updateNonBoneAttachments(){ + Globals.profiler.beginCpuSample("AttachUtils.updateNonBoneAttachments"); Matrix4d parentTransform = new Matrix4d().identity(); + Vector3d position = new Vector3d(); + Quaterniond rotation = new Quaterniond(); + Vector3d scaleRaw = new Vector3d(); + Vector3f scale = new Vector3f(); + Entity parent; + Matrix4f transform; //update entities attached to centerpoint + transform of other entities for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.TRANSFORM_ATTACHED)){ - Entity parent; if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){ - Matrix4f transform; if((transform = getTransformOffset(currentEntity))!=null){ //parent objects Vector3d parentPosition = EntityUtils.getPosition(parent); @@ -130,11 +149,10 @@ public class AttachUtils { .scale(parentScale.x,parentScale.y,parentScale.z) .mul(transform); //transform bone space - Vector4d positionRaw = parentTransform.transform(new Vector4d(0,0,0,1)); - Vector3d position = new Vector3d(positionRaw.x,positionRaw.y,positionRaw.z); - Quaterniond rotation = parentTransform.getUnnormalizedRotation(new Quaterniond()).normalize(); - Vector3d scaleRaw = parentTransform.getScale(new Vector3d()); - Vector3f scale = new Vector3f((float)scaleRaw.x,(float)scaleRaw.y,(float)scaleRaw.z); + parentTransform.getTranslation(position); + parentTransform.getUnnormalizedRotation(rotation).normalize(); + parentTransform.getScale(scaleRaw); + scale.set((float)scaleRaw.x,(float)scaleRaw.y,(float)scaleRaw.z); //transform worldspace // position.add(new Vector3d(EntityUtils.getPosition(parent))); //set @@ -144,6 +162,7 @@ public class AttachUtils { } } } + Globals.profiler.endCpuSample(); } @@ -217,7 +236,7 @@ public class AttachUtils { Vector3d parentPosition = EntityUtils.getPosition(parent); Vector3d childPosition = EntityUtils.getPosition(toAttach); Vector3d offset = new Vector3d(childPosition).sub(parentPosition); - Globals.clientSceneWrapper.getScene().registerEntityToTag(toAttach, EntityTags.BONE_ATTACHED); + Globals.clientSceneWrapper.getScene().registerEntityToTag(toAttach, EntityTags.TRANSFORM_ATTACHED); toAttach.putData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED, true); toAttach.putData(EntityDataStrings.ATTACH_PARENT, parent); toAttach.putData(EntityDataStrings.ATTACH_TARGET_BASE, true); diff --git a/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java b/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java index c3b102de..91eccb9a 100644 --- a/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java +++ b/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java @@ -126,8 +126,7 @@ public class ProceduralTree { treeModel.getPhysicsBody().getDimension2(), Collidable.TYPE_STATIC_BIT ); - DCylinder cylinder = (DCylinder)rigidBody.getGeomIterator().next(); - cylinder.setOffsetPosition(0,treeModel.getPhysicsBody().getOffsetY(),0); + CollisionBodyCreation.setOffsetPosition(Globals.clientSceneWrapper.getCollisionEngine(), rigidBody, new Vector3d(0,treeModel.getPhysicsBody().getOffsetY(),0)); CollisionBodyCreation.setKinematic(Globals.clientSceneWrapper.getCollisionEngine(), rigidBody); Collidable collidable = new Collidable(trunkChild, Collidable.TYPE_OBJECT); trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); @@ -393,8 +392,7 @@ public class ProceduralTree { treeModel.getPhysicsBody().getDimension2(), Collidable.TYPE_STATIC_BIT ); - DCylinder cylinder = (DCylinder)rigidBody.getGeomIterator().next(); - cylinder.setOffsetPosition(0,treeModel.getPhysicsBody().getOffsetY(),0); + CollisionBodyCreation.setOffsetPosition(realm.getCollisionEngine(), rigidBody, new Vector3d(0,treeModel.getPhysicsBody().getOffsetY(),0)); CollisionBodyCreation.setKinematic(realm.getCollisionEngine(), rigidBody); Collidable collidable = new Collidable(trunkChild, Collidable.TYPE_FOLIAGE_STATIC); trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); diff --git a/src/main/java/electrosphere/net/client/ClientNetworking.java b/src/main/java/electrosphere/net/client/ClientNetworking.java index 0c049682..c96043c8 100644 --- a/src/main/java/electrosphere/net/client/ClientNetworking.java +++ b/src/main/java/electrosphere/net/client/ClientNetworking.java @@ -176,6 +176,8 @@ public class ClientNetworking implements Runnable{ } + static final int MAX_MESSAGES_PARSED = 1000; + public void parseMessages(){ if(initialized){ while(parser.hasIncomingMessaage()){ @@ -187,7 +189,9 @@ public class ClientNetworking implements Runnable{ //print network message printMessage(message); //do something + Globals.profiler.beginCpuSample("ClientProtocol.handleMessage"); clientProtocol.handleMessage(message); + Globals.profiler.endCpuSample(); } } } diff --git a/src/main/java/electrosphere/net/client/protocol/ClientProtocol.java b/src/main/java/electrosphere/net/client/protocol/ClientProtocol.java index 0a4dc5b9..ae20aa1c 100644 --- a/src/main/java/electrosphere/net/client/protocol/ClientProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/ClientProtocol.java @@ -29,6 +29,7 @@ public class ClientProtocol { boolean hasReceivedWorld = false; public void handleMessage(NetworkMessage message){ + Globals.profiler.beginAggregateCpuSample("ClientProtocol.handleMessage"); switch(message.getType()){ case ENTITY_MESSAGE: EntityProtocol.handleEntityMessage((EntityMessage)message); @@ -58,6 +59,7 @@ public class ClientProtocol { SynchronizationProtocol.handleSynchronizationMessage((SynchronizationMessage)message); break; } + Globals.profiler.endCpuSample(); } // void handleStatusMessage(StatusMessage message){ diff --git a/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java b/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java index 1c1430d2..47fee8be 100644 --- a/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java @@ -21,6 +21,7 @@ import electrosphere.util.Utilities; public class EntityProtocol { protected static void handleEntityMessage(EntityMessage message){ + Globals.profiler.beginCpuSample("EntityProtocol.handleEntityMessage"); LoggerInterface.loggerNetworking.DEBUG("Parse entity message of type " + message.getMessageSubtype()); Entity newlySpawnedEntity; switch(message.getMessageSubtype()){ @@ -122,6 +123,7 @@ public class EntityProtocol { Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID()); } break; } + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/net/client/protocol/PlayerProtocol.java b/src/main/java/electrosphere/net/client/protocol/PlayerProtocol.java index 792db582..4a06e48d 100644 --- a/src/main/java/electrosphere/net/client/protocol/PlayerProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/PlayerProtocol.java @@ -11,6 +11,7 @@ import electrosphere.net.server.player.Player; public class PlayerProtocol { protected static void handlePlayerMessage(PlayerMessage message){ + Globals.profiler.beginCpuSample("PlayerProtocol.handlePlayerMessage"); switch(message.getMessageSubtype()){ case SET_ID: Globals.clientPlayer = new Player(message.getplayerID()); @@ -20,6 +21,7 @@ public class PlayerProtocol { Globals.clientPlayerData.setWorldPos(new Vector3i(message.getinitialDiscretePositionX(), message.getinitialDiscretePositionY(), message.getinitialDiscretePositionZ())); break; } + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/net/client/protocol/SynchronizationProtocol.java b/src/main/java/electrosphere/net/client/protocol/SynchronizationProtocol.java index 5e6e8523..1e904dcb 100644 --- a/src/main/java/electrosphere/net/client/protocol/SynchronizationProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/SynchronizationProtocol.java @@ -6,6 +6,7 @@ import electrosphere.net.parser.net.message.SynchronizationMessage; public class SynchronizationProtocol { protected static void handleSynchronizationMessage(SynchronizationMessage message){ + Globals.profiler.beginCpuSample("SynchronizationProtocol.handleSynchronizationMessage"); switch(message.getMessageSubtype()){ case UPDATECLIENTSTATE: case ATTACHTREE: @@ -13,6 +14,7 @@ public class SynchronizationProtocol { Globals.clientSynchronizationManager.pushMessage(message); break; } + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/net/client/protocol/TerrainProtocol.java b/src/main/java/electrosphere/net/client/protocol/TerrainProtocol.java index 361ed53f..728ea695 100644 --- a/src/main/java/electrosphere/net/client/protocol/TerrainProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/TerrainProtocol.java @@ -16,6 +16,7 @@ import electrosphere.net.parser.net.message.TerrainMessage; public class TerrainProtocol { protected static void handleTerrainMessage(TerrainMessage message){ + Globals.profiler.beginCpuSample("TerrainProtocol.handleTerrainMessage"); switch(message.getMessageSubtype()){ case RESPONSEMETADATA: Globals.clientWorldData = new ClientWorldData( @@ -60,6 +61,7 @@ public class TerrainProtocol { LoggerInterface.loggerNetworking.WARNING("Client networking: Unhandled message of type: " + message.getMessageSubtype()); break; } + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java b/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java index 33ae9423..49b70814 100644 --- a/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/CompositePipeline.java @@ -2,6 +2,7 @@ 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; @@ -10,6 +11,7 @@ public class CompositePipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Globals.profiler.beginCpuSample("CompositePipeline.render"); // //Setup to render screen textures & bind screen framebuffer // @@ -63,7 +65,7 @@ public class CompositePipeline implements RenderPipeline { GL40.glBindVertexArray(0); - + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java index 9483e291..5a127c38 100644 --- a/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java @@ -28,6 +28,8 @@ public class DebugContentPipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Globals.profiler.beginCpuSample("DebugContentPipeline.render"); + //bind screen fbo RenderingEngine.screenFramebuffer.bind(); openGLState.glDepthTest(true); @@ -202,6 +204,8 @@ public class DebugContentPipeline implements RenderPipeline { } } } + + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java b/src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java index b8f63421..e3fd8cd3 100644 --- a/src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/MainContentNoOITPipeline.java @@ -22,6 +22,8 @@ public class MainContentNoOITPipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Globals.profiler.beginCpuSample("MainContentNoOITPipeline.render"); + //bind screen fbo RenderingEngine.screenFramebuffer.bind(); openGLState.glDepthTest(true); @@ -75,6 +77,8 @@ public class MainContentNoOITPipeline implements RenderPipeline { currentActor.draw(renderPipelineState,openGLState); } } + + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java index ccc89af6..79884de0 100644 --- a/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java @@ -29,6 +29,7 @@ public class MainContentPipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Globals.profiler.beginCpuSample("MainContentPipeline.render"); Matrix4d modelTransformMatrix = new Matrix4d(); @@ -214,6 +215,8 @@ public class MainContentPipeline implements RenderPipeline { // glBindVertexArray(0); + + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java b/src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java index 177dffcf..a887fb04 100644 --- a/src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/NormalsForOutlinePipeline.java @@ -20,6 +20,7 @@ public class NormalsForOutlinePipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Globals.profiler.beginCpuSample("NormalsForOutlinePipeline.render"); /* gameImageNormalsTexture; static Framebuffer gameImageNormalsFramebuffer; @@ -83,6 +84,8 @@ public class NormalsForOutlinePipeline implements RenderPipeline { currentActor.draw(renderPipelineState,openGLState); } } + + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java b/src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java index bfb44292..ed890dc3 100644 --- a/src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/PostProcessingPipeline.java @@ -15,6 +15,7 @@ public class PostProcessingPipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Globals.profiler.beginCpuSample("PostProcessingPipeline.render"); // // Outline normals // @@ -40,6 +41,8 @@ public class PostProcessingPipeline implements RenderPipeline { GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); GL40.glBindVertexArray(0); } + + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java b/src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java index d547b473..9b677d24 100644 --- a/src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/RenderScreenPipeline.java @@ -14,6 +14,7 @@ public class RenderScreenPipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Globals.profiler.beginCpuSample("RenderScreenPipeline.render"); // //unbind texture channels // @@ -71,6 +72,8 @@ public class RenderScreenPipeline implements RenderPipeline { } GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); GL40.glBindVertexArray(0); + + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java b/src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java index b1ff6f50..902a78af 100644 --- a/src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/ShadowMapPipeline.java @@ -24,6 +24,7 @@ public class ShadowMapPipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Globals.profiler.beginCpuSample("ShadowMapPipeline.render"); Matrix4d modelTransformMatrix = new Matrix4d(); //set the viewport to shadow map size @@ -105,6 +106,8 @@ public class ShadowMapPipeline implements RenderPipeline { openGLState.glViewport(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); //resume culling backface // glCullFace(GL_BACK); + + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java b/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java index 62a6b653..0a26226d 100644 --- a/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java @@ -17,6 +17,7 @@ public class UIPipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Globals.profiler.beginCpuSample("UIPipeline.render"); // //Black background @@ -73,6 +74,7 @@ public class UIPipeline implements RenderPipeline { } } + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java b/src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java index 3647c03b..6fe2e2eb 100644 --- a/src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/VolumeBufferPipeline.java @@ -23,6 +23,7 @@ public class VolumeBufferPipeline implements RenderPipeline { @Override public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { + Globals.profiler.beginCpuSample("VolumeBufferPipeline.render"); Matrix4d modelTransformMatrix = new Matrix4d(); //set the viewport to shadow map size @@ -189,6 +190,8 @@ public class VolumeBufferPipeline implements RenderPipeline { openGLState.glBindFramebuffer(GL40.GL_FRAMEBUFFER,0); //resume culling backface GL40.glDisable(GL40.GL_CULL_FACE); + + Globals.profiler.endCpuSample(); } } diff --git a/src/main/java/electrosphere/server/content/EnvironmentGenerator.java b/src/main/java/electrosphere/server/content/EnvironmentGenerator.java index 6b5abfbc..be4a31f4 100644 --- a/src/main/java/electrosphere/server/content/EnvironmentGenerator.java +++ b/src/main/java/electrosphere/server/content/EnvironmentGenerator.java @@ -45,7 +45,7 @@ public class EnvironmentGenerator { public static void generateForest(Realm realm, ServerDataCell cell, Vector3i worldPos, long randomizer){ Random rand = new Random(randomizer); - int targetNum = (int)(rand.nextFloat() * 5) + 5; + int targetNum = (int)(rand.nextFloat() * 3) + 3; LoggerInterface.loggerGameLogic.DEBUG("generate forest"); for(int i = 0; i < targetNum; i++){ Vector3d position = new Vector3d(