Renderer/src/main/java/electrosphere/engine/Main.java
2023-05-28 15:06:28 -04:00

396 lines
13 KiB
Java

package electrosphere.engine;
import static org.lwjgl.glfw.GLFW.glfwGetTime;
import static org.lwjgl.glfw.GLFW.glfwTerminate;
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
import java.util.concurrent.TimeUnit;
import electrosphere.audio.AudioEngine;
import electrosphere.client.sim.ClientFunctions;
import electrosphere.controls.ControlHandler;
import electrosphere.engine.cli.CLIParser;
import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.game.config.UserSettings;
import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.TerrainMessage;
import electrosphere.net.parser.net.raw.NetworkParser;
import electrosphere.net.parser.util.ByteStreamUtils;
import electrosphere.renderer.Model;
import electrosphere.renderer.RenderingEngine;
import electrosphere.util.worldviewer.TerrainViewer;
public class Main {
//
//Visualization Controls
//
//These are used in calculating the time between frames for visualization (camera) control and such
static double deltaTime = 0.0f;
static double lastFrame = 0.0f;
static long frameCount = 0;
public static float deltaFrames = 0;
public static boolean running = true;
//target amount of time per frame
public static float targetFrameRate = 60.0f;
static float targetFramePeriod = 1.0f/targetFrameRate;
//framestep variable
static int framestep = 2;
public static void main(String args[]){
//
//
// I N I T I A L I Z A T I O N
//
//
//parse command line arguments
CLIParser.parseCLIArgs(args);
startUp();
mainLoop();
}
public static void startUp(){
//initialize logging interfaces
LoggerInterface.initLoggers();
//load user settings
UserSettings.loadUserSettings();
//controls
if(Globals.RUN_CLIENT){
initControlHandler();
}
//init global variables
Globals.initGlobals();
// if(1==1){
// SaveUtils.loadSave("arena");
// Globals.authenticationManager = new AuthenticationManager();
// String rawPass = "testpassword";
// String hashedPassword = AuthenticationManager.getHashedString(rawPass);
// boolean authed = Globals.authenticationManager.authenticate("testuser", hashedPassword);
// System.out.println("Authenticated: " + authed);
// System.exit(0);
// }
//world gen testing
//gen terrain
// Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0);
// Globals.serverTerrainManager.load();
// Globals.serverWorldData = ServerWorldData.createGameWorld(Globals.serverTerrainManager);
// //gen world
// Globals.macroData = MacroData.generateWorld(0);
// Globals.macroData.describeWorld();
// boolean run = true;
// Globals.macroSimulation = new MacroSimulation();
// while(run){
// Globals.macroSimulation.simulate();
// try {
// TimeUnit.MILLISECONDS.sleep(1000);
// } catch (InterruptedException ex) {
// ex.printStackTrace();
// }
// }
// if(1==1){
// Globals.audioEngine = new AudioEngine();
// Globals.audioEngine.init();
// Globals.assetManager.addAudioPathToQueue("/Audio/MenuStartup.ogg");
// Globals.assetManager.loadAssetsInQueue();
// Globals.audioEngine.setGain(0.1f);
// AudioSource startupSound = AudioUtils.playAudioAtLocation("/Audio/MenuStartup.ogg", new Vector3f(3,0,0));
// if(startupSound != null){
// while(startupSound.isPlaying()){
// try {
// TimeUnit.MILLISECONDS.sleep(10);
// } catch (InterruptedException ex) {
// ex.printStackTrace();
// }
// }
// }
// System.exit(0);
// }
//debug: create terrain/world viewer
// TerrainViewer.runViewer();
//create the drawing context
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
Globals.renderingEngine = new RenderingEngine();
Globals.renderingEngine.createOpenglContext();
}
//uncomment to test loading a model into engine
// if(1==1){
// Globals.assetManager.addModelPathToQueue("/Models/tank1.fbx");
// Globals.assetManager.loadAssetsInQueue();
// Model model = Globals.assetManager.fetchModel("/Models/tank1.fbx");
// // for(electrosphere.renderer.anim.Animation anim : model.animations){
// // if(anim.name.equals("Armature|Idle1")){
// // System.out.println(anim.duration);
// // for(electrosphere.renderer.anim.AnimChannel channel : anim.channels){
// // if(channel.getNodeID().equals("Torso")){
// // channel.fullDescribeChannel();
// // }
// // // System.out.println("CHannel: " + channel.getNodeID());
// // }
// // break;
// // }
// // }
// model.animations.get(0).fullDescribeAnimation();
// // model.describeHighLevel();
// System.exit(0);
// }
//create the audio context
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
Globals.audioEngine = new AudioEngine();
Globals.audioEngine.init();
// Globals.audioEngine.setGain(0.1f);
}
//init default resources
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
Globals.initDefaultGraphicalResources();
Globals.initDefaultAudioResources();
}
//fire off a loading thread for the title menus/screen
LoggerInterface.loggerStartup.INFO("Fire off loading thread");
if(Globals.RUN_CLIENT){
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_TITLE_MENU);
Globals.loadingThreadsList.add(serverThread);
serverThread.start();
} else {
LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_ARENA);
Globals.loadingThreadsList.add(clientThread);
clientThread.start();
}
//recapture the screen for rendering
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
LoggerInterface.loggerStartup.INFO("Recapture screen");
Globals.controlHandler.setShouldRecapture(true);
}
// RenderUtils.recaptureScreen();
}
/**
* Runs the main loop indefinitely. Blocks the thread this is called in.
*/
public static void mainLoop(){
mainLoop(0);
}
/**
* Runs the main loop for a specified number of frames.
* @param maxFrames The number of frames to run for. If 0, will run indefinitely.
*/
public static void mainLoop(long maxFrames){
//main loop
while (running) {
/*
Frame calculation
*/
double currentTime = glfwGetTime();
deltaTime = currentTime - lastFrame;
deltaFrames = targetFrameRate * (float)deltaTime;
lastFrame = currentTime;
///
/// A S S E T M A N A G E R S T U F F
///
if(Globals.RUN_CLIENT){
Globals.assetManager.loadAssetsInQueue();
}
///
/// C L I E N T N E T W O R K I N G S T U F F
///
//Why is this its own function? Just to get the networking code out of main()
if(Globals.RUN_CLIENT && Globals.clientConnection != null){
Globals.clientConnection.parseMessages();
}
//handle framestep
if(framestep == 1){
framestep = 0;
}
///
/// I N P U T C O N T R O L S
///
//Poll controls
if(Globals.RUN_CLIENT){
Globals.controlHandler.pollControls();
Globals.controlHandler.recaptureIfNecessary();
}
///
/// C L I E N T S I M U L A T I O N S T U F F
///
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){
Globals.clientSimulation.simulate();
}
if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){
ClientFunctions.runClientFunctions();
}
///
/// S E R V E R M I C R O S I M U L A T I O N
///
if(Globals.realmManager != null){
Globals.realmManager.simulate();
}
///
/// M A C R O S I M U L A T I O N S T U F F
///
if(Globals.macroSimulation != null && Globals.macroSimulation.isReady() && framestep > 0){
Globals.macroSimulation.simulate();
}
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
Globals.renderingEngine.drawScreen();
}
if(Globals.ENGINE_SHUTDOWN_FLAG || (!Globals.HEADLESS && Globals.RUN_CLIENT && glfwWindowShouldClose(Globals.window))){
running = false;
}
if(deltaTime < targetFramePeriod){
sleep((int)(1000.0 * (targetFramePeriod - deltaTime)));
} else {
sleep(1);
}
frameCount++;
if(maxFrames > 0 && frameCount > maxFrames){
running = false;
}
}
//
// S H U T D O W N
//
//Terminate the program.
if(!Globals.HEADLESS && Globals.RUN_CLIENT){
glfwTerminate();
}
//used to signal threads to stop
running = false;
if(Globals.server != null){
Globals.server.close();
Globals.serverThread.interrupt();
}
//shut down audio engine
if(!Globals.HEADLESS && Globals.RUN_CLIENT){
Globals.audioEngine.shutdown();
}
//if netmonitor is running, close
if(Globals.netMonitor != null){
Globals.netMonitor.close();
}
}
public static long getCurrentFrame(){
return frameCount;
}
static void sleep(int i) {
try {
TimeUnit.MILLISECONDS.sleep(i);
} catch (InterruptedException ex) {
System.out.println("Sleep somehow interrupted?!");
}
}
public static boolean isRunning(){
return running;
}
public static void initControlHandler(){
LoggerInterface.loggerStartup.INFO("Initialize control handler");
Globals.controlHandler = ControlHandler.generateExampleControlsMap();
Globals.controlHandler.setCallbacks();
// Globals.controlHandler = FileLoadingUtils.loadModelObjectFromBakedJsonFile("/Config/keybinds.json",ControlHandler.class);
}
/**
* Sets the framestep state (2 to resume automatic, 1 to make single step)
* @param framestep 2 - automatic framestep, 1 - single step, 0 - no step
*/
public static void setFramestep(int framestep){
Main.framestep = framestep;
}
// public static void updateMouseVariables(){
// glfwGetCursorPos(Globals.window, mouse_X_Buffer, mouse_Y_Buffer);
// xpos = mouse_X_Buffer[0];
// ypos = mouse_Y_Buffer[0];
// float xoffset = (float) (xpos - mouse_lastX) * mouseSensitivity;
// float yoffset = (float) (mouse_lastY - ypos) * mouseSensitivity;
// mouse_lastX = (float) xpos;
// mouse_lastY = (float) ypos;
// if(Globals.controlHandler != null && !Globals.controlHandler.isMouseVisible()){
// yaw = yaw + xoffset;
// pitch = pitch - yoffset;
// if (pitch > 100.0f) {
// pitch = 100.0f;
// }
// if (pitch < -99.0f) {
// pitch = -99.0f;
// }
// }
// }
}