#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 render_system = ecs->GetSystem(); std::shared_ptr shadow_system = ecs->GetSystem(); 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 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 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(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); }