This commit is contained in:
Confideo-IOM
2026-08-18 16:23:20 +01:00
parent 282243a16b
commit 20c0794d10
66 changed files with 622 additions and 1144 deletions
@@ -1,16 +0,0 @@
#ifndef HYDRALIGHTBUFFER
#define HYDRALIGHTBUFFER
#include <GLMIncludes.h>
struct HydraLightBuffer
{
alignas(16) glm::vec3 light_direction;
alignas(16) glm::vec3 light_colour;
uint32_t light_type;
float light_intensity;
float padding[2];
};
#endif /* HYDRALIGHTBUFFER */
@@ -1,44 +1,99 @@
#include "HydraLightBufferManager.h"
#include "../scheduler/HydraTaskScheduler.h"
#include "../engine/HydraEngine.h"
#include "../task/buffer/HydraCreateGPUBufferTask.hpp"
#include "../task/buffer/HydraDeleteGPUBufferTask.hpp"
#include "../task/buffer/HydraUpdatePartialGPUBufferTask.hpp"
#include "../ecs/components/HydraLightComponent.h"
void HydraLightBufferManager::Initialise()
{
m_light_lookup.resize(MAX_LIGHTS);
m_lights.resize(MAX_LIGHTS);
for(uint32_t i = 0; i < MAX_LIGHTS; i ++)
{
m_available_lights.push(i);
m_light_lookup[i] = INVALID_HYDRA_ID;
}
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID create_gpu_buffer_task_id = task_scheduler->CreateTask<HydraCreateGPUBufferTask>(HydraThreadAffinity::Render);
HydraCreateGPUBufferTask *task = static_cast<HydraCreateGPUBufferTask *>(task_scheduler->GetTask(create_gpu_buffer_task_id));
task->Intialise("LightBuffer", 1, MAX_LIGHTS * sizeof(HydraLightComponent), &m_light_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
}
void HydraLightBufferManager::Shutdown()
{
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID delete_gpu_buffer_task_id = task_scheduler->CreateTask<HydraDeleteGPUBufferTask>(HydraThreadAffinity::Render);
HydraDeleteGPUBufferTask *task = static_cast<HydraDeleteGPUBufferTask *>(task_scheduler->GetTask(delete_gpu_buffer_task_id));
task->Intialise(m_light_buffer_id);
task_scheduler->WaitForTask(delete_gpu_buffer_task_id);
}
HydraID HydraLightBufferManager::CreateLight(HydraLightBuffer light_buffer)
void HydraLightBufferManager::UpdateBuffer()
{
void *buffer = static_cast<void *>(m_lights.data());
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID update_buffer_task_id = task_scheduler->CreateTask<HydraUpdatePartialGPUBufferTask>(HydraThreadAffinity::Render);
HydraUpdatePartialGPUBufferTask *task = static_cast<HydraUpdatePartialGPUBufferTask *>(task_scheduler->GetTask(update_buffer_task_id));
task->Intialise(m_light_buffer_id, 0, sizeof(HydraLightComponent) * m_lights.size(), buffer);
task_scheduler->WaitForTask(update_buffer_task_id);
}
void HydraLightBufferManager::AddLight(HydraLightComponent light)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_lights.size() > 0)
if(m_available_lights.size() == 0)
{
HydraID light_id = m_available_lights.front();
m_available_lights.pop();
m_lights[m_light_count] = light_buffer;
m_light_lookup[light_id] = m_light_count;
m_light_count++;
return light_id;
return;
}
return INVALID_HYDRA_ID;
auto it = std::find(m_light_lookup.begin(), m_light_lookup.end(), light.entity_id);
if(it == m_light_lookup.end())
{
//light ID is not the index in the light buffer - this has to stay contiguous
m_lights.push_back(light);
m_light_lookup[m_light_count] = light.entity_id;
m_light_count++;
}
else
{
m_lights[m_light_lookup[*it]] = light;
}
}
HydraLightBuffer *const HydraLightBufferManager::GetLightBufferBase()
//Remove the light from the buffer and shuffle all of the others down to keep
//the light buffer contiguous.
void HydraLightBufferManager::RemoveLight(HydraID entity_id)
{
return &m_lights[0];
}
std::lock_guard<std::mutex> lock(m_mutex);
auto it = std::find(m_light_lookup.begin(), m_light_lookup.end(), entity_id);
if(it != m_light_lookup.end())
{
uint32_t remove_idx = it - m_light_lookup.begin();
//end one - easy
if(remove_idx == m_light_count-1)
{
m_lights.erase(m_lights.end()-1);
m_light_count--;
return;
}
HydraLightBuffer &HydraLightBufferManager::GetLightBuffer(HydraID light_id)
{
HydraID light_idx = m_light_lookup[light_id];
return m_lights[light_idx];
HydraLightComponent light_to_delete = m_lights[remove_idx];
HydraLightComponent light_to_move = m_lights[m_light_count-1];
m_lights[remove_idx] = light_to_move;
m_lights.erase(m_lights.end()-1);
m_light_lookup[m_light_count-1] = INVALID_HYDRA_ID;
m_light_lookup[remove_idx] = light_to_move.entity_id;
m_light_count--;
}
}
uint32_t HydraLightBufferManager::GetLightCount()
@@ -2,7 +2,8 @@
#define HYDRALIGHTBUFFERMANAGER
#include "../engine/HydraObject.h"
#include "HydraLightBuffer.h"
#include "../ecs/components/HydraLightComponent.h"
#include <vector>
#include <queue>
#include <mutex>
@@ -11,17 +12,18 @@ class HydraLightBufferManager : public HydraObject
{
public:
void Initialise();
void Shutdown();
HydraID CreateLight(HydraLightBuffer light_buffer);
HydraLightBuffer* const GetLightBufferBase();
HydraLightBuffer& GetLightBuffer(HydraID light_id);
void Shutdown();
uint32_t GetLightCount();
void UpdateBuffer();
void AddLight(HydraLightComponent light);
void RemoveLight(HydraID entity_id);
private:
std::mutex m_mutex;
uint32_t m_light_count = 0;
std::vector<HydraLightBuffer> m_lights;
std::vector<HydraLightComponent> m_lights;
std::queue<HydraID> m_available_lights;
std::vector<HydraID> m_light_lookup;
HydraID m_light_buffer_id = INVALID_HYDRA_ID;
};
#endif /* HYDRALIGHTBUFFERMANAGER */
@@ -4,7 +4,9 @@
#include "../task/buffer/HydraUpdateWholeGPUBufferTask.hpp"
#include "../task/buffer/HydraUpdatePartialGPUBufferTask.hpp"
#include "../task/buffer/HydraCreateUnBoundTextureTask.hpp"
#include "../task/buffer/HydraDeleteGPUBufferTask.hpp"
#include "../task/renderer/HydraCreateCascadeShadowFrameBuffer.hpp"
#include "../task/renderer/HydraCreateCubemapShadowFrameBuffer.hpp"
#include "../task/renderer/HydraCreateShadowFrameBuffer.hpp"
#include "../task/renderer/HydraDeleteShadowFrameBufferTask.hpp"
#include "../ecs/components/HydraDirectionalShadowSourceComponent.h"
@@ -52,9 +54,24 @@ void HydraShadowBufferManager::Initialise()
}
void HydraShadowBufferManager::Shutdown()
{
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
uint32_t delete_gpu_buffer_task_id = task_scheduler->CreateTask<HydraDeleteGPUBufferTask>(HydraThreadAffinity::Render);
HydraDeleteGPUBufferTask *point_task = static_cast<HydraDeleteGPUBufferTask *>(task_scheduler->GetTask(delete_gpu_buffer_task_id));
point_task->Intialise(m_point_shadow_buffer_id);
task_scheduler->WaitForTask(delete_gpu_buffer_task_id);
delete_gpu_buffer_task_id = task_scheduler->CreateTask<HydraDeleteGPUBufferTask>(HydraThreadAffinity::Render);
HydraDeleteGPUBufferTask *dir_task = static_cast<HydraDeleteGPUBufferTask *>(task_scheduler->GetTask(delete_gpu_buffer_task_id));
dir_task->Intialise(m_directional_shadow_buffer_id);
task_scheduler->WaitForTask(delete_gpu_buffer_task_id);
delete_gpu_buffer_task_id = task_scheduler->CreateTask<HydraDeleteGPUBufferTask>(HydraThreadAffinity::Render);
HydraDeleteGPUBufferTask *spot_task = static_cast<HydraDeleteGPUBufferTask *>(task_scheduler->GetTask(delete_gpu_buffer_task_id));
spot_task->Intialise(m_point_shadow_buffer_id);
task_scheduler->WaitForTask(delete_gpu_buffer_task_id);
}
HydraID HydraShadowBufferManager::AddDirectionalShadow(HydraDirectionalShadowSourceComponent shadow)
HydraID HydraShadowBufferManager::AddDirectionalShadow(HydraDirectionalShadowSourceComponent& shadow)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_dir.size() == 0)
@@ -65,9 +82,27 @@ HydraID HydraShadowBufferManager::AddDirectionalShadow(HydraDirectionalShadowSou
HydraID shadow_id = m_available_dir.front();
shadow.shadow_id = shadow_id;
m_directional_shadow_buffer[shadow_id] = shadow;
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
uint32_t depth_texture_id = 0;
uint32_t frame_buffer_id = 0;
HydraID create_framebuffer_task_id = task_scheduler->CreateTask<HydraCreateCascadeShadowFrameBuffer>(HydraThreadAffinity::Render);
HydraCreateCascadeShadowFrameBuffer *fb_task = static_cast<HydraCreateCascadeShadowFrameBuffer *>(task_scheduler->GetTask(create_framebuffer_task_id));
fb_task->Initialise(&depth_texture_id, &frame_buffer_id);
task_scheduler->WaitForTask(create_framebuffer_task_id);
shadow.shadow_texture_id = depth_texture_id;
shadow.frame_buffer_id = frame_buffer_id;
return shadow_id;
}
HydraID HydraShadowBufferManager::AddSpotShadow(HydraSpotShadowSourceComponent shadow)
HydraID HydraShadowBufferManager::AddSpotShadow(HydraSpotShadowSourceComponent& shadow)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_spot.size() == 0)
@@ -77,10 +112,26 @@ HydraID HydraShadowBufferManager::AddSpotShadow(HydraSpotShadowSourceComponent s
HydraID shadow_id = m_available_spot.front();
m_spot_shadow_buffer[shadow_id] = shadow;
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
uint32_t depth_texture_id = 0;
uint32_t frame_buffer_id = 0;
HydraID create_framebuffer_task_id = task_scheduler->CreateTask<HydraCreateShadowFrameBuffer>(HydraThreadAffinity::Render);
HydraCreateShadowFrameBuffer *fb_task = static_cast<HydraCreateShadowFrameBuffer *>(task_scheduler->GetTask(create_framebuffer_task_id));
fb_task->Initialise(&depth_texture_id, &frame_buffer_id);
task_scheduler->WaitForTask(create_framebuffer_task_id);
shadow.shadow_texture_id = depth_texture_id;
shadow.frame_buffer_id = frame_buffer_id;
return shadow_id;
}
HydraID HydraShadowBufferManager::AddPointShadow(HydraPointShadowSourceComponent shadow)
HydraID HydraShadowBufferManager::AddPointShadow(HydraPointShadowSourceComponent& shadow)
{
std::lock_guard<std::mutex> lock(m_mutex);
if(m_available_point.size() == 0)
@@ -90,6 +141,24 @@ HydraID HydraShadowBufferManager::AddPointShadow(HydraPointShadowSourceComponent
HydraID shadow_id = m_available_point.front();
m_point_shadow_buffer[shadow_id] = shadow;
HydraEngine *engine = GetEngine();
HydraECS *ecs = engine->ECS();
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
uint32_t depth_texture_id = 0;
uint32_t frame_buffer_id = 0;
HydraID create_framebuffer_task_id = task_scheduler->CreateTask<HydraCreateCubemapShadowFrameBuffer>(HydraThreadAffinity::Render);
HydraCreateCubemapShadowFrameBuffer *fb_task = static_cast<HydraCreateCubemapShadowFrameBuffer *>(task_scheduler->GetTask(create_framebuffer_task_id));
fb_task->Initialise( &depth_texture_id, &frame_buffer_id);
task_scheduler->WaitForTask(create_framebuffer_task_id);
shadow.shadow_texture_id = depth_texture_id;
shadow.frame_buffer_id = frame_buffer_id;
return shadow_id;
}
@@ -131,6 +200,7 @@ void HydraShadowBufferManager::DeleteDirectionalShadow(HydraID shadow_id)
fb_task->Initialise(shadow_comp.shadow_texture_id, shadow_comp.frame_buffer_id);
task_scheduler->WaitForTask(delete_frame_buffer_task_id);
m_available_dir.push(shadow_id);
}
void HydraShadowBufferManager::DeleteSpotShadow(HydraID shadow_id)
{
@@ -143,6 +213,7 @@ void HydraShadowBufferManager::DeleteSpotShadow(HydraID shadow_id)
fb_task->Initialise(shadow_comp.shadow_texture_id, shadow_comp.frame_buffer_id);
task_scheduler->WaitForTask(delete_frame_buffer_task_id);
m_available_spot.push(shadow_id);
}
void HydraShadowBufferManager::DeletePointShadow(HydraID shadow_id)
@@ -156,6 +227,7 @@ void HydraShadowBufferManager::DeletePointShadow(HydraID shadow_id)
fb_task->Initialise(shadow_comp.shadow_texture_id, shadow_comp.frame_buffer_id);
task_scheduler->WaitForTask(delete_frame_buffer_task_id);
m_available_point.push(shadow_id);
}
void HydraShadowBufferManager::UpdateShadowBuffer()
@@ -15,9 +15,9 @@ class HydraShadowBufferManager : public HydraObject
public:
void Initialise();
void Shutdown();
HydraID AddDirectionalShadow(HydraDirectionalShadowSourceComponent shadow);
HydraID AddSpotShadow(HydraSpotShadowSourceComponent shadow);
HydraID AddPointShadow(HydraPointShadowSourceComponent shadow);
HydraID AddDirectionalShadow(HydraDirectionalShadowSourceComponent& shadow);
HydraID AddSpotShadow(HydraSpotShadowSourceComponent& shadow);
HydraID AddPointShadow(HydraPointShadowSourceComponent& shadow);
void UpdateDirectionalShadow(HydraID shadow_id, HydraDirectionalShadowSourceComponent shadow);
void UpdateSpotShadow(HydraID shadow_id, HydraSpotShadowSourceComponent shadow);
@@ -29,6 +29,8 @@ class HydraShadowBufferManager : public HydraObject
void UpdateShadowBuffer();
private:
std::vector<HydraDirectionalShadowSourceComponent> m_directional_shadow_buffer;
std::vector<HydraSpotShadowSourceComponent> m_spot_shadow_buffer;
std::vector<HydraPointShadowSourceComponent> m_point_shadow_buffer;
@@ -39,6 +41,7 @@ class HydraShadowBufferManager : public HydraObject
uint32_t m_spot_shadow_buffer_id;
uint32_t m_point_shadow_buffer_id;
std::mutex m_mutex;
};
#endif /* HYDRASHADOWBUFFERMANAGER */
@@ -242,19 +242,15 @@ void HydraTextureBufferManager::BindTexture(HydraID texture_id, uint32_t target)
HydraTextureBuffer texture = m_textures[texture_id];
glBindTexture(target, texture.gl_tex_id);
// glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_WRAP_S, GL_REPEAT);
// glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_WRAP_T, GL_REPEAT);
// glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_MIN_FILTER, texture.min_filter);
// glTextureParameteri(texture.gl_tex_id, GL_TEXTURE_MAG_FILTER, texture.mag_filter);
texture.texture_binding = glGetTextureHandleARB(texture.gl_tex_id);
glMakeTextureHandleResidentARB(texture.texture_binding);
m_bindless_texture_ids[texture_id] = texture.texture_binding;
}
void HydraTextureBufferManager::UnbindTexture(HydraID texture_id)
void HydraTextureBufferManager::UnbindTexture(HydraID gl_texture_id)
{
glMakeTextureHandleNonResidentARB(texture_id);
glMakeTextureHandleNonResidentARB(gl_texture_id);
}
void HydraTextureBufferManager::DeleteTexture(HydraID texture_id)
@@ -262,6 +258,7 @@ void HydraTextureBufferManager::DeleteTexture(HydraID texture_id)
if (m_bindless_texture_ids[texture_id] != 0)
{
UnbindTexture(m_bindless_texture_ids[texture_id]);
m_bindless_texture_ids[texture_id]=0;
}
glDeleteTextures(1, &m_textures[texture_id].gl_tex_id);
}