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(); } }