#include "HydraShadowBufferManager.h" #include "../scheduler/HydraTaskScheduler.h" #include "../task/buffer/HydraCreateGPUBufferTask.hpp" #include "../task/buffer/HydraUpdateWholeGPUBufferTask.hpp" #include "../task/buffer/HydraUpdatePartialGPUBufferTask.hpp" #include "../task/buffer/HydraCreateUnBoundTextureTask.hpp" #include "../task/renderer/HydraCreateCascadeShadowFrameBuffer.hpp" #include "../task/renderer/HydraCreateShadowFrameBuffer.hpp" void HydraShadowBufferManager::Initialise() { HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler(); for(uint32_t i = 0; i < MAX_DIRECTIONAL_SHADOWS; i++) { m_available_dir.push(i); } for(uint32_t i = 0; i < MAX_SPOT_SHADOWS; i++) { m_available_spot.push(i); } m_directional_shadow_buffer.resize(MAX_DIRECTIONAL_SHADOWS); m_spot_shadow_buffer.resize(MAX_SPOT_SHADOWS); uint32_t buffer_size = (MAX_DIRECTIONAL_SHADOWS * sizeof(HydraDirectionalShadowSourceComponent)); HydraID create_gpu_buffer_task_id = task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraCreateGPUBufferTask *task = static_cast(task_scheduler->GetTask(create_gpu_buffer_task_id)); task->Intialise("DirectionalShadowBuffer", 1, buffer_size, &m_directional_shadow_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER); task_scheduler->WaitForTask(create_gpu_buffer_task_id); buffer_size = (MAX_SPOT_SHADOWS * sizeof(HydraSpotShadowSourceComponent)); create_gpu_buffer_task_id = task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraCreateGPUBufferTask *spot_task = static_cast(task_scheduler->GetTask(create_gpu_buffer_task_id)); spot_task->Intialise("SpotShadowBuffer", 1, buffer_size, &m_spot_shadow_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER); task_scheduler->WaitForTask(create_gpu_buffer_task_id); } void HydraShadowBufferManager::Shutdown() { } HydraID HydraShadowBufferManager::AddDirectionalShadow(HydraDirectionalShadowSourceComponent shadow) { std::lock_guard lock(m_mutex); if(m_available_dir.size() == 0) { return INVALID_HYDRA_ID; } HydraID shadow_id = m_available_dir.front(); shadow.shadow_id = shadow_id; m_directional_shadow_buffer[shadow_id] = shadow; return shadow_id; } HydraID HydraShadowBufferManager::AddSpotShadow(HydraSpotShadowSourceComponent shadow) { std::lock_guard lock(m_mutex); if(m_available_spot.size() == 0) { return INVALID_HYDRA_ID; } HydraID shadow_id = m_available_spot.front(); m_spot_shadow_buffer[shadow_id] = shadow; return shadow_id; } void HydraShadowBufferManager::UpdateDirectionalShadow(HydraID shadow_id, HydraDirectionalShadowSourceComponent shadow) { std::lock_guard lock(m_mutex); if(shadow_id < MAX_DIRECTIONAL_SHADOWS) { m_directional_shadow_buffer[shadow_id] = shadow; } } void HydraShadowBufferManager::UpdateSpotShadow(HydraID shadow_id, HydraSpotShadowSourceComponent shadow) { std::lock_guard lock(m_mutex); if(shadow_id < MAX_SPOT_SHADOWS) { m_spot_shadow_buffer[shadow_id] = shadow; } } void HydraShadowBufferManager::RemoveDirectionalShadow(HydraID shadow_id) { } void HydraShadowBufferManager::RemoveSpotShadow(HydraID shadow_id) { } void HydraShadowBufferManager::UpdateShadowBuffer() { HydraEngine *engine = GetEngine(); HydraECS *ecs = engine->ECS(); HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler(); void *buffer = static_cast(m_directional_shadow_buffer.data()); HydraID update_buffer_task_id = task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraUpdateWholeGPUBufferTask *task = static_cast(task_scheduler->GetTask(update_buffer_task_id)); task->Intialise(m_directional_shadow_buffer_id, buffer); task_scheduler->WaitForTask(update_buffer_task_id); void *spot_buffer = static_cast(m_spot_shadow_buffer.data()); update_buffer_task_id = task_scheduler->CreateTask(HydraThreadAffinity::Render); HydraUpdateWholeGPUBufferTask *spot_task = static_cast(task_scheduler->GetTask(update_buffer_task_id)); spot_task->Intialise(m_spot_shadow_buffer_id, spot_buffer); task_scheduler->WaitForTask(update_buffer_task_id); }