Shadows - need to fix frame buffers
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
Reference in New Issue
Block a user