Shadows - need to fix frame buffers

This commit is contained in:
Confideo-IOM
2026-07-28 00:26:04 +01:00
parent 3810f74e81
commit d48097c645
54 changed files with 623 additions and 100 deletions
+2
View File
@@ -41,6 +41,8 @@ const uint32_t MAX_MATERIALS = 1000;
const uint32_t MAX_TEXTURES = 1000;
const uint32_t MAX_ACTORS = 10000;
const uint32_t MAX_LIGHTS = 500;
const uint32_t MAX_SHADOWS = 10;
const uint32_t SHADOW_MAP_SIZE = 1024;
enum class HYDRA_RENDERABLE_TYPE
@@ -45,7 +45,7 @@ layout(binding = 1) uniform uniform_output_textures
uint texture_ids[16];
};
layout(binding = 1) readonly buffer PositionsBuffer
layout(std430, binding = 1) readonly buffer PositionsBuffer
{
mat4 model_matrix[];
};
@@ -9,7 +9,7 @@ layout(binding = 0) uniform uniform_per_frame
uint light_count;
} ubo_per_frame;
layout(binding = 1) readonly buffer PositionsBuffer
layout(std430, binding = 1) readonly buffer PositionsBuffer
{
mat4 model_matrix[];
};
@@ -9,7 +9,7 @@ layout(binding = 0) uniform uniform_per_frame
uint light_count;
} ubo_per_frame;
layout(binding = 1) readonly buffer PositionsBuffer
layout(std430, binding = 1) readonly buffer PositionsBuffer
{
mat4 model_matrix[];
};
@@ -0,0 +1,17 @@
//*PIXEL*
#version 450
#extension GL_EXT_scalar_block_layout : enable
#extension GL_EXT_nonuniform_qualifier : enable
const uint DIRECTIONAL_LIGHT = 1;
const uint POINT_LIGHT = 2;
const uint SPOT_LIGHT = 3;
void main()
{
//gl_FragDepth = gl_FragCoord.z;
}
@@ -0,0 +1,45 @@
#version 450
layout(triangles, invocations = 6) in;
layout(triangle_strip, max_vertices = 3) out;
struct ShadowMapSet
{
uint entity_id;
uint cascade_count;
uint shadow_texture_id;
uint padding0;
float near_plane[8];
float far_plane[8];
mat4 light_space_proj[6];
mat4 light_space_view[6];
};
//Push constants updated for each light
layout(binding = 0) uniform shadow_per_frame
{
vec3 camera_pos;
uint shadow_idxs;
};
layout(std430, binding = 0) readonly buffer ShadowMapSets
{
ShadowMapSet shadows[10];
};
void main()
{
for (int i = 0; i < 3; ++i)
{
gl_Position = shadows[shadow_idxs].light_space_proj[gl_InvocationID] *
shadows[shadow_idxs].light_space_view[gl_InvocationID] *
gl_in[i].gl_Position;
gl_Layer = gl_InvocationID;
EmitVertex();
}
EndPrimitive();
}
@@ -0,0 +1,23 @@
//*VERTEX*
#version 450
#extension GL_EXT_buffer_reference : enable
layout(binding = 1) readonly buffer PositionsBuffer
{
mat4 model_matrix[];
};
layout (location = 0) in vec3 inPos; //12 bytes : 0
layout (location = 1) in vec2 inUV; //8 Bytes : 12
layout (location = 2) in uvec3 inChunkID; //12 Bytes : 20
layout (location = 3) in vec3 inNormal; //8 Bytes : 12
layout (location = 4) in vec3 inBiTangent;
layout (location = 5) in vec3 inTangent;
void main()
{
uint chunkid = inChunkID[0];
mat4 model = model_matrix[chunkid];
gl_Position = model * vec4(inPos, 1.0);
}
@@ -23,35 +23,35 @@ void HydraOutputActor::_CreateMaterial()
render_settings.DisplayHeight,
GL_RGBA8,
GL_NEAREST,
GL_NEAREST);
GL_NEAREST, 1);
HydraID depth = engine->TextureBufferManager()->CreateTexture("deferred_depth",
render_settings.DisplayWidth,
render_settings.DisplayHeight,
GL_DEPTH_COMPONENT24,
GL_NEAREST,
GL_NEAREST);
GL_NEAREST, 1);
HydraID metal_rough = engine->TextureBufferManager()->CreateTexture("deferred_metal_rough_buffer",
render_settings.DisplayWidth,
render_settings.DisplayHeight,
GL_RGBA8,
GL_NEAREST,
GL_NEAREST);
GL_NEAREST, 1);
HydraID normal = engine->TextureBufferManager()->CreateTexture("deferred_normal_buffer",
render_settings.DisplayWidth,
render_settings.DisplayHeight,
GL_RGBA32F,
GL_NEAREST,
GL_NEAREST);
GL_NEAREST, 1);
HydraID position = engine->TextureBufferManager()->CreateTexture("deferred_position_buffer",
render_settings.DisplayWidth,
render_settings.DisplayHeight,
GL_RGBA32F,
GL_NEAREST,
GL_NEAREST);
GL_NEAREST, 1);
// engine->TextureBufferManager()->BindTexture(depth);
@@ -0,0 +1,17 @@
#ifndef HYDRASHADOWBUFFER
#define HYDRASHADOWBUFFER
#include "../engine/HydraEngine.h"
struct HydraShadowBuffer
{
uint32_t entity_id;
uint32_t cascade_count;
uint32_t shadow_texture_id;
uint32_t padding0;
float near_plane[8];
float far_plane[8];
glm::mat4 light_space_proj[6];
glm::mat4 light_space_view[6];
};
#endif /* HYDRASHADOWBUFFER */
@@ -64,6 +64,7 @@ HydraID HydraTextureBufferManager::LoadTexture(std::string texture_filename)
format,
GL_NEAREST_MIPMAP_NEAREST,
GL_LINEAR,
1,
GL_UNSIGNED_BYTE,
5,
data,
@@ -112,6 +113,7 @@ HydraID HydraTextureBufferManager::CreateTexture(std::string texture_name,
uint32_t internal_format,
uint32_t min_filter,
uint32_t mag_filter,
uint32_t levels,
uint32_t format,
uint32_t data_type,
uint32_t mip_levels,
@@ -121,8 +123,8 @@ HydraID HydraTextureBufferManager::CreateTexture(std::string texture_name,
glCreateTextures(GL_TEXTURE_2D, 1, &gl_tex_id);
glBindTexture(GL_TEXTURE_2D, gl_tex_id);
// important to create mip_levels + 1 images
glTextureStorage2D(gl_tex_id, mip_levels + 1, internal_format, width, height);
glTextureStorage2D(gl_tex_id, levels, internal_format, width, height);
if (data != nullptr)
{
@@ -19,7 +19,7 @@ class HydraTextureBufferManager : public HydraObject
void Intialise();
void Shutdown();
HydraID CreateTexture(std::string texture_name, uint32_t width, uint32_t height, uint32_t internal_format,
uint32_t min_filter, uint32_t mag_filter,
uint32_t min_filter, uint32_t mag_filter, uint32_t levels,
uint32_t format = GL_RGBA, uint32_t data_type = GL_UNSIGNED_BYTE, uint32_t mip_levels = 0, void* data = nullptr);
void BindTexture(HydraID texture_id);
void UnbindTexture(HydraID texture_id);
@@ -26,11 +26,9 @@ public:
template <typename T> std::shared_ptr<T> GetSystem()
{
std::string type_name = std::string(typeid(T).name());
auto it = m_systems.find(type_name);
assert(it!= m_systems.end() && "System not found.");
return std::static_pointer_cast<T>( it->second);
}
template <typename T>
@@ -50,12 +48,9 @@ public:
template<typename T> void SetSignature(HydraSignature signature)
{
std::string type_name = std::string(typeid(T).name());
assert(m_systems.find(type_name) != m_systems.end() && "System used before registered.");
// Set the signature for this system
m_signatures.insert({type_name, signature});
}
void EntitySignatureChanged(HydraID entity_id, HydraSignature signature)
{
@@ -11,7 +11,8 @@ struct HydraShadowSourceComponent
uint32_t padding0;
float near_plane[8];
float far_plane[8];
glm::mat4 projection[6];
glm::mat4 light_space_proj[6];
glm::mat4 light_space_view[6];
};
#endif /* HYDRACASTERCOMPONENT */
@@ -1,9 +1,140 @@
#include "HydraShadowSourceSystem.h"
#include "../../engine/HydraEngine.h"
#include "../../camera/HydraCamera.h"
#include "../HydraECS.h"
#include "../components/HydraShadowSourceComponent.h"
#include "../components/HydraPositionComponent.h"
#include "../components/HydraLightComponent.h"
#include "../../buffer/HydraShadowBuffer.h"
#include "../../buffer/HydraTextureBufferManager.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 "../../actor/HydraActorManager.h"
void HydraShadowSourceSystem::Initialise()
{
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("ShadowBuffer", 1, MAX_SHADOWS * sizeof(HydraShadowBuffer), &m_shadow_buffer_id, HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
task_scheduler->WaitForTask(create_gpu_buffer_task_id);
}
void HydraShadowSourceSystem::InitialiseComponent(HydraID entity_id)
{
{
HydraEngine* engine = GetEngine();
HydraECS* ecs = engine->ECS();
HydraLightComponent& light_comp = ecs->GetComponent<HydraLightComponent>(entity_id);
switch(light_comp.light_type)
{
case (int)HYDRA_LIGHT_TYPE::HYDRA_LIGHT_DIRECTIONAL:
_InitialiseDirectionalLight(entity_id);
break;
}
}
void HydraShadowSourceSystem::UpdateSystem(float delta_t_seconds)
{
HydraEngine* engine = GetEngine();
HydraECS* ecs = engine->ECS();
std::vector<HydraShadowSourceComponent> shadows;
for(HydraID entity_id:Entities)
{
HydraLightComponent& light_comp = ecs->GetComponent<HydraLightComponent>(entity_id);
switch(light_comp.light_type)
{
case (int)HYDRA_LIGHT_TYPE::HYDRA_LIGHT_DIRECTIONAL:
_UpdateDirectionalLight(entity_id);
break;
}
HydraShadowSourceComponent shad_comp = ecs->GetComponent<HydraShadowSourceComponent>(entity_id);
shadows.push_back(shad_comp);
}
_WriteToGPU(shadows);
}
void HydraShadowSourceSystem::_UpdateDirectionalLight(HydraID entity_id)
{
HydraEngine* engine = GetEngine();
HydraECS* ecs = engine->ECS();
HydraPositionComponent pos_comp = ecs->GetComponent<HydraPositionComponent>(entity_id);
HydraShadowSourceComponent& shad_comp = ecs->GetComponent<HydraShadowSourceComponent>(entity_id);
float view_size = 5.0f;
float view_near = -5.0f;
float view_far = 5.0f;
float PI = 3.1415927;
float TWO_PI = 6.2831854;
glm::vec3 light_dir = glm::vec3(0, 0, -1);
glm::mat3 light_rot = glm::mat3(1);
glm::vec3 light_euler = pos_comp.orientation;
light_rot = glm::eulerAngleXYZ(light_euler.x, light_euler.y, light_euler.z);
light_dir = light_rot * light_dir;
light_dir = glm::normalize(light_dir);
glm::vec3 camera_pos = GetEngine()->Camera()->GetPosition();
for (uint32_t i = 0; i < 6; i++)
{
glm::vec3 light_pos = camera_pos; // - (light_dir * light_distance);
glm::mat4 light_trans = glm::translate(light_pos * glm::vec3(-1, -1, -1));
glm::mat4 light_orient = glm::eulerAngleXYZ(light_euler.x, light_euler.y, light_euler.z);
glm::mat4 view = light_orient * light_trans;
glm::mat4 proj = glm::orthoRH<float>(view_size, -view_size, -view_size, view_size, -15000, 15000);
// glm::mat4 proj = glm::orthoRH<float>(view_size, -view_size, -view_size, view_size, view_near, view_far);
shad_comp.far_plane[i] = view_far;
shad_comp.near_plane[i] = view_near;
shad_comp.light_space_proj[i] = proj;
shad_comp.light_space_view[i] = view;
view_far *= 3.0f;
view_near = -view_far;
view_size *= 3.0f;
}
}
void HydraShadowSourceSystem::_InitialiseDirectionalLight(HydraID entity_id)
{
HydraEngine* engine = GetEngine();
HydraECS* ecs = engine->ECS();
HydraTextureBufferManager* tex_man = engine->TextureBufferManager();
HydraShadowSourceComponent& shad_comp = ecs->GetComponent<HydraShadowSourceComponent>(entity_id);
shad_comp.entity_id = entity_id;
shad_comp.cascade_count = 6;
HydraTaskScheduler *task_scheduler = GetEngine()->TaskScheduler();
HydraID create_texture_task_id = task_scheduler->CreateTask<HydraCreateUnBoundTextureTask>(HydraThreadAffinity::Render);
HydraCreateUnBoundTextureTask *task = static_cast<HydraCreateUnBoundTextureTask *>(task_scheduler->GetTask(create_texture_task_id));
task->Initialise("shadow", SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, GL_R32F, GL_R32F, GL_LINEAR, GL_LINEAR, 6, GL_BYTE, 0, nullptr, &shad_comp.shadow_texture_id);
task_scheduler->WaitForTask(create_texture_task_id);
}
void HydraShadowSourceSystem::_WriteToGPU(std::vector<HydraShadowSourceComponent> shadows)
{
HydraEngine* engine = GetEngine();
HydraECS* ecs = engine->ECS();
void *buffer = static_cast<void *>(shadows.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_shadow_buffer_id, 0, sizeof(HydraLightComponent) * shadows.size(), buffer);
task_scheduler->WaitForTask(update_buffer_task_id);
}
@@ -2,6 +2,7 @@
#define HYDRASHADOWSOURCESYSTEM
#include "../../engine/HydraObject.h"
#include "../HydraSystem.h"
#include "../components/HydraShadowSourceComponent.h"
#include <GLMIncludes.h>
#include <queue>
@@ -10,8 +11,15 @@ class HydraShadowSourceSystem : public HydraSystem
public:
virtual void Initialise() override;
protected:
virtual void InitialiseComponent(HydraID entity_id) override;
void UpdateSystem(float delta_t_seconds) override {}
void InitialiseComponent(HydraID entity_id) override;
void UpdateSystem(float delta_t_seconds) override;
private:
void _UpdateDirectionalLight(HydraID entity_id);
void _InitialiseDirectionalLight(HydraID entity_id);
void _WriteToGPU(std::vector<HydraShadowSourceComponent> shadows);
HydraID m_shadow_buffer_id = INVALID_HYDRA_ID;
};
#endif /* HYDRASHADOWCASTERSYSTEM */
+28 -1
View File
@@ -36,6 +36,7 @@
#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"
@@ -51,6 +52,8 @@
#include "../task/buffer/HydraShutdownBufferManagerTask.hpp"
#include "../task/buffer/HydraInitialiseTextureManagerTask.hpp"
#include "../task/actor/HydraUpdatePlayerTask.h"
#include "../task/renderer/HydraBeginRenderTask.hpp"
#include "../task/renderer/HydraEndRenderTask.hpp"
#include "../mesh/HydraMeshManager.h"
HydraTaskScheduler *const HydraEngine::TaskScheduler()
@@ -177,6 +180,7 @@ void HydraEngine::_CreateManagers()
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();
@@ -238,13 +242,14 @@ void HydraEngine::_InitialiseSystems()
shadow_sig.set(m_ecs->GetComponentType<HydraLightComponent>(), true);
shadow_sig.set(m_ecs->GetComponentType<HydraPositionComponent>(), true);
shadow_sig.set(m_ecs->GetComponentType<HydraShadowSourceComponent>(), true);
m_ecs->SetSystemSignature<HydraMeshSystem>(mesh_sig);
m_ecs->SetSystemSignature<HydraTransformSystem>(trans_sig);
m_ecs->SetSystemSignature<HydraRenderSystem>(render_sig);
m_ecs->SetSystemSignature<HydraMaterialSystem>(material_sig);
m_ecs->SetSystemSignature<HydraLightSystem>(light_sig);
m_ecs->SetSystemSignature<HydraShadowSourceSystem>(shadow_sig);
}
void HydraEngine::_UpdateSystems()
@@ -268,6 +273,12 @@ void HydraEngine::_InitialiseSystems()
HydraUpdateSystemTask* update_light_task = static_cast<HydraUpdateSystemTask*>(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 update_shadow_id = m_task_scheduler->CreateTask<HydraUpdateSystemTask>(HydraThreadAffinity::General);
HydraUpdateSystemTask* update_shadow_task = static_cast<HydraUpdateSystemTask*>(m_task_scheduler->GetTask(update_shadow_id));
update_shadow_task->Initialise(m_delta_t, m_shadow_system);
m_task_scheduler->WaitForTask(update_shadow_id);
}
void HydraEngine::_GameLoop()
@@ -296,6 +307,11 @@ void HydraEngine::_GameLoop()
pipeline_task->Initialise(m_pipeline);
m_task_scheduler->WaitForTask(initialise_pipeline_task_id);
HydraID initialise_shadow_pipeline_task_id = m_task_scheduler->CreateTask<HydraInitialisePipelineTask>(HydraThreadAffinity::Render);
HydraInitialisePipelineTask *pipeline_shadow_task = static_cast<HydraInitialisePipelineTask*>(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<HydraInitialisePipelineTask>(HydraThreadAffinity::Render);
HydraInitialisePipelineTask *pipeline_def_task = static_cast<HydraInitialisePipelineTask*>(m_task_scheduler->GetTask(initialise_def_pipeline_task_id));
pipeline_def_task->Initialise(m_deferred_pipeline);
@@ -349,10 +365,21 @@ void HydraEngine::_GameLoop()
// render_task->Initialise(m_pipeline);
// m_task_scheduler->WaitForTask(render_task_id);
HydraID begin_task_id = m_task_scheduler->CreateTask<HydraBeginRenderTask>(HydraThreadAffinity::Render);
m_task_scheduler->WaitForTask(begin_task_id);
HydraID render_shadow_task_id = m_task_scheduler->CreateTask<HydraRenderPipelineTask>(HydraThreadAffinity::Render);
HydraRenderPipelineTask* render_shadow_task = static_cast<HydraRenderPipelineTask*>(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<HydraRenderPipelineTask>(HydraThreadAffinity::Render);
HydraRenderPipelineTask* render_def_task = static_cast<HydraRenderPipelineTask*>(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<HydraEndRenderTask>(HydraThreadAffinity::Render);
m_task_scheduler->WaitForTask(end_task_id);
}
}
+2
View File
@@ -83,6 +83,7 @@ private:
HydraRenderSettings m_render_settings;
HydraPipeline* m_pipeline = nullptr;
HydraPipeline* m_deferred_pipeline = nullptr;
HydraPipeline* m_shadow_pipeline = nullptr;
HydraTextureBufferManager* m_texture_buffer_manager = nullptr;
HydraMaterialBufferManager* m_material_buffer_manager = nullptr;
HydraLightBufferManager* m_light_buffer_manager = nullptr;
@@ -93,6 +94,7 @@ private:
std::shared_ptr<HydraMaterialSystem> m_material_system;
std::shared_ptr<HydraLightSystem> m_light_system;
std::shared_ptr<HydraShadowSourceSystem> m_shadow_system;
bool m_running = true;
float m_delta_t = 0.0f;
@@ -286,6 +286,7 @@ void HydraGLTFLoader::_ProcessGLTFTextures(aiScene const *scene, std::vector<uin
GL_RGBA8,
GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR,
1,
GL_RGBA,
GL_UNSIGNED_BYTE,
5,
@@ -48,8 +48,7 @@ void HydraDeferredPipeline::Render()
HydraECS* ecs = GetEngine()->ECS();
std::shared_ptr<HydraRenderSystem> render_system = ecs->GetSystem<HydraRenderSystem>();
GetEngine()->Renderer()->BeginFrame();
GetEngine()->Renderer()->BeginFrame();
for(uint32_t rs_idx = 0; rs_idx <m_render_stages.size(); rs_idx++)
{
m_render_stages[rs_idx]->Render(render_system->Entities);
@@ -176,7 +175,7 @@ void HydraDeferredPipeline::_CreateColourRenderStage()
render_stage->Initialise(shader_path + "deferred_shader.vert",
shader_path + "deferred_shader.frag",
shader_path + "deferred_shader.frag", "",
shader_binding,
m_frame_buffer_id,
textures,
@@ -234,7 +233,7 @@ void HydraDeferredPipeline::_CreateOutputRenderStage()
render_stage->Initialise(shader_path + "deferred_output_shader.vert",
shader_path + "deferred_output_shader.frag",
shader_path + "deferred_output_shader.frag", "",
shader_binding,
0,
textures,
@@ -36,14 +36,11 @@ void HydraForwardPipeline::Initialise()
std::vector<uint32_t> textures;
std::vector<uint32_t> rb_attachments;
render_stage->Initialise(shader_path + "forward_shader.vert", shader_path + "forward_shader.frag", shader_binding, 0, textures, true, HYDRA_RENDERABLE_TYPE::HYDRA_COLOUR);
render_stage->Initialise(shader_path + "forward_shader.vert", shader_path + "forward_shader.frag", "", shader_binding, 0, textures, true, HYDRA_RENDERABLE_TYPE::HYDRA_COLOUR);
m_render_stages.push_back(render_stage);
m_per_frame_ubo = buffer_manager->CreateGPUBuffer("PerFrameUBO",
sizeof(PerFrameUBO), 0, HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
sizeof(PerFrameUBO), 0, HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
}
@@ -14,6 +14,7 @@
void HydraRenderStage::Initialise(std::string vertex_shader_file,
std::string fragment_shader_file,
std::string geometry_shader_file,
HydraShaderBinding shader_binding,
uint32_t framebuffer_id,
std::vector<uint32_t> textures,
@@ -25,21 +26,23 @@ void HydraRenderStage::Initialise(std::string vertex_shader_file,
m_shader_binding = shader_binding;
m_textures = textures;
m_cull = enable_culling;
m_program = glCreateProgram();
if(vertex_shader_file.length() > 0)
{
m_vertex_shader = _LoadShader(vertex_shader_file, GL_VERTEX_SHADER);
glAttachShader(m_program, m_vertex_shader);
}
if(fragment_shader_file.length() > 0)
{
m_fragment_shader = _LoadShader(fragment_shader_file, GL_FRAGMENT_SHADER);
glAttachShader(m_program, m_fragment_shader);
}
if(geometry_shader_file.length() > 0)
{
m_geometry_shader = _LoadShader(geometry_shader_file, GL_GEOMETRY_SHADER);
glAttachShader(m_program, m_geometry_shader);
}
m_program = glCreateProgram();
glAttachShader(m_program, m_vertex_shader);
glAttachShader(m_program, m_fragment_shader);
glLinkProgram(m_program);
}
void HydraRenderStage::ShutDown()
@@ -12,6 +12,7 @@ class HydraRenderStage : public HydraObject
public:
void Initialise(std::string vertex_shader_file,
std::string fragment_shader_file,
std::string geometry_shader_file,
HydraShaderBinding shader_binding,
uint32_t framebuffer_id,
std::vector<uint32_t> textures,
@@ -27,6 +28,7 @@ class HydraRenderStage : public HydraObject
HydraShaderBinding m_shader_binding;
uint32_t m_vertex_shader = GL_INVALID_VALUE;
uint32_t m_fragment_shader = GL_INVALID_VALUE;
uint32_t m_geometry_shader = GL_INVALID_VALUE;
uint32_t m_program = GL_INVALID_VALUE;
uint32_t m_renderable_type;
uint32_t m_framebuffer_id = 0;
@@ -0,0 +1,141 @@
#include "HydraShadowPipeline.h"
#include "HydraRenderStage.h"
#include "../engine/HydraEngine.h"
#include "../buffer/HydraBufferManager.h"
#include "../buffer/HydraTextureBufferManager.h"
#include "../buffer/HydraLightBufferManager.h"
#include "PerFrameUBO.hpp"
#include "../camera/HydraCamera.h"
#include "../renderer/HydraRenderer.h"
#include "../ecs/HydraECS.h"
#include "../ecs/systems/HydraRenderSystem.h"
#include "../ecs/systems/HydraShadowSourceSystem.h"
#include "../mesh/StandardVertex.h"
#include "../actor/HydraActorManager.h"
#include "../actor/HydraOutputActor.h"
void HydraShadowPipeline::Initialise()
{
_CreateUBOs();
_CreateFrameBuffer();
_CreateRenderStage();
}
void HydraShadowPipeline::Shutdown()
{
}
void HydraShadowPipeline::Render()
{
HydraECS* ecs = GetEngine()->ECS();
std::shared_ptr<HydraRenderSystem> render_system = ecs->GetSystem<HydraRenderSystem>();
std::shared_ptr<HydraShadowSourceSystem> shadow_system = ecs->GetSystem<HydraShadowSourceSystem>();
uint32_t shadow_idx =0;
for(HydraID entity_id:shadow_system->Entities)
{
_UpdateUBO(shadow_idx);
_BindFrameBufferAttachments(entity_id);
GetEngine()->Renderer()->BeginFrame();
for(uint32_t rs_idx = 0; rs_idx <m_render_stages.size(); rs_idx++)
{
m_render_stages[rs_idx]->Render(render_system->Entities);
}
GetEngine()->Renderer()->EndFrame();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
shadow_idx++;
}
}
void HydraShadowPipeline::_CreateRenderStage()
{
HydraRenderStage* render_stage = new HydraRenderStage();
std::string shader_path = std::string(shader_base);
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
HydraID pos_buffer_id = buffer_manager->FindBuffer("PositionsBuffer");
HydraID shadow_buffer_id = buffer_manager->FindBuffer("ShadowBuffer");
HydraID per_frame_buffer_id = buffer_manager->FindBuffer("ShadowPerFrameUBO");
HydraShaderBinding shader_binding = {};
shader_binding.block_name.push_back("PositionsBuffer");
shader_binding.binding_point.push_back(1);
shader_binding.buffer_id.push_back(pos_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("ShadowMapSets");
shader_binding.binding_point.push_back(0);
shader_binding.buffer_id.push_back(shadow_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER);
shader_binding.block_name.push_back("shadow_per_frame");
shader_binding.binding_point.push_back(0);
shader_binding.buffer_id.push_back(per_frame_buffer_id);
shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
std::vector<uint32_t> textures;
render_stage->Initialise(shader_path + "shadow_shader.vert",
shader_path + "shadow_shader.frag",
shader_path + "shadow_shader.geom",
shader_binding,
m_frame_buffer_id,
textures,
true,
HYDRA_RENDERABLE_TYPE::HYDRA_COLOUR);
m_render_stages.push_back(render_stage);
}
void HydraShadowPipeline::_UpdateUBO(uint32_t shadow_idx)
{
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
buffer_manager->UpdatePartialBuffer(m_per_frame_ubo,3*sizeof(float), sizeof(uint32_t), &shadow_idx);
glBindBuffer(GL_UNIFORM_BUFFER, m_per_frame_ubo);
}
void HydraShadowPipeline::_BindFrameBufferAttachments(HydraID entity_id)
{
HydraShadowSourceComponent shad_comp = GetEngine()->ECS()->GetComponent<HydraShadowSourceComponent>(entity_id);
HydraTextureBuffer texture = GetEngine()->TextureBufferManager()->GetTexture(shad_comp.shadow_texture_id);
glBindFramebuffer(GL_FRAMEBUFFER, m_frame_buffer_id);
glBindTexture(GL_TEXTURE_2D, texture.gl_tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture.gl_tex_id, 0);
GLenum draw_buffers[4] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindTexture(GL_TEXTURE_2D, 0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // we're not using the stencil buffer now
glEnable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void HydraShadowPipeline::_CreateFrameBuffer()
{
HydraEngine* engine = GetEngine();
HydraTextureBufferManager* tex_buffer_manager = engine->TextureBufferManager();
HydraRenderSettings render_settings = engine->RenderSettings();
glGenFramebuffers(1, &m_frame_buffer_id);
glBindFramebuffer(GL_FRAMEBUFFER, m_frame_buffer_id);
}
void HydraShadowPipeline::_CreateUBOs()
{
HydraBufferManager* buffer_manager = GetEngine()->BufferManager();
m_per_frame_ubo = buffer_manager->CreateGPUBuffer("ShadowPerFrameUBO",
sizeof(float)*4, 0, HYDRA_BUFFER_TYPE::HYDRA_UBO_BUFFER);
}
@@ -17,6 +17,13 @@ class HydraShadowPipeline : public HydraPipeline
void Shutdown() override;
void Render() override;
private:
void _CreateUBOs();
void _CreateFrameBuffer();
void _CreateRenderStage();
void _UpdateUBO(uint32_t shadow_idx);
void _BindFrameBufferAttachments(HydraID entity_id);
HydraID m_per_frame_ubo = INVALID_HYDRA_ID;
uint32_t m_frame_buffer_id;
};
@@ -17,6 +17,7 @@ private:
uint32_t m_mip_levels;
uint32_t m_min_filter;
uint32_t m_mag_filter;
uint32_t m_levels;
void *m_data;
HydraID *m_texture_id;
@@ -29,6 +30,7 @@ public:
m_internal_format,
m_min_filter,
m_mag_filter,
m_levels,
m_format,
m_data_type,
m_mip_levels,
@@ -43,6 +45,7 @@ public:
uint32_t format,
uint32_t min_filter,
uint32_t mag_filter,
uint32_t levels,
uint32_t data_type,
uint32_t mip_levels,
void *data,
@@ -59,6 +62,7 @@ public:
m_texture_id = texture_id;
m_min_filter = min_filter;
m_mag_filter = mag_filter;
m_levels = levels;
}
};
@@ -0,0 +1,69 @@
#ifndef HYDRACREATEUNBOUNDTEXTURETASK
#define HYDRACREATEUNBOUNDTEXTURETASK
#include "../HydraTask.h"
#include "../../engine/HydraEngine.h"
#include "../../buffer/HydraTextureBufferManager.h"
class HydraCreateUnBoundTextureTask : public HydraTask
{
private:
std::string m_texture_name;
uint32_t m_width;
uint32_t m_height;
uint32_t m_internal_format;
uint32_t m_format;
uint32_t m_data_type;
uint32_t m_mip_levels;
uint32_t m_min_filter;
uint32_t m_mag_filter;
uint32_t m_levels;
void *m_data;
HydraID *m_texture_id;
protected:
public:
virtual void Process() override
{
*m_texture_id = GetEngine()->TextureBufferManager()->CreateTexture(m_texture_name,
m_width, m_height,
m_internal_format,
m_min_filter,
m_mag_filter,
m_levels,
m_format,
m_data_type,
m_mip_levels,
m_data);
}
void Initialise(std::string texture_name,
uint32_t width,
uint32_t height,
uint32_t internal_format,
uint32_t format,
uint32_t min_filter,
uint32_t mag_filter,
uint32_t levels,
uint32_t data_type,
uint32_t mip_levels,
void *data,
HydraID *texture_id)
{
m_texture_name = texture_name;
m_width = width;
m_height = height;
m_internal_format = internal_format;
m_format = format;
m_data_type = data_type;
m_mip_levels = mip_levels;
m_data = data;
m_texture_id = texture_id;
m_min_filter = min_filter;
m_mag_filter = mag_filter;
m_levels = levels;
}
};
#endif /* HYDRACREATEUNBOUNDTEXTURETASK */
@@ -15,8 +15,8 @@ class HydraUpdatePartialGPUBufferTask : public HydraTask
protected:
public:
virtual void Process() override
{
GetEngine()->BufferManager()->UpdateWholeBuffer(m_buffer_id, m_data);
{
GetEngine()->BufferManager()->UpdatePartialBuffer(m_buffer_id, m_start, m_size, m_data);
}
void Intialise(HydraID buffer_id, uint32_t start, uint32_t size, void* data)
{
@@ -25,7 +25,6 @@ class HydraUpdatePartialGPUBufferTask : public HydraTask
m_start = start;
m_size = size;
}
};
#endif /* HYDRAUPDATEPARTIALGPUBUFFERTASK */
@@ -0,0 +1,19 @@
#ifndef HYDRABEGINRENDERTASK
#define HYDRABEGINRENDERTASK
#include "../HydraTask.h"
#include "../../engine/HydraEngine.h"
#include "../../renderer/HydraRenderer.h"
class HydraBeginRenderTask : public HydraTask
{
private:
protected:
public:
virtual void Process() override
{
GetEngine()->Renderer()->BeginFrame();
}
};
#endif /* HYDRABEGINRENDERTASK */
@@ -0,0 +1,18 @@
#ifndef HYDRAENDRENDERTASK
#define HYDRAENDRENDERTASK
#include "../HydraTask.h"
#include "../../engine/HydraEngine.h"
#include "../../renderer/HydraRenderer.h"
class HydraEndRenderTask : public HydraTask
{
private:
protected:
public:
virtual void Process() override
{
GetEngine()->Renderer()->EndFrame();
}
};
#endif /* HYDRAENDRENDERTASK */