Files
axyz/src/Engine/Rendering/LightCullingPass.cpp
T
2016-02-19 11:42:52 +01:00

187 lines
7.3 KiB
C++

#include "Rendering/LightCullingPass.h"
LightCullingPass::LightCullingPass(IRenderer* renderer)
{
m_Renderer = renderer;
SetSSBOSizes();
InitializeSSBOs();
InitializeShaderPrograms();
//GenerateNewFrustum(TODO);
}
LightCullingPass::~LightCullingPass()
{
}
void LightCullingPass::GenerateNewFrustum(RenderScene& scene)
{
if (scene.Jobs.PointLight.size() == 0)
return;
GLERROR("CalculateFrustum Error: Pre");
m_CalculateFrustumProgram->Bind();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
glDispatchCompute((int)(m_Renderer->GetViewportSize().Width/(TILE_SIZE*TILE_SIZE) + 1), (int)(m_Renderer->GetViewportSize().Height/(TILE_SIZE*TILE_SIZE) + 1), 1);
GLERROR("CalculateFrustum Error: End");
}
void LightCullingPass::OnResolutionChange()
{
SetSSBOSizes();
}
void LightCullingPass::SetSSBOSizes()
{
m_NumberOfTiles = (int)(m_Renderer->GetViewportSize().Width/TILE_SIZE) * (int)(m_Renderer->GetViewportSize().Height/TILE_SIZE);
m_Frustums = new Frustum[m_NumberOfTiles];
m_LightGrid = new LightGrid[m_NumberOfTiles];
m_LightIndex = new float[m_NumberOfTiles*MAX_LIGHTS_PER_TILE];
for (int i = 0; i < m_NumberOfTiles*MAX_LIGHTS_PER_TILE; i++) {
m_LightIndex[i] = -1;
}
}
void LightCullingPass::CullLights(RenderScene& scene)
{
GLERROR("CullLights Error: Pre");
m_LightOffset = 0;
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
if (m_LightSources.size() > 0) {
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightSource) * m_LightSources.size(), &(m_LightSources[0]), GL_DYNAMIC_COPY);
} else {
GLfloat zero = 0.f;
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat), &zero , GL_DYNAMIC_COPY);
}
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
m_LightCullProgram->Bind();
glUniform2f(glGetUniformLocation(m_LightCullProgram->GetHandle(), "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);
glUniformMatrix4fv(glGetUniformLocation(m_LightCullProgram->GetHandle(), "V"), 1, false, glm::value_ptr(scene.Camera->ViewMatrix()));
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO);
glDispatchCompute(glm::ceil(m_Renderer->GetViewportSize().Width/ TILE_SIZE), glm::ceil(m_Renderer->GetViewportSize().Height / TILE_SIZE), 1);
GLERROR("CullLights Error: End");
}
void LightCullingPass::FillLightList(RenderScene& scene)
{
m_LightSources.clear();
for(auto &job : scene.Jobs.PointLight) {
auto pointLightjob = std::dynamic_pointer_cast<PointLightJob>(job);
if (pointLightjob) {
LightSource p;
p.Color = pointLightjob->Color;
p.Falloff = pointLightjob->Falloff;
p.Intensity = pointLightjob->Intensity;
p.Position = glm::vec4(glm::vec3(pointLightjob->Position), 1.f);
p.Radius = pointLightjob->Radius;
//p.Padding = 123.f;
p.Type = LightSource::Point;
m_LightSources.push_back(p);
}
}
for(auto &job : scene.Jobs.DirectionalLight) {
auto directionalLightJob = std::dynamic_pointer_cast<DirectionalLightJob>(job);
if(directionalLightJob) {
LightSource p;
p.Direction = directionalLightJob->Direction;
p.Color = directionalLightJob->Color;
p.Intensity = directionalLightJob->Intensity;
p.Type = LightSource::Directional;
m_LightSources.push_back(p);
}
}
}
void LightCullingPass::OnWindowResize()
{
SetSSBOSizes();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Frustum)*m_NumberOfTiles, nullptr, GL_DYNAMIC_COPY);
GLERROR("m_FrustumSSBO");
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightSource) * 200, nullptr, GL_DYNAMIC_COPY);
GLERROR("m_LightSSBO");
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightGrid)*m_NumberOfTiles, nullptr, GL_DYNAMIC_COPY);
GLERROR("m_LightGridSSBO");
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);
GLERROR("m_LightOffsetSSBO");
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightIndexSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float)*m_NumberOfTiles*MAX_LIGHTS_PER_TILE, m_LightIndex, GL_DYNAMIC_COPY);
GLERROR("m_LightIndexSSBO");
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
}
void LightCullingPass::InitializeSSBOs()
{
glGenBuffers(1, &m_FrustumSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Frustum)*m_NumberOfTiles, nullptr, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_FrustumSSBO");
glGenBuffers(1, &m_LightSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightSource) * 200, nullptr, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightSSBO");
glGenBuffers(1, &m_LightGridSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightGrid)*m_NumberOfTiles, nullptr, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightGridSSBO");
glGenBuffers(1, &m_LightOffsetSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightOffsetSSBO");
glGenBuffers(1, &m_LightIndexSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightIndexSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float)*m_NumberOfTiles*MAX_LIGHTS_PER_TILE, m_LightIndex, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightIndexSSBO");
}
void LightCullingPass::InitializeShaderPrograms()
{
m_CalculateFrustumProgram = ResourceManager::Load<ShaderProgram>("#CalculateFrustumProgram");
m_CalculateFrustumProgram->AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/GridFrustum.comp.glsl")));
m_CalculateFrustumProgram->Compile();
m_CalculateFrustumProgram->Link();
m_LightCullProgram = ResourceManager::Load<ShaderProgram>("#LightCullProgram");
m_LightCullProgram->AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/CullLights.comp.glsl")));
m_LightCullProgram->Compile();
m_LightCullProgram->Link();
}