diff --git a/include/Engine/Rendering/DrawBloomPass.h b/include/Engine/Rendering/DrawBloomPass.h index 204f97d1..a76eb053 100644 --- a/include/Engine/Rendering/DrawBloomPass.h +++ b/include/Engine/Rendering/DrawBloomPass.h @@ -33,13 +33,14 @@ public: if (m_Quality == 0) { return m_BlackTexture->m_Texture; } else { - return m_GaussianTexture_vert; + return m_FinalGaussianTexture; } } private: void GaussianLodPass(GLuint mipMap, GLuint texture); + void CombineGaussianBlur(); Texture* m_BlackTexture; Model* m_ScreenQuad; @@ -52,12 +53,15 @@ private: GLuint m_GaussianTexture_horiz = 0; GLuint m_GaussianTexture_vert = 0; + GLuint m_FinalGaussianTexture = 0; FrameBuffer* m_GaussianFrameBuffer_horiz = nullptr; FrameBuffer* m_GaussianFrameBuffer_vert = nullptr; + FrameBuffer m_GaussianCombineBuffer; ShaderProgram* m_GaussianProgram_horiz; ShaderProgram* m_GaussianProgram_vert; + ShaderProgram* m_GaussianCombineProgram; }; diff --git a/resources/Shaders/CombineGaussianTexture.frag.glsl b/resources/Shaders/CombineGaussianTexture.frag.glsl new file mode 100644 index 00000000..66892a6a --- /dev/null +++ b/resources/Shaders/CombineGaussianTexture.frag.glsl @@ -0,0 +1,22 @@ +#version 430 + +layout (binding = 0) uniform sampler2D Texture; + + +in VertexData{ + vec2 TextureCoordinate; +}Input; + +out vec4 fragmentColor; + +void main() +{ + vec4 texel0 = textureLod(Texture, Input.TextureCoordinate, 0); + vec4 texel1 = textureLod(Texture, Input.TextureCoordinate, 1); + vec4 texel2 = textureLod(Texture, Input.TextureCoordinate, 2); + vec4 texel3 = textureLod(Texture, Input.TextureCoordinate, 3); + + fragmentColor = texel0 + texel1 + texel2 + texel3; +} + + diff --git a/resources/Shaders/CombineGaussianTexture.vert.glsl b/resources/Shaders/CombineGaussianTexture.vert.glsl new file mode 100644 index 00000000..346bc141 --- /dev/null +++ b/resources/Shaders/CombineGaussianTexture.vert.glsl @@ -0,0 +1,13 @@ +#version 430 + +layout (location = 0) in vec3 Position; + +out VertexData{ + vec2 TextureCoordinate; +}Output; + +void main() +{ + gl_Position = vec4(Position, 1.0); + Output.TextureCoordinate = (vec2(Position) + 1) / 2; +} \ No newline at end of file diff --git a/src/Engine/Rendering/DrawBloomPass.cpp b/src/Engine/Rendering/DrawBloomPass.cpp index f30734db..f73611a2 100644 --- a/src/Engine/Rendering/DrawBloomPass.cpp +++ b/src/Engine/Rendering/DrawBloomPass.cpp @@ -12,6 +12,7 @@ DrawBloomPass::DrawBloomPass(IRenderer* renderer, ConfigFile* config) DrawBloomPass::~DrawBloomPass() { CommonFunctions::DeleteTexture(&m_GaussianTexture_horiz); CommonFunctions::DeleteTexture(&m_GaussianTexture_vert); + CommonFunctions::DeleteTexture(&m_FinalGaussianTexture); } void DrawBloomPass::InitializeTextures() @@ -30,9 +31,8 @@ void DrawBloomPass::ChangeQuality(int quality) if (m_Quality == 0) { CommonFunctions::DeleteTexture(&m_GaussianTexture_horiz); - CommonFunctions::DeleteTexture(&m_GaussianTexture_vert); - m_GaussianTexture_horiz = 0; - m_GaussianTexture_vert = 0; + CommonFunctions::DeleteTexture(&m_GaussianTexture_vert); + CommonFunctions::DeleteTexture(&m_FinalGaussianTexture); return; } InitializeTextures(); @@ -62,6 +62,15 @@ void DrawBloomPass::InitializeShaderPrograms() m_GaussianProgram_vert->BindFragDataLocation(0, "fragmentColor"); m_GaussianProgram_vert->Link(); } + + m_GaussianCombineProgram = ResourceManager::Load("#GaussianCombineProgram"); + if (m_GaussianCombineProgram->GetHandle() == 0) { + m_GaussianCombineProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/CombineGaussianTexture.vert.glsl"))); + m_GaussianCombineProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/CombineGaussianTexture.frag.glsl"))); + m_GaussianCombineProgram->Compile(); + m_GaussianCombineProgram->BindFragDataLocation(0, "fragmentColor"); + m_GaussianCombineProgram->Link(); + } } void DrawBloomPass::InitializeBuffers() @@ -72,6 +81,12 @@ void DrawBloomPass::InitializeBuffers() CommonFunctions::GenerateMipMapTexture( &m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height) , GL_RGB, GL_FLOAT, m_BloomLod); + CommonFunctions::GenerateTexture(&m_FinalGaussianTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); + + if (m_GaussianCombineBuffer.GetHandle() == 0) { + m_GaussianCombineBuffer.AddResource(std::shared_ptr(new Texture2D(&m_FinalGaussianTexture, GL_COLOR_ATTACHMENT0))); + } + m_GaussianCombineBuffer.Generate(); if(m_GaussianFrameBuffer_horiz == nullptr) { m_GaussianFrameBuffer_horiz = new FrameBuffer[m_BloomLod]; @@ -109,8 +124,12 @@ void DrawBloomPass::ClearBuffer() glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT); m_GaussianFrameBuffer_vert[i].Unbind(); - } + } + m_GaussianCombineBuffer.Bind(); + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + m_GaussianCombineBuffer.Unbind(); GLERROR("END"); } @@ -123,6 +142,7 @@ void DrawBloomPass::Draw(GLuint texture) for (int i = 0; i < m_BloomLod; i++) { GaussianLodPass(i, texture); } + CombineGaussianBlur(); } @@ -148,7 +168,7 @@ void DrawBloomPass::OnWindowResize() void DrawBloomPass::GaussianLodPass(GLuint mipMap, GLuint texture) { GLERROR("DrawBloomPass::Draw: Pre"); - + glViewport(0, 0, m_Renderer->GetViewportSize().Width/(glm::pow(2, mipMap)), m_Renderer->GetViewportSize().Height/(glm::pow(2, mipMap))); DrawBloomPassState state; GLuint shaderHandle_horiz = m_GaussianProgram_horiz->GetHandle(); @@ -156,8 +176,6 @@ void DrawBloomPass::GaussianLodPass(GLuint mipMap, GLuint texture) //Horizontal pass, first use the given texture then save it to the horizontal framebuffer. m_GaussianFrameBuffer_horiz[mipMap].Bind(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, mipMap); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipMap); m_GaussianProgram_horiz->Bind(); glUniform1i(glGetUniformLocation(shaderHandle_horiz, "Lod"), mipMap); @@ -214,6 +232,20 @@ void DrawBloomPass::GaussianLodPass(GLuint mipMap, GLuint texture) , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); GLERROR("DrawBloomPass::Draw: END"); + glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); m_GaussianFrameBuffer_vert[mipMap].Unbind(); } + +void DrawBloomPass::CombineGaussianBlur() +{ + m_GaussianCombineBuffer.Bind(); + m_GaussianCombineProgram->Bind(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_vert); + glBindVertexArray(m_ScreenQuad->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); +} diff --git a/src/Engine/Rendering/Util/CommonFunctions.cpp b/src/Engine/Rendering/Util/CommonFunctions.cpp index dac9fca3..c185cd5c 100644 --- a/src/Engine/Rendering/Util/CommonFunctions.cpp +++ b/src/Engine/Rendering/Util/CommonFunctions.cpp @@ -25,6 +25,7 @@ void CommonFunctions::GenerateMultiSampleTexture(GLuint* texture, int numSamples void CommonFunctions::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) { + glDeleteTextures(1, texture); glGenTextures(1, texture); glBindTexture(GL_TEXTURE_2D, *texture); glTexStorage2D(GL_TEXTURE_2D, numMipMaps, GL_RGBA8, dimensions.x, dimensions.y);