diff --git a/include/Core/Renderer.h b/include/Core/Renderer.h index bb47561..844f42f 100755 --- a/include/Core/Renderer.h +++ b/include/Core/Renderer.h @@ -73,6 +73,7 @@ private: ShaderProgram* m_spForward; ShaderProgram* m_spScreen; ShaderProgram* t_m_spWater; + ShaderProgram* t_m_spWater2; GLuint m_ScreenQuad = 0; Model* m_UnitSphere = nullptr; @@ -94,9 +95,13 @@ private: //Water GTexture GLuint t_m_Gwater = 0; //Water blur texture - GLuint t_m_tWater; + GLuint t_m_BWater; + GLuint t_m_BWater2; //WAterpass Framebuffer GLuint t_m_fbWater; + //Waterpass Framebuffer + GLuint t_m_fbWaterBlur; + GLuint t_m_fbWaterBlur2; GLuint m_CurrentScreenBuffer = 0; diff --git a/src/game/Core/Renderer.cpp b/src/game/Core/Renderer.cpp index a80106c..b02684c 100755 --- a/src/game/Core/Renderer.cpp +++ b/src/game/Core/Renderer.cpp @@ -94,6 +94,8 @@ void dd::Renderer::LoadShaders() //Water Pass t_m_spWater = ResourceManager::Load("Shaders/Deferred/water/"); t_m_spWater->Link(); + t_m_spWater2 = ResourceManager::Load("Shaders/Deferred/water2/"); + t_m_spWater2->Link(); // Pass #3: Combining into final image m_spDeferred3 = ResourceManager::Load("Shaders/Deferred/3/"); @@ -114,6 +116,7 @@ void dd::Renderer::LoadShaders() void dd::Renderer::CreateBuffers() { + //TODO: Make the most common cases of texture create and FBO create into a function so it's not so cluttered in here. m_ScreenQuad = CreateQuad(); m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); m_UnitSphere = ResourceManager::Load("Models/Core/UnitSphere.obj"); @@ -211,7 +214,47 @@ void dd::Renderer::CreateBuffers() glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWater); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t_m_Gwater, 0); GLenum waterPassDrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; - glDrawBuffers(1, secondPassDrawBuffers); + glDrawBuffers(1, waterPassDrawBuffers); + if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LOG_ERROR("m_fbDeferred2 incomplete: 0x%x\n", fbStatus); + exit(EXIT_FAILURE); + } + + //water Blur texture + glGenTextures(1, &t_m_BWater); + glBindTexture(GL_TEXTURE_2D, t_m_BWater); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + //Fill waterBlur pass + glGenFramebuffers(1, &t_m_fbWaterBlur); + glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWaterBlur); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t_m_BWater, 0); + GLenum waterBlurDrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, waterBlurDrawBuffers); + if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LOG_ERROR("m_fbDeferred2 incomplete: 0x%x\n", fbStatus); + exit(EXIT_FAILURE); + } + + //water Blur texture2 + glGenTextures(1, &t_m_BWater2); + glBindTexture(GL_TEXTURE_2D, t_m_BWater2); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + //Fill waterBlur pass2 + glGenFramebuffers(1, &t_m_fbWaterBlur2); + glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWaterBlur2); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t_m_BWater2, 0); + GLenum waterBlur2DrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, waterBlur2DrawBuffers); if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { LOG_ERROR("m_fbDeferred2 incomplete: 0x%x\n", fbStatus); exit(EXIT_FAILURE); @@ -318,6 +361,8 @@ void dd::Renderer::DrawDeferred(RenderQueue &objects, RenderQueue &lights, Rende glBindTexture(GL_TEXTURE_2D, m_GDiffuse); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_tLighting); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, t_m_BWater2); glBindVertexArray(m_ScreenQuad); glDrawArrays(GL_TRIANGLES, 0, 6); } @@ -460,10 +505,8 @@ void dd::Renderer::DrawWater(RenderQueue &waterParticles) glm::mat4 PV = projectionMatrix * viewMatrix; glm::mat4 MVP; for ( auto &job : waterParticles ) { - LOG_INFO("1"); auto waterJob = std::dynamic_pointer_cast(job); if (waterJob) { - LOG_INFO("2"); glm::mat4 modelMatrix = waterJob->ModelMatrix; MVP = PV * modelMatrix; glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); @@ -480,8 +523,47 @@ void dd::Renderer::DrawWater(RenderQueue &waterParticles) glDrawElementsBaseVertex(GL_TRIANGLES, m_UnitQuad->m_Indices.size(), GL_UNSIGNED_INT, 0, 0); } } + + //blur1 + shaderProgramHandle = *t_m_spWater2; + glCullFace(GL_BACK); + glDisable(GL_BLEND); + glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWaterBlur); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + t_m_spWater2->Bind(); + + glUniform2fv(glGetUniformLocation(shaderProgramHandle, "dir"), 1, glm::value_ptr(glm::vec2(1.0f, 0.0f))); + glUniform1f(glGetUniformLocation(shaderProgramHandle, "res"), m_Resolution.Height); + glUniform1f(glGetUniformLocation(shaderProgramHandle, "radius"), 2.0f); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, t_m_Gwater); + glBindVertexArray(m_ScreenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + + + //blur2 + shaderProgramHandle = *t_m_spWater2; + glCullFace(GL_BACK); + glDisable(GL_BLEND); + glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWaterBlur2); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + t_m_spWater2->Bind(); + + glUniform2fv(glGetUniformLocation(shaderProgramHandle, "dir"), 1, glm::value_ptr(glm::vec2(0.0f, 1.0f))); + glUniform1f(glGetUniformLocation(shaderProgramHandle, "res"), m_Resolution.Height); + glUniform1f(glGetUniformLocation(shaderProgramHandle, "radius"), 2.0f); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, t_m_BWater); + glBindVertexArray(m_ScreenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); } + + GLuint dd::Renderer::CreateWaterParticleVAO(RenderQueue &particles) { float waterVerts[particles.Size()]; @@ -577,6 +659,6 @@ void dd::Renderer::DebugKeys() m_CurrentScreenBuffer = m_tLighting; } if (glfwGetKey(m_Window, GLFW_KEY_F7)) { - m_CurrentScreenBuffer = t_m_Gwater; + m_CurrentScreenBuffer = t_m_BWater2; } } diff --git a/src/game/Core/Shaders/Deferred/3/Fragment.glsl b/src/game/Core/Shaders/Deferred/3/Fragment.glsl index 61f54ac..3f5f28c 100755 --- a/src/game/Core/Shaders/Deferred/3/Fragment.glsl +++ b/src/game/Core/Shaders/Deferred/3/Fragment.glsl @@ -22,6 +22,7 @@ uniform vec3 La; layout (binding=0) uniform sampler2D DiffuseTexture; layout (binding=1) uniform sampler2D LightingTexture; +layout (binding=2) uniform sampler2D WaterTexture; in VertexData { @@ -35,11 +36,12 @@ void main() { vec4 DiffuseTexel = texture(DiffuseTexture, Input.TextureCoord); vec4 LightingTexel = texture(LightingTexture, Input.TextureCoord); + vec4 WaterTexel = texture(WaterTexture, Input.TextureCoord); //frag_Diffuse = DiffuseTexel * (vec4(La, 0.0) * (vec4(LightingTexel.rgb, 0.0) + vec4(LightingTexel.a, LightingTexel.a, LightingTexel.a, 0.0))); //frag_Diffuse = DiffuseTexel * (vec4(La, 0.0) + LightingTexel); //frag_Diffuse = DiffuseTexel * (vec4(1.f, 1.f, 1.f, 0.0) + LightingTexel); - frag_Diffuse = DiffuseTexel + LightingTexel; + frag_Diffuse = DiffuseTexel + LightingTexel + WaterTexel; //frag_Diffuse = DiffuseTexel; //frag_Diffuse = vec4(LightingTexel.r, LightingTexel.g, LightingTexel.b, 1.0); } \ No newline at end of file diff --git a/src/game/Core/Shaders/Deferred/water2/Fragment.glsl b/src/game/Core/Shaders/Deferred/water2/Fragment.glsl new file mode 100755 index 0000000..a8c72f3 --- /dev/null +++ b/src/game/Core/Shaders/Deferred/water2/Fragment.glsl @@ -0,0 +1,63 @@ +/* + This file is part of Daydream Engine. + Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung + + Daydream Engine is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Daydream Engine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with Daydream Engine. If not, see . +*/ + +#version 440 + +uniform vec2 dir; +uniform float res; +uniform float radius; + +layout (binding=0) uniform sampler2D WaterTexture; + +in VertexData +{ + vec3 Position; + vec2 TextureCoord; +} Input; + +out vec4 frag_Diffuse; + +void main() +{ + vec4 WaterTexel = texture(WaterTexture, Input.TextureCoord); + + vec4 sum = vec4(0.0); + vec2 tc = Input.TextureCoord; + + //How much blur, 1 = blur by one pixel. + float blur = radius/res; + + float hstep = dir.x; + float vstep = dir.y; + + //apply filter using a 9 tap filter with predefined gaussian weights + + sum += texture(WaterTexture, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162; + sum += texture(WaterTexture, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541; + sum += texture(WaterTexture, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216; + sum += texture(WaterTexture, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946; + + sum += texture(WaterTexture, vec2(tc.x, tc.y)) * 0.2270270270; + + sum += texture(WaterTexture, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946; + sum += texture(WaterTexture, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216; + sum += texture(WaterTexture, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541; + sum += texture(WaterTexture, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162; + + frag_Diffuse = vec4(sum.rgb, 1.0) * vec4(0.0, 0.3, 1.0, 1.0); +} \ No newline at end of file diff --git a/src/game/Core/Shaders/Deferred/water2/Vertex.glsl b/src/game/Core/Shaders/Deferred/water2/Vertex.glsl new file mode 100755 index 0000000..08bb198 --- /dev/null +++ b/src/game/Core/Shaders/Deferred/water2/Vertex.glsl @@ -0,0 +1,34 @@ +/* + This file is part of Daydream Engine. + Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung + + Daydream Engine is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Daydream Engine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with Daydream Engine. If not, see . +*/ + +#version 440 + +layout (location = 0) in vec3 Position; + +out VertexData +{ + vec3 Position; + vec2 TextureCoord; +} Output; + +void main() +{ + gl_Position = vec4(Position, 1.0); + Output.Position = Position; + Output.TextureCoord = (vec2(Position) + 1) / 2; +} \ No newline at end of file