Renderer/src/main/java/electrosphere/engine/Globals.java
austin 6fe1733d58
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
move more client state
2025-05-15 15:48:04 -04:00

506 lines
19 KiB
Java

package electrosphere.engine;
import electrosphere.audio.AudioEngine;
import electrosphere.auth.AuthenticationManager;
import electrosphere.client.ClientState;
import electrosphere.client.block.cells.BlockTextureAtlas;
import electrosphere.client.entity.particle.ParticleService;
import electrosphere.client.terrain.cells.VoxelTextureAtlas;
import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.controls.CameraHandler;
import electrosphere.controls.ControlCallback;
import electrosphere.controls.ControlHandler;
import electrosphere.controls.MouseCallback;
import electrosphere.controls.ScrollCallback;
import electrosphere.controls.cursor.CursorState;
import electrosphere.data.voxel.VoxelType;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.engine.assetmanager.AssetManager;
import electrosphere.engine.os.fs.FileWatcherService;
import electrosphere.engine.profiler.Profiler;
import electrosphere.engine.signal.sync.MainThreadSignalService;
import electrosphere.logger.LoggerInterface;
import electrosphere.net.config.NetConfig;
import electrosphere.net.monitor.NetMonitor;
import electrosphere.renderer.RenderUtils;
import electrosphere.renderer.RenderingEngine;
import electrosphere.renderer.actor.instance.InstanceManager;
import electrosphere.renderer.loading.ModelPretransforms;
import electrosphere.renderer.meshgen.FluidChunkModelGeneration;
import electrosphere.renderer.shader.ShaderOptionMap;
import electrosphere.renderer.shader.VisualShader;
import electrosphere.renderer.texture.TextureMap;
import electrosphere.renderer.ui.ElementService;
import electrosphere.renderer.ui.elements.ImagePanel;
import electrosphere.renderer.ui.font.FontManager;
import electrosphere.script.ScriptEngine;
import electrosphere.server.ServerState;
import electrosphere.server.db.DatabaseController;
import electrosphere.server.entity.poseactor.PoseModel;
import electrosphere.server.service.CharacterService;
import electrosphere.server.service.StructureScanningService;
import electrosphere.util.FileUtils;
/**
* Global values
*/
public class Globals {
/**
* State for the engine
*/
public static EngineState engineState;
/**
* The engine and game configuration
*/
public static electrosphere.data.Config gameConfigCurrent;
/**
* State for the client
*/
public static ClientState clientState;
/**
* State for the server
*/
public static ServerState serverState;
//
//Rendering Engine
//
public static RenderingEngine renderingEngine;
//
//Audio Engine
//
public static AudioEngine audioEngine;
//
//Core Engine signals
//
public static boolean ENGINE_SHUTDOWN_FLAG = false;
//main debug flag
//current enables imgui debug menu or not
public static boolean ENGINE_DEBUG = true;
//
//Profiler
//
public static Profiler profiler;
//
//Garbage Collection
//
//set to true to trigger full GC every frame
//a full GC includes collecting old generations as well -- likely very laggy!!
public static boolean EXPLICIT_GC = false;
/**
* Number of frames to wait before triggering gc again
*/
public static final int GC_FRAME_FREQUENCY = 15;
//
//Engine timing
//
public static boolean EXPLICIT_SLEEP = true;
//
//Signals for running various parts of the engine
//
public static boolean RUN_DEMO = false;
public static boolean RUN_CLIENT = true;
public static boolean RUN_HIDDEN = false; //glfw session will be created with hidden window
public static boolean RUN_AUDIO = true;
public static boolean RUN_SCRIPTS = true;
public static boolean RUN_PHYSICS = true; //toggles whether physics is run or not
public static boolean RUN_FLUIDS = false; //toggles whether fluid physics is run or not
public static int clientCharacterID;
public static NetConfig netConfig = null;
//
//Server manager thing
//
public static boolean RUN_SERVER = true;
//
//Authentication manager
//
public static AuthenticationManager authenticationManager;
//
//Controls Handler
//
public static ControlHandler controlHandler;
public static boolean updateCamera = true;
public static ControlCallback controlCallback = new ControlCallback();
public static MouseCallback mouseCallback = new MouseCallback();
public static ScrollCallback scrollCallback = new ScrollCallback();
public static CursorState cursorState = new CursorState();
//
// Database stuff
//
public static DatabaseController dbController = new DatabaseController();
//
//OpenGL - Other
//
public static int WINDOW_WIDTH;
public static int WINDOW_HEIGHT;
public static boolean WINDOW_DECORATED = true; //used to control whether the window is created with decorations or not (ie for testing)
public static boolean WINDOW_FULLSCREEN = false; //used to control whether the window is created fullscreen or not (ie for testing)
//title bar dimensions
public static int WINDOW_TITLE_BAR_HEIGHT = 0;
//
//Renderer-adjacent data I need to move into config at some point
//
public static TextureMap textureMapDefault;
public static ModelPretransforms modelPretransforms;
public static ShaderOptionMap shaderOptionMap;
public static FontManager fontManager;
public static CameraHandler cameraHandler = new CameraHandler();
//
//OpenGL - Abstracted engine objects
//
public static VisualShader defaultMeshShader;
public static VisualShader terrainShaderProgram;
public static VisualShader blockShader;
//
// Particle stuff
//
public static ParticleService particleService;
//
//Engine - Main managers/variables
//
//manages all models loaded into memory
public static AssetManager assetManager;
//script engine
public static ScriptEngine scriptEngine;
//services
public static MainThreadSignalService mainThreadSignalService;
//instanced actor manager
public static InstanceManager clientInstanceManager = new InstanceManager();
//chunk stuff
public static VoxelTextureAtlas voxelTextureAtlas = new VoxelTextureAtlas();
public static BlockTextureAtlas blockTextureAtlas = new BlockTextureAtlas();
//manager for all widgets currently being drawn to screen
public static ElementService elementService;
public static int openInventoriesCount = 0;
//services
public static FileWatcherService fileWatcherService;
public static StructureScanningService structureScanningService;
//
//Base engine creation flags
//
public static boolean HEADLESS = false;
//
//
// Renderer flags
//
//
public static boolean RENDER_FLAG_RENDER_SHADOW_MAP = false;
public static boolean RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = false;
public static boolean RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = false;
public static boolean RENDER_FLAG_RENDER_BLACK_BACKGROUND = true;
public static boolean RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
public static boolean RENDER_FLAG_RENDER_UI = true;
public static boolean RENDER_FLAG_RENDER_UI_BOUNDS = false;
//
// Debugging tools
//
public static NetMonitor netMonitor;
/**
* Inits globals
*/
public static void initGlobals(){
//load user settings
Globals.WINDOW_WIDTH = 1920;
Globals.WINDOW_HEIGHT = 1080;
//spin up engine state
Globals.engineState = new EngineState();
//game config
gameConfigCurrent = electrosphere.data.Config.loadDefaultConfig();
NetConfig.readNetConfig();
//render flags
RENDER_FLAG_RENDER_SHADOW_MAP = false;
RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = false;
RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = false;
RENDER_FLAG_RENDER_BLACK_BACKGROUND = true;
RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
RENDER_FLAG_RENDER_UI = true;
RENDER_FLAG_RENDER_UI_BOUNDS = false;
//client state
Globals.clientState = new ClientState();
//server state
Globals.serverState = new ServerState();
Globals.serverState.characterService = (CharacterService)Globals.engineState.serviceManager.registerService(new CharacterService());
//load in default texture map
textureMapDefault = TextureMap.construct("Textures/default_texture_map.json");
//load model pretransforms
modelPretransforms = FileUtils.loadObjectFromAssetPath("Models/modelPretransforms.json", ModelPretransforms.class);
modelPretransforms.init();
//load in shader options map
shaderOptionMap = FileUtils.loadObjectFromAssetPath("Shaders/shaderoptions.json", ShaderOptionMap.class);
shaderOptionMap.debug();
//load asset manager
assetManager = new AssetManager();
//
//Values that depend on the loaded config
Globals.clientState.clientSelectedVoxelType = (VoxelType)gameConfigCurrent.getVoxelData().getTypes().toArray()[1];
//net monitor
if(Globals.gameConfigCurrent.getSettings().getNetRunNetMonitor()){
netMonitor = new NetMonitor();
}
//profiler
profiler = new Profiler();
//add services here
Globals.elementService = (ElementService)Globals.engineState.serviceManager.registerService(new ElementService());
Globals.particleService = (ParticleService)Globals.engineState.serviceManager.registerService(new ParticleService());
Globals.scriptEngine = (ScriptEngine)Globals.engineState.serviceManager.registerService(new ScriptEngine());
Globals.mainThreadSignalService = (MainThreadSignalService)Globals.engineState.serviceManager.registerService(new MainThreadSignalService());
Globals.fileWatcherService = (FileWatcherService)Globals.engineState.serviceManager.registerService(new FileWatcherService());
Globals.structureScanningService = (StructureScanningService)Globals.engineState.serviceManager.registerService(new StructureScanningService());
Globals.engineState.serviceManager.instantiate();
//
//End service manager
}
/**
* Inits default audio resources
*/
public static void initDefaultAudioResources(){
String[] audioToInit = new String[]{
"/Audio/ambienceWind1SeamlessMono.ogg",
"/Audio/weapons/swordUnsheath1.ogg",
"/Audio/weapons/swoosh-03.ogg",
"/Audio/movement/Equip A.wav",
"/Audio/weapons/collisions/FleshWeaponHit1.wav",
"/Audio/weapons/collisions/Massive Punch A.wav",
"/Audio/weapons/collisions/Massive Punch B.wav",
"/Audio/weapons/collisions/Massive Punch C.wav",
"Audio/weapons/collisions/Sword Hit A.wav",
"Audio/weapons/collisions/Sword Hit B.wav",
"Audio/weapons/collisions/Sword Hit C.wav",
"Audio/weapons/collisions/Sword Hit D.wav",
"Audio/weapons/collisions/Sword Hit E.wav",
AssetDataStrings.UI_TONE_CONFIRM_PRIMARY,
AssetDataStrings.UI_TONE_CONFIRM_SECONDARY,
AssetDataStrings.UI_TONE_CURSOR_PRIMARY,
AssetDataStrings.UI_TONE_CURSOR_SECONDARY,
AssetDataStrings.UI_TONE_BACK_PRIMARY,
AssetDataStrings.UI_TONE_BACK_SECONDARY,
AssetDataStrings.UI_TONE_ERROR_PRIMARY,
AssetDataStrings.UI_TONE_ERROR_SECONDARY,
AssetDataStrings.UI_TONE_BUTTON_TITLE,
AssetDataStrings.UI_SFX_ITEM_GRAB,
AssetDataStrings.UI_SFX_ITEM_RELEASE,
AssetDataStrings.UI_SFX_INVENTORY_OPEN,
AssetDataStrings.UI_SFX_INVENTORY_CLOSE,
AssetDataStrings.INTERACT_SFX_BLOCK_PICKUP,
AssetDataStrings.INTERACT_SFX_BLOCK_PLACE,
AssetDataStrings.INTERACT_SFX_DIG,
};
LoggerInterface.loggerStartup.INFO("Loading default audio resources");
for(String path : audioToInit){
Globals.assetManager.addAudioPathToQueue(path);
}
Globals.audioEngine.movementAudioService.init();
}
/**
* Texture paths to be loaded when renderer inits
*/
private static String[] defaultTexturePaths = new String[]{
AssetDataStrings.TEXTURE_DEFAULT,
"Textures/default_diffuse.png",
"Textures/default_specular.png",
"Textures/b1.png",
"Textures/w1.png",
"Textures/ow1.png",
"Textures/ui/WindowBorder.png",
"Textures/ui/uiOutline1.png",
AssetDataStrings.UI_ENGINE_LOGO_1,
AssetDataStrings.UI_FRAME_TEXTURE_DEFAULT_1,
AssetDataStrings.UI_FRAME_TEXTURE_DEFAULT_2,
AssetDataStrings.UI_FRAME_TEXTURE_DEFAULT_3,
"Textures/ui/circle.png",
"Textures/ui/square.png",
"Textures/color/transparent_green.png",
"Textures/color/transparent_magenta.png",
"Textures/color/transparent_orange.png",
"Textures/color/transparent_teal.png",
"Textures/color/transparent_yellow.png",
"Textures/bloodsplat1.png",
};
/**
* The set of models who should correspond to no pose model
*/
private static String[] defaultModelsWithNoPose = new String[]{
AssetDataStrings.POSE_EMPTY,
AssetDataStrings.UNITSPHERE,
AssetDataStrings.UNITCYLINDER,
AssetDataStrings.UNITCUBE,
AssetDataStrings.MODEL_BLOCK_SINGLE,
};
/**
* Inits default graphical resources
*/
public static void initDefaultGraphicalResources(){
LoggerInterface.loggerStartup.INFO("Loading default graphical resources");
//load default textures
for(String defaultTexturePath: defaultTexturePaths){
Globals.assetManager.addTexturePathtoQueue(defaultTexturePath);
}
//create font manager
fontManager = new FontManager();
fontManager.loadFonts();
assetManager.registerModelWithPath(RenderUtils.createBitmapCharacter(), AssetDataStrings.BITMAP_CHARACTER_MODEL);
//particle billboard model
assetManager.registerModelWithPath(RenderUtils.createParticleModel(), AssetDataStrings.MODEL_PARTICLE);
//initialize required windows
WindowUtils.initBaseWindows();
//init default shaderProgram
defaultMeshShader = VisualShader.smartAssembleShader(false,true);
//init terrain shader program
terrainShaderProgram = VisualShader.loadSpecificShader("/Shaders/entities/terrain2/terrain2.vs", "/Shaders/entities/terrain2/terrain2.fs");
blockShader = VisualShader.loadSpecificShader("/Shaders/entities/block/block.vs", "/Shaders/entities/block/block.fs");
//init fluid shader program
FluidChunkModelGeneration.fluidChunkShaderProgram = VisualShader.loadSpecificShader("/Shaders/entities/fluid2/fluid2.vs", "/Shaders/entities/fluid2/fluid2.fs");
//init models
assetManager.registerModelWithPath(RenderUtils.createUnitsphere(), AssetDataStrings.UNITSPHERE);
assetManager.registerModelWithPath(RenderUtils.createUnitCylinder(), AssetDataStrings.UNITCYLINDER);
assetManager.registerModelWithPath(RenderUtils.createUnitCube(), AssetDataStrings.UNITCUBE);
assetManager.registerModelWithPath(RenderUtils.createBlockSingleModel(), AssetDataStrings.MODEL_BLOCK_SINGLE);
assetManager.addModelPathToQueue("Models/basic/geometry/SmallCube.fbx");
assetManager.addModelPathToQueue("Models/basic/geometry/unitcapsule.glb");
assetManager.addModelPathToQueue("Models/basic/geometry/unitplane.fbx");
assetManager.addModelPathToQueue("Models/basic/geometry/unitcube.fbx");
assetManager.registerModelWithPath(RenderUtils.createPlaneModel("Shaders/core/plane/plane.vs", "Shaders/core/plane/plane.fs"), AssetDataStrings.MODEL_IMAGE_PLANE);
assetManager.addShaderToQueue("Shaders/core/plane/plane.vs", "Shaders/core/plane/plane.fs");
//init pose models for basic shapes
PoseModel emptyPoseModel = PoseModel.createEmpty();
for(String modelPath : defaultModelsWithNoPose){
assetManager.registerPoseModelWithPath(emptyPoseModel, modelPath);
}
//image panel
ImagePanel.imagePanelModelPath = assetManager.registerModel(RenderUtils.createPlaneModel("Shaders/core/imagepanel/imagepanel.vs", "Shaders/core/imagepanel/imagepanel.fs"));
Globals.assetManager.addShaderToQueue("Shaders/ui/plainBox/plainBox.vs", "Shaders/ui/plainBox/plainBox.fs");
//window content shader
assetManager.addShaderToQueue("Shaders/ui/windowContent/windowContent.vs", "Shaders/ui/windowContent/windowContent.fs");
//debug shaders
assetManager.addShaderToQueue("Shaders/ui/debug/windowBorder/windowBound.vs", "Shaders/ui/debug/windowBorder/windowBound.fs");
assetManager.addShaderToQueue("Shaders/ui/debug/windowContentBorder/windowContentBound.vs", "Shaders/ui/debug/windowContentBorder/windowContentBound.fs");
//compute shaders
assetManager.addComputeShaderToQueue(AssetDataStrings.COMPUTE_LIGHT_CLUSTER);
assetManager.addComputeShaderToQueue(AssetDataStrings.COMPUTE_LIGHT_CULL);
//as these assets are required for the renderer to work, we go ahead and
//load them into memory now. The loading time penalty is worth it I think.
Globals.assetManager.loadAssetsInQueue();
}
/**
* Unloads scene
*/
public static void unloadScene(){
if(Globals.serverState != null){
Globals.serverState.aiManager.shutdown();
Globals.serverState.realmManager.reset();
}
Globals.dbController.disconnect();
Globals.engineState.serviceManager.unloadScene();
Globals.clientState = new ClientState();
Globals.serverState = new ServerState();
Globals.serverState.characterService = (CharacterService)Globals.engineState.serviceManager.registerService(new CharacterService());
}
/**
* Resets global values
*/
public static void resetGlobals(){
if(Globals.serverState != null){
Globals.serverState.aiManager.shutdown();
Globals.serverState.realmManager.reset();
}
Globals.dbController.disconnect();
//
//Actual globals to destroy
Globals.assetManager = null;
Globals.elementService = null;
Globals.clientState = null;
Globals.serverState = null;
Globals.audioEngine = null;
Globals.engineState = null;
Globals.renderingEngine = null;
Globals.fileWatcherService = null;
Globals.RENDER_FLAG_RENDER_SHADOW_MAP = true;
Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = false;
Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = false;
Globals.RENDER_FLAG_RENDER_UI = false;
Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false;
Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
LoggerInterface.destroyLoggers();
}
}