#include "posteffectmodule.h" #include "framebuffer.h" #include "texture.h" #include "shader.h" #include "textureblur.h" #include "textureredux.h" #include "shadersource.h" #include const GLfloat PostEffectModule::vertices[] = { -1.0f, -1.0f, 3.0f, -1.0f, -1.0f, 3.0f }; PostEffectModule::PostEffectModule(int width, int height) : frameBuffers(NULL), outputFBO(FrameBuffer::screen), blur(NULL), blurSource(NULL), redux(NULL), bloom_threshold(0.7f) { for(int i=0; isetSource(blurSource); if(redux != NULL) delete(redux); redux = new TextureRedux(frameBuffers + BLOOM_FBO); if(shaders[REDUX_SHADER] != NULL) redux->setShader(shaders[REDUX_SHADER]); } void PostEffectModule::renderGL(Camera* myCamera, Scene* scene) { if(shaders[0] != NULL) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glBindVertexArray(vao); // thresholding the luminance to isolate high luminance pixels for bloom luminanceStep(); // blur the high luminance pixels bloomStep(); // compute average luminance and apply tonemapping hdrStep(); glEnable(GL_DEPTH_TEST); } frameBuffers[INPUT_FBO].bindFBO(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void PostEffectModule::luminanceStep() { glViewport(0, 0, width, height); frameBuffers[LUMINANCE_FBO].bindFBO(); glClear(GL_COLOR_BUFFER_BIT); shaders[LUMINANCE_SHADER]->bind(); shaders[LUMINANCE_SHADER]->bindInteger(shaders[LUMINANCE_SHADER]->getLocation("colorSampler"), 0); frameBuffers[INPUT_FBO].getTexture(0)->bind(0); shaders[LUMINANCE_SHADER]->bindFloat(shaders[LUMINANCE_SHADER]->getLocation("threshold"), bloom_threshold); glDrawArrays(GL_TRIANGLES, 0, 3); } void PostEffectModule::bloomStep() { blur->blur(); glViewport(0, 0, width, height); frameBuffers[BLOOM_FBO].bindFBO(); glClear(GL_COLOR_BUFFER_BIT); shaders[BLOOM_SHADER]->bind(); shaders[BLOOM_SHADER]->bindInteger(shaders[BLOOM_SHADER]->getLocation("colorSampler"), 0); frameBuffers[INPUT_FBO].getTexture(0)->bind(0); shaders[BLOOM_SHADER]->bindInteger(shaders[BLOOM_SHADER]->getLocation("blurSampler0"), 1); blur->getTexture(0)->bind(1); shaders[BLOOM_SHADER]->bindInteger(shaders[BLOOM_SHADER]->getLocation("blurSampler1"), 2); blur->getTexture(1)->bind(2); shaders[BLOOM_SHADER]->bindInteger(shaders[BLOOM_SHADER]->getLocation("blurSampler2"), 3); blur->getTexture(2)->bind(3); shaders[BLOOM_SHADER]->bindInteger(shaders[BLOOM_SHADER]->getLocation("blurSampler3"), 4); blur->getTexture(3)->bind(4); shaders[BLOOM_SHADER]->bindInteger(shaders[BLOOM_SHADER]->getLocation("width"), width); shaders[BLOOM_SHADER]->bindInteger(shaders[BLOOM_SHADER]->getLocation("height"), height); glDrawArrays(GL_TRIANGLES, 0, 3); } void PostEffectModule::hdrStep() { glm::vec3 minMaxMean = redux->redux(); float gamma = 2.2f; glViewport(0, 0, width, height); outputFBO->bindFBO(); glClear(GL_COLOR_BUFFER_BIT); shaders[HDR_SHADER]->bind(); shaders[HDR_SHADER]->bindInteger(shaders[HDR_SHADER]->getLocation("colorSampler"), 0); frameBuffers[BLOOM_FBO].getTexture(1)->bind(0); shaders[HDR_SHADER]->bindVec3(shaders[HDR_SHADER]->getLocation("minMaxMean"), minMaxMean); shaders[HDR_SHADER]->bindFloat(shaders[HDR_SHADER]->getLocation("gamma"), gamma); glDrawArrays(GL_TRIANGLES, 0, 3); } void PostEffectModule::setShaders(const std::string &luminanceFragSource, const std::string &bloomFragSource, const std::string &hdrFragSource, const std::string &blurFragSource, const std::string &reduxFragSource) { const std::string version_string = "#version 330 core\n"; shaders[LUMINANCE_SHADER] = new Shader(version_string+vertSource, version_string+luminanceFragSource); shaders[BLOOM_SHADER] = new Shader(version_string+vertSource, version_string+bloomFragSource); shaders[HDR_SHADER] = new Shader(version_string+vertSource, version_string+hdrFragSource); shaders[REDUX_SHADER] = new Shader(version_string+vertSource, version_string+reduxFragSource); redux->setShader(shaders[REDUX_SHADER]); if(blurSource != NULL) delete(blurSource); blurSource = new ShaderSource(); blurSource->setSource(vertSource.c_str(), ShaderSource::VERTEX); blurSource->setSource(blurFragSource.c_str(), ShaderSource::FRAGMENT); blur->setSource(blurSource); } glm::vec3 PostEffectModule::getObjectInfo(int x, int y) { frameBuffers[INPUT_FBO].getTexture(1)->bind(0); glm::vec3 *val = new glm::vec3[width*height]; glGetTexImage(GL_TEXTURE_RECTANGLE, 0, GL_RGB, GL_FLOAT, val); glm::vec3 ret = val[x + (height-y)*width]; ret.z -= 1; // clearColor compensation delete[] val; return ret; } const std::string PostEffectModule::vertSource = "layout(location = 0)in vec2 inPosition;\n\ void main(void) {\n\ gl_Position = vec4(inPosition, 0.0, 1.0);\n\ }\n";