#include "HydraEngine.h" #include "HydraInputManager.h" #include "../scheduler/HydraTaskScheduler.h" #include "../scheduler/HydraTaskScheduler.h" #include "../windowmanager/HydraWindowManager.h" #include "../game/HydraGameProxy.h" #include "../renderer/HydraRenderer.h" #include "../buffer/HydraBufferManager.h" #include "../buffer/HydraVertexBufferManager.h" #include "../buffer/HydraTextureBufferManager.h" #include "../buffer/HydraMaterialBufferManager.h" #include "../buffer/HydraLightBufferManager.h" #include "../buffer/HydraShadowBufferManager.h" #include "../ecs/HydraECS.h" #include "../ecs/systems/HydraTransformSystem.h" #include "../ecs/systems/HydraMeshSystem.h" #include "../ecs/systems/HydraRenderSystem.h" #include "../ecs/systems/HydraMaterialSystem.h" #include "../ecs/systems/HydraLightSystem.h" #include "../ecs/systems/HydraDirectionalShadowSourceSystem.h" #include "../ecs/systems/HydraSpotShadowSourceSystem.h" #include "../ecs/components/HydraPositionComponent.h" #include "../ecs/components/HydraMeshComponent.h" #include "../ecs/components/HydraRenderableComponent.h" #include "../ecs/components/HydraTextureComponent.h" #include "../ecs/components/HydraMaterialComponent.h" #include "../ecs/components/HydraLightComponent.h" #include "../ecs/components/HydraDirectionalShadowSourceComponent.h" #include "../ecs/components/HydraSpotShadowSourceComponent.h" #include "../camera/HydraCamera.h" #include "../actor/HydraActorManager.h" #include "../pipeline/HydraPipeline.h" #include "../pipeline/HydraForwardPipeline.h" #include "../pipeline/HydraDeferredPipeline.h" #include "../pipeline/HydraShadowPipeline.h" #include "../task/windowmanager/HydraInitialiseWindowManagerTask.hpp" #include "../task/windowmanager/HydraShutdownWindowManagerTask.hpp" #include "../task/windowmanager/HydraProcessInputTask.hpp" #include "../task/renderer/HydraInitialiseRendererTask.hpp" #include "../task/renderer/HydraRenderTask.hpp" #include "../task/pipeline/HydraInitialisePipelineTask.hpp" #include "../task/pipeline/HydraShutdownPipelineTask.hpp" #include "../task/pipeline/HydraRenderPipelineTask.hpp" #include "../task/ecs/HydraUpdateSystemTask.hpp" #include "../task/ecs/HydraInitialiseComponentsTask.hpp" #include "../task/buffer/HydraShutdownBufferManagerTask.hpp" #include "../task/buffer/HydraInitialiseTextureManagerTask.hpp" #include "../task/buffer/HydraInitialiseShadowBufferTask.hpp" #include "../task/actor/HydraUpdatePlayerTask.h" #include "../task/renderer/HydraEndRenderTask.hpp" #include "../mesh/HydraMeshManager.h" HydraTaskScheduler *const HydraEngine::TaskScheduler() { return m_task_scheduler; } void HydraEngine::InitialiseGame(HydraGameProxy *game) { m_game = game; } void HydraEngine::Start() { _CreateManagers(); _InitialiseManagers(); _InitialiseSystems(); m_game->Initialise(); _GameLoop(); _Shutdown(); } HydraWindowManager *const HydraEngine::WindowManager() { return m_window_manager; } HydraRenderSettings HydraEngine::RenderSettings() { return m_render_settings; } HydraInputManager *const HydraEngine::InputManager() { return m_input_manager; } HydraRenderer *const HydraEngine::Renderer() { return m_renderer; } HydraECS *const HydraEngine::ECS() { return m_ecs; } HydraActorManager *const HydraEngine::ActorManager() { return m_actor_manager; } HydraCamera *const HydraEngine::Camera() { return m_camera; } HydraBufferManager *const HydraEngine::BufferManager() { return m_buffer_manager; } HydraVertexBufferManager *const HydraEngine::VertexBufferManager() { return m_vertex_buffer_manager; } HydraMeshManager *const HydraEngine::MeshManager() { return m_mesh_manager; } HydraPipeline *const HydraEngine::Pipeline() { return m_pipeline; } HydraTextureBufferManager *const HydraEngine::TextureBufferManager() { return m_texture_buffer_manager; } HydraMaterialBufferManager *const HydraEngine::MaterialBufferManager() { return m_material_buffer_manager; } HydraLightBufferManager *const HydraEngine::LightBufferManager() { return m_light_buffer_manager; } HydraShadowBufferManager *const HydraEngine::ShadowBufferManager() { return m_shadow_buffer_manager; } void HydraEngine::PossessPlayer(HydraID actor_id) { m_possessed_actor_id = actor_id; } HydraID HydraEngine::GetPossessedPlayer() { return m_possessed_actor_id; } float HydraEngine::GetDeltaT() { return m_delta_t; } uint32_t HydraEngine::GetLightCount() { return m_light_system->GetLightCount(); } void HydraEngine::_CreateManagers() { m_camera = new HydraCamera(); m_task_scheduler = new HydraTaskScheduler(); m_window_manager = new HydraWindowManager(); m_input_manager = new HydraInputManager(); m_renderer = new HydraRenderer(); m_ecs = new HydraECS(); m_actor_manager = new HydraActorManager(); m_buffer_manager = new HydraBufferManager(); m_vertex_buffer_manager = new HydraVertexBufferManager(); m_mesh_manager = new HydraMeshManager(); m_pipeline = new HydraForwardPipeline(); m_deferred_pipeline = new HydraDeferredPipeline(); m_shadow_pipeline = new HydraShadowPipeline(); m_texture_buffer_manager = new HydraTextureBufferManager(); m_material_buffer_manager = new HydraMaterialBufferManager(); m_light_buffer_manager = new HydraLightBufferManager(); m_shadow_buffer_manager = new HydraShadowBufferManager(); } void HydraEngine::_InitialiseManagers() { m_task_scheduler->Initialise(1); HydraID create_window_task_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); m_task_scheduler->WaitForTask(create_window_task_id); HydraID create_renderer_task_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); m_task_scheduler->WaitForTask(create_renderer_task_id); m_mesh_manager->Initialise(); m_ecs->Init(); m_actor_manager->Initialise(MAX_ACTORS); m_buffer_manager->Initialise(); m_vertex_buffer_manager->Initialise(); m_texture_buffer_manager->Intialise(); m_material_buffer_manager->Intialise(); m_light_buffer_manager->Initialise(); HydraID create_shadow_buffer_task_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); m_task_scheduler->WaitForTask(create_shadow_buffer_task_id); } void HydraEngine::_InitialiseSystems() { m_ecs->RegisterComponentType(); m_ecs->RegisterComponentType(); m_ecs->RegisterComponentType(); m_ecs->RegisterComponentType(); m_ecs->RegisterComponentType(); m_ecs->RegisterComponentType(); m_ecs->RegisterComponentType(); m_ecs->RegisterComponentType(); m_mesh_system = m_ecs->RegisterSystem(); m_transform_system = m_ecs->RegisterSystem(); m_render_system = m_ecs->RegisterSystem(); m_material_system = m_ecs->RegisterSystem(); m_light_system = m_ecs->RegisterSystem(); m_directional_shadow_system = m_ecs->RegisterSystem(); m_spot_shadow_system = m_ecs->RegisterSystem(); HydraSignature mesh_sig; HydraSignature trans_sig; HydraSignature render_sig; HydraSignature material_sig; HydraSignature light_sig; HydraSignature directional_shadow_sig; HydraSignature spot_shadow_sig; mesh_sig.set(m_ecs->GetComponentType(),true); trans_sig.set(m_ecs->GetComponentType(),true); render_sig.set(m_ecs->GetComponentType(),true); material_sig.set(m_ecs->GetComponentType(),true); light_sig.set(m_ecs->GetComponentType(), true); light_sig.set(m_ecs->GetComponentType(), true); directional_shadow_sig.set(m_ecs->GetComponentType(), true); directional_shadow_sig.set(m_ecs->GetComponentType(), true); directional_shadow_sig.set(m_ecs->GetComponentType(), true); spot_shadow_sig.set(m_ecs->GetComponentType(), true); spot_shadow_sig.set(m_ecs->GetComponentType(), true); spot_shadow_sig.set(m_ecs->GetComponentType(), true); m_ecs->SetSystemSignature(mesh_sig); m_ecs->SetSystemSignature(trans_sig); m_ecs->SetSystemSignature(render_sig); m_ecs->SetSystemSignature(material_sig); m_ecs->SetSystemSignature(light_sig); m_ecs->SetSystemSignature(directional_shadow_sig); m_ecs->SetSystemSignature(spot_shadow_sig); } void HydraEngine::_UpdateSystems() { HydraID posUpdateBarrierID = m_task_scheduler->CreateBarrier(); HydraID update_trans_id = m_task_scheduler->CreateTask(HydraThreadAffinity::General, posUpdateBarrierID); HydraUpdateSystemTask* update_trans_task = static_cast(m_task_scheduler->GetTask(update_trans_id)); update_trans_task->Initialise(m_delta_t, m_transform_system); HydraID update_mat_id = m_task_scheduler->CreateTask(HydraThreadAffinity::General, posUpdateBarrierID); HydraUpdateSystemTask* update_mat_task = static_cast(m_task_scheduler->GetTask(update_mat_id)); update_mat_task->Initialise(m_delta_t, m_material_system); m_task_scheduler->StartTask(update_trans_id); m_task_scheduler->StartTask(update_mat_id); m_task_scheduler->WaitForBarrier(posUpdateBarrierID); HydraID update_light_id = m_task_scheduler->CreateTask(HydraThreadAffinity::General); HydraUpdateSystemTask* update_light_task = static_cast(m_task_scheduler->GetTask(update_light_id)); update_light_task->Initialise(m_delta_t, m_light_system); m_task_scheduler->WaitForTask(update_light_id); HydraID shadow_barrier = m_task_scheduler->CreateBarrier(); HydraID update_shadow_id = m_task_scheduler->CreateTask(HydraThreadAffinity::General, shadow_barrier); HydraUpdateSystemTask* update_shadow_task = static_cast(m_task_scheduler->GetTask(update_shadow_id)); update_shadow_task->Initialise(m_delta_t, m_directional_shadow_system); HydraID update_spot_shadow_id = m_task_scheduler->CreateTask(HydraThreadAffinity::General, shadow_barrier); HydraUpdateSystemTask* update_spot_shadow_task = static_cast(m_task_scheduler->GetTask(update_spot_shadow_id)); update_spot_shadow_task->Initialise(m_delta_t, m_spot_shadow_system); m_task_scheduler->StartTask(update_shadow_id); m_task_scheduler->StartTask(update_spot_shadow_id); m_task_scheduler->WaitForBarrier(shadow_barrier); m_shadow_buffer_manager->UpdateShadowBuffer(); } void HydraEngine::_GameLoop() { // game loop std::chrono::steady_clock clock; int fpsFrameCount = 0; int fpsHighLowCount = 0; float fpsLow = 99999; float fpsHigh = 0; float totalTime = 0.0f; bool fixed_tick = false; std::chrono::time_point last_tick = clock.now(); std::chrono::time_point last_fixed_tick = clock.now(); // m_fps_label_id = UIManager()->CreateWidget(); // HydraUILabelWidget* label = (HydraUILabelWidget*)UIManager()->GetWidget(m_fps_label_id); // label->SetText("FPS"); // label->Position = glm::vec3(0, 200, 0); // label->SetFont("Calibri", 10.0f); HydraID initialise_pipeline_task_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraInitialisePipelineTask *pipeline_task = static_cast(m_task_scheduler->GetTask(initialise_pipeline_task_id)); pipeline_task->Initialise(m_pipeline); m_task_scheduler->WaitForTask(initialise_pipeline_task_id); HydraID initialise_shadow_pipeline_task_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraInitialisePipelineTask *pipeline_shadow_task = static_cast(m_task_scheduler->GetTask(initialise_shadow_pipeline_task_id)); pipeline_shadow_task->Initialise(m_shadow_pipeline); m_task_scheduler->WaitForTask(initialise_shadow_pipeline_task_id); HydraID initialise_def_pipeline_task_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraInitialisePipelineTask *pipeline_def_task = static_cast(m_task_scheduler->GetTask(initialise_def_pipeline_task_id)); pipeline_def_task->Initialise(m_deferred_pipeline); m_task_scheduler->WaitForTask(initialise_def_pipeline_task_id); while (m_running) { HydraID barrierID = m_task_scheduler->CreateBarrier(); std::chrono::time_point this_tick = clock.now(); std::chrono::duration diff = this_tick - last_tick; std::chrono::duration fixed_diff = this_tick - last_fixed_tick; totalTime = totalTime += diff.count(); m_delta_t = diff.count(); float fixed_delta_t = fixed_diff.count(); if (fixed_delta_t > 0.016666666666f) { m_fixed_delta_t = fixed_diff.count(); last_fixed_tick = this_tick; fixed_tick = true; HydraID processInputID = m_task_scheduler->CreateTask(HydraThreadAffinity::Render, barrierID); m_task_scheduler->StartTask(processInputID); //Physics here } if (fpsFrameCount >= 15) { float fps = 1.0f / (totalTime / fpsFrameCount); // m_fps_label->SetText("FPS: " + std::to_string(fps)); // label->SetText("FPS: " + std::to_string(fps)); fpsFrameCount = 0; totalTime = 0.0f; } last_tick = this_tick; fpsFrameCount++; HydraID initialise_components_id = m_task_scheduler->CreateTask(HydraThreadAffinity::General, barrierID); HydraID update_player_task_id = m_task_scheduler->CreateTask(HydraThreadAffinity::General, barrierID); m_task_scheduler->StartTask(initialise_components_id); m_task_scheduler->StartTask(update_player_task_id); m_task_scheduler->WaitForBarrier(barrierID); m_game->Update(m_delta_t); _UpdateSystems(); HydraID render_shadow_task_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraRenderPipelineTask* render_shadow_task = static_cast(m_task_scheduler->GetTask(render_shadow_task_id)); render_shadow_task->Initialise(m_shadow_pipeline); m_task_scheduler->WaitForTask(render_shadow_task_id); HydraID render_def_task_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraRenderPipelineTask* render_def_task = static_cast(m_task_scheduler->GetTask(render_def_task_id)); render_def_task->Initialise(m_deferred_pipeline); m_task_scheduler->WaitForTask(render_def_task_id); HydraID end_task_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); m_task_scheduler->WaitForTask(end_task_id); } } void HydraEngine::_Shutdown() { m_actor_manager->Shutdown(); m_ecs->Shutdown(); //Shutdown the buffer and vertex buffer managers HydraID shutdown_buffer_mgr_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); m_task_scheduler->WaitForTask(shutdown_buffer_mgr_id); HydraID shutdown_pipeline_id = m_task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraShutdownPipelineTask *pipeline_task = static_cast(m_task_scheduler->GetTask(shutdown_pipeline_id)); pipeline_task->Initialise(m_pipeline); m_task_scheduler->WaitForTask(shutdown_pipeline_id); m_task_scheduler->Shutdown(); delete m_actor_manager; delete m_ecs; delete m_input_manager; delete m_window_manager; delete m_task_scheduler; delete m_buffer_manager; delete m_vertex_buffer_manager; delete m_pipeline; delete m_texture_buffer_manager; delete m_material_buffer_manager; delete m_light_buffer_manager; } bool HydraEngine::KeyPressed(HYDRA_KEY_CODES key) { return m_input_manager->KeyPressed(key); } glm::vec2 HydraEngine::MouseChange() { return m_input_manager->MouseChange(); } void HydraEngine::Exit() { m_running = false; }