#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(); _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; glViewport(0, 0, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE); glEnable(GL_DEPTH_TEST); // Depth testing must be active glDepthMask(GL_TRUE); // Depth buffer must be writable glDepthFunc(GL_LESS); //glEnable(GL_POLYGON_OFFSET_FILL); //glPolygonOffset(2.5f, 1.0f); for (HydraID entity_id : shadow_system->Entities) { _UpdateUBO(shadow_idx); // _BindFrameBufferAttachments(entity_id); HydraShadowSourceComponent shad_comp = GetEngine()->ECS()->GetComponent(entity_id); glBindFramebuffer(GL_FRAMEBUFFER, shad_comp.frame_buffer_id); // HydraTextureBuffer tex_buffer = GetEngine()->TextureBufferManager()->GetTexture(shad_comp.shadow_texture_id); // glBindTextureUnit(tex_buffer.gl_tex_id, 0); float depth_value = 1.0f; float clear_colour[] = {0,0,0}; glClearNamedFramebufferfv(shad_comp.frame_buffer_id, GL_DEPTH, 0, &depth_value); glClearNamedFramebufferfv(shad_comp.frame_buffer_id, GL_COLOR, 0, clear_colour); for (uint32_t rs_idx = 0; rs_idx < m_render_stages.size(); rs_idx++) { m_render_stages[rs_idx]->Render(render_system->Entities, INVALID_HYDRA_ID); } glBindFramebuffer(GL_FRAMEBUFFER, 0); shadow_idx++; } // glDisable(GL_POLYGON_OFFSET_FILL); } 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 mat_buffer_id = buffer_manager->FindBuffer("MaterialBuffer"); HydraID tex_buffer_id = buffer_manager->FindBuffer("TextureBuffer"); 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("positions_buffer"); 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("material_buffer"); shader_binding.binding_point.push_back(2); shader_binding.buffer_id.push_back(mat_buffer_id); shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER); shader_binding.block_name.push_back("texture_buffer"); shader_binding.binding_point.push_back(3); shader_binding.buffer_id.push_back(tex_buffer_id); shader_binding.buffer_type.push_back(HYDRA_BUFFER_TYPE::HYDRA_SSBO_BUFFER); shader_binding.block_name.push_back("shadow_map_sets"); shader_binding.binding_point.push_back(5); 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(1); 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, 0, textures, true, GL_FRONT, 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); glBindFramebuffer(GL_FRAMEBUFFER, shad_comp.frame_buffer_id); glBindTextureUnit(0, 0); } 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); }