diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 6d9fab60c..0ac4396eb 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -393,6 +393,39 @@ namespace PointLightShader } } +namespace LightBlendShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_diffuse, uniform_specular, uniform_ambient_occlusion, uniform_specular_map, uniform_ambient; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/lightblend.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_diffuse = glGetUniformLocation(Program, "diffuse"); + uniform_specular = glGetUniformLocation(Program, "specular"); + uniform_ambient_occlusion = glGetUniformLocation(Program, "ambient_occlusion"); + uniform_specular_map = glGetUniformLocation(Program, "specular_map"); + uniform_ambient = glGetUniformLocation(Program, "ambient"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + static void renderBloom(ITexture *in) @@ -533,6 +566,45 @@ void PostProcessing::renderPointlight(ITexture *in, const std::vector &po glDisable(GL_BLEND); } +void PostProcessing::renderLightbBlend(ITexture *diffuse, ITexture *specular, ITexture *ao, ITexture *specmap, bool debug) +{ + const SColorf s = irr_driver->getSceneManager()->getAmbientLight(); + if (!LightBlendShader::Program) + LightBlendShader::init(); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + if (debug) + glBlendFunc(GL_ONE, GL_ZERO); + else + glBlendFunc(GL_DST_COLOR, GL_ZERO); + glDisable(GL_DEPTH_TEST); + + glUseProgram(LightBlendShader::Program); + glBindVertexArray(LightBlendShader::vao); + + glUniform3f(LightBlendShader::uniform_ambient, s.r, s.g, s.b); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(diffuse)->getOpenGLTextureName()); + glUniform1i(LightBlendShader::uniform_diffuse, 0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, static_cast(specular)->getOpenGLTextureName()); + glUniform1i(LightBlendShader::uniform_specular, 1); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, static_cast(ao)->getOpenGLTextureName()); + glUniform1i(LightBlendShader::uniform_ambient_occlusion, 2); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, static_cast(specmap)->getOpenGLTextureName()); + glUniform1i(LightBlendShader::uniform_specular_map, 3); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); +} + // ---------------------------------------------------------------------------- /** Render the post-processed scene */ void PostProcessing::render() diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index b1ab9a410..97434d02e 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -78,6 +78,9 @@ public: /** Generate diffuse and specular map */ void renderPointlight(video::ITexture *in, const std::vector &positions, const std::vector &colors, const std::vector &energy); + /** Blend all light related map */ + void renderLightbBlend(video::ITexture *diffuse, video::ITexture *specular, video::ITexture *ao, video::ITexture *specmap, bool debug); + /** Render the post-processed scene */ void render(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 26dc99f97..fea8f7265 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -808,30 +808,9 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, m_post_processing->drawQuad(cam, m_material); } - // Blend lights to the image - video::SMaterial lightmat; - lightmat.Lighting = false; - lightmat.ZWriteEnable = false; - lightmat.ZBuffer = video::ECFN_ALWAYS; - lightmat.setFlag(video::EMF_BILINEAR_FILTER, false); - lightmat.setTexture(0, m_rtts->getRTT(RTT_TMP1)); - lightmat.setTexture(1, m_rtts->getRTT(RTT_TMP2)); - lightmat.setTexture(2, m_rtts->getRTT(RTT_SSAO)); - lightmat.setTexture(3, m_rtts->getRTT(RTT_SPECULARMAP)); - - lightmat.MaterialType = m_shaders->getShader(ES_LIGHTBLEND); - if (!m_lightviz) - lightmat.MaterialTypeParam = video::pack_textureBlendFunc(video::EBF_DST_COLOR, video::EBF_ZERO); - else - lightmat.MaterialTypeParam = video::pack_textureBlendFunc(video::EBF_ONE, video::EBF_ZERO); - lightmat.BlendOperation = video::EBO_ADD; - - lightmat.TextureLayer[0].TextureWrapU = - lightmat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); if (!m_mipviz) - m_post_processing->drawQuad(cam, lightmat); + m_post_processing->renderLightbBlend(m_rtts->getRTT(RTT_TMP1), m_rtts->getRTT(RTT_TMP2), m_rtts->getRTT(RTT_SSAO), m_rtts->getRTT(RTT_SPECULARMAP), m_lightviz); } // ----------------------------------------------------------------------------