diff --git a/PluginCollection-PostProcessors/Plugin-FXAA/CMakeLists.txt b/PluginCollection-PostProcessors/Plugin-FXAA/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..faea732405e275a41bf14855ce3f8351fa20e108 --- /dev/null +++ b/PluginCollection-PostProcessors/Plugin-FXAA/CMakeLists.txt @@ -0,0 +1,2 @@ +include (plugin) +openflipper_plugin ( INSTALLDATA Shaders ) diff --git a/PluginCollection-PostProcessors/Plugin-FXAA/PostProcessorFXAAPlugin.cc b/PluginCollection-PostProcessors/Plugin-FXAA/PostProcessorFXAAPlugin.cc new file mode 100644 index 0000000000000000000000000000000000000000..1c4a666ad242a639e86dba12d099aba6b245a888 --- /dev/null +++ b/PluginCollection-PostProcessors/Plugin-FXAA/PostProcessorFXAAPlugin.cc @@ -0,0 +1,207 @@ +/*===========================================================================*\ +* * +* OpenFlipper * +* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen * +* www.openflipper.org * +* * +*--------------------------------------------------------------------------- * +* This file is part of OpenFlipper. * +* * +* OpenFlipper 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 with the * +* following exceptions: * +* * +* If other files instantiate templates or use macros * +* or inline functions from this file, or you compile this file and * +* link it with other files to produce an executable, this file does * +* not by itself cause the resulting executable to be covered by the * +* GNU Lesser General Public License. This exception does not however * +* invalidate any other reasons why the executable file might be * +* covered by the GNU Lesser General Public License. * +* * +* OpenFlipper 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 LesserGeneral Public * +* License along with OpenFlipper. If not, * +* see . * +* * +\*===========================================================================*/ + +/*===========================================================================*\ +* * +* $Revision: 17080 $ * +* $LastChangedBy: moeller $ * +* $Date: 2013-07-19 12:58:31 +0200 (Fri, 19 Jul 2013) $ * +* * +\*===========================================================================*/ + +#if QT_VERSION >= 0x050000 + #include +#else + #include +#endif + +#include "PostProcessorFXAAPlugin.hh" + +#include +#include +#include +#include + +#include +#include + + +PostProcessorFXAAPlugin::PostProcessorFXAAPlugin() : +sceneTexWidth_(0), +sceneTexHeight_(0), +fxaa_(0) +{ + +} + +PostProcessorFXAAPlugin::~PostProcessorFXAAPlugin() +{ + delete fxaa_; +} + + +QString PostProcessorFXAAPlugin::postProcessorName() { + return QString("FXAA"); +} + + + +void PostProcessorFXAAPlugin::updateDepthStencilTextureBuffer(ACG::GLState* _glstate) { + + if ( !ACG::checkExtensionSupported("GL_ARB_texture_rectangle") ) { + std::cerr << "GL_ARB_texture_rectangle not supported! " << std::endl; + return; + } + + int vp_l, vp_b, vp_w, vp_h; + _glstate->get_viewport (vp_l, vp_b, vp_w, vp_h); + + // Does color texture exist? + if (!pSceneTexture_.is_valid()) { + // ====================================================================================================== + // creating an 24-bit depth + 8-bit stencil texture + // ====================================================================================================== + + pSceneTexture_.enable(); + pSceneTexture_.bind(); + GLenum texTarget = GL_TEXTURE_2D; + GLenum texInternalFormat = GL_RGB; + GLenum texFormat = GL_RGB; + GLenum texType = GL_UNSIGNED_BYTE; + GLenum texFilterMode = GL_LINEAR; + glTexImage2D(texTarget, 0, texInternalFormat, vp_w, vp_h, 0, texFormat, texType, NULL); + + glTexParameterf(texTarget, GL_TEXTURE_MIN_FILTER, texFilterMode); + glTexParameterf(texTarget, GL_TEXTURE_MAG_FILTER, texFilterMode); + glTexParameterf(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + } + + // Resize target texture + if (_glstate->viewport_width() != sceneTexWidth_ || _glstate->viewport_height() != sceneTexHeight_) { + + pSceneTexture_.bind(); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _glstate->viewport_width(), _glstate->viewport_height(), 0, + GL_RGB, GL_UNSIGNED_BYTE, 0); + + ACG::GLState::bindTexture(GL_TEXTURE_2D, 0); + + sceneTexWidth_ = _glstate->viewport_width(); + sceneTexHeight_ = _glstate->viewport_height(); + } + + ACG::glCheckErrors(); + +} + + +void PostProcessorFXAAPlugin::postProcess(ACG::GLState* _glstate) { + + // ====================================================================================================== + // Load shader if needed + // ====================================================================================================== + if (!fxaa_) + fxaa_ = GLSL::loadProgram("FXAA/screenquad.glsl", "FXAA/fxaa.glsl"); + + // ====================================================================================================== + // Adjust buffer to correct size + // ====================================================================================================== + updateDepthStencilTextureBuffer(_glstate); + + // ====================================================================================================== + // Get current viewport size + // ====================================================================================================== + int vp_l, vp_b, vp_w, vp_h; + _glstate->get_viewport(vp_l, vp_b, vp_w, vp_h); + + // ====================================================================================================== + // Bind color texture + // ====================================================================================================== + + // ====================================================================================================== + // Copy color component of rendered image to texture + // ====================================================================================================== + +// if (!_input || !_input->colorTex_) + { + glActiveTexture(GL_TEXTURE0); + pSceneTexture_.enable(); + pSceneTexture_.bind(); + + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vp_l, vp_b, vp_w , vp_h, 0); + } +/* else + { + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, _input->colorTex_); + } +*/ + ACG::glCheckErrors(); + + // ====================================================================================================== + // Clear rendering buffer + // ====================================================================================================== + _glstate->clearBuffers(); + + // ====================================================================================================== + // Render a simple quad (rest is done by the texture) + // ====================================================================================================== + + glDepthMask(1); + glColorMask(1,1,1,1); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + + fxaa_->use(); + fxaa_->setUniform("textureSampler", 0); + + ACG::Vec2f texcoordOffset(1.0f / float(vp_w), 1.0f / float(vp_h)); + fxaa_->setUniform("texcoordOffset", texcoordOffset); + + ACG::ScreenQuad::draw(fxaa_); + + // Disable depth stencil buffer + pSceneTexture_.disable(); + +} + + +#if QT_VERSION < 0x050000 + Q_EXPORT_PLUGIN2( postprocessorfxaaplugin , PostProcessorFXAAPlugin ); +#endif + diff --git a/PluginCollection-PostProcessors/Plugin-FXAA/PostProcessorFXAAPlugin.hh b/PluginCollection-PostProcessors/Plugin-FXAA/PostProcessorFXAAPlugin.hh new file mode 100644 index 0000000000000000000000000000000000000000..3f0179935193fe82ccddf002e7582a95335c6a90 --- /dev/null +++ b/PluginCollection-PostProcessors/Plugin-FXAA/PostProcessorFXAAPlugin.hh @@ -0,0 +1,98 @@ +/*===========================================================================*\ +* * +* OpenFlipper * +* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen * +* www.openflipper.org * +* * +*--------------------------------------------------------------------------- * +* This file is part of OpenFlipper. * +* * +* OpenFlipper 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 with the * +* following exceptions: * +* * +* If other files instantiate templates or use macros * +* or inline functions from this file, or you compile this file and * +* link it with other files to produce an executable, this file does * +* not by itself cause the resulting executable to be covered by the * +* GNU Lesser General Public License. This exception does not however * +* invalidate any other reasons why the executable file might be * +* covered by the GNU Lesser General Public License. * +* * +* OpenFlipper 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 LesserGeneral Public * +* License along with OpenFlipper. If not, * +* see . * +* * +\*===========================================================================*/ + +/*===========================================================================*\ +* * +* $Revision: 17080 $ * +* $LastChangedBy: moeller $ * +* $Date: 2013-07-19 12:58:31 +0200 (Fri, 19 Jul 2013) $ * +* * +\*===========================================================================*/ + + +#include + +#include +#include + +#include +#include + +class PostProcessorFXAAPlugin : public QObject, BaseInterface, PostProcessorInterface +{ + Q_OBJECT + Q_INTERFACES(BaseInterface) + Q_INTERFACES(PostProcessorInterface) + +#if QT_VERSION >= 0x050000 + Q_PLUGIN_METADATA(IID "org.OpenFlipper.Plugins.Plugin-PostProcessorDepthImage") +#endif + + public: + PostProcessorFXAAPlugin(); + ~PostProcessorFXAAPlugin(); + + public : + QString name() { return (QString("FXAA Postprocessor Plugin")); }; + QString description( ) { return (QString(tr("Fast approximate anti aliasing"))); }; + + + public slots: + QString version() { return QString("1.0"); }; + + private slots: + + void updateDepthStencilTextureBuffer(ACG::GLState* _glstate); + + void postProcess(ACG::GLState* _glstate); + + QString postProcessorName(); + + private: + /// depthStencil texture buffer + ACG::Texture2D pSceneTexture_; + + /// Current width of the depthStencil texture buffer + int sceneTexWidth_; + + /// Current height of the depthStencil texture buffer + int sceneTexHeight_; + + + /// fxaa shader + GLSL::Program* fxaa_; + + private: +}; + diff --git a/PluginCollection-PostProcessors/Plugin-FXAA/Shaders/FXAA/fxaa.glsl b/PluginCollection-PostProcessors/Plugin-FXAA/Shaders/FXAA/fxaa.glsl new file mode 100644 index 0000000000000000000000000000000000000000..bd2ca2ea6d9eb7a055a01e3ebe8f2731b591bce0 --- /dev/null +++ b/PluginCollection-PostProcessors/Plugin-FXAA/Shaders/FXAA/fxaa.glsl @@ -0,0 +1,66 @@ +// FXAA shader, GLSL code adapted from: +// http://horde3d.org/wiki/index.php5?title=Shading_Technique_-_FXAA +// Whitepaper describing the technique: +// http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf + +#version 150 + +uniform sampler2D textureSampler; + +// The inverse of the texture dimensions along X and Y +uniform vec2 texcoordOffset; + +in vec2 vTexCoord; +out vec4 oColor; + +void main() { + // The parameters are hardcoded for now, but could be + // made into uniforms to control fromt he program. + float FXAA_SPAN_MAX = 8.0; + float FXAA_REDUCE_MUL = 1.0/8.0; + float FXAA_REDUCE_MIN = (1.0/128.0); + + vec3 rgbNW = texture2D(textureSampler, vTexCoord.xy + (vec2(-1.0, -1.0) * texcoordOffset)).xyz; + vec3 rgbNE = texture2D(textureSampler, vTexCoord.xy + (vec2(+1.0, -1.0) * texcoordOffset)).xyz; + vec3 rgbSW = texture2D(textureSampler, vTexCoord.xy + (vec2(-1.0, +1.0) * texcoordOffset)).xyz; + vec3 rgbSE = texture2D(textureSampler, vTexCoord.xy + (vec2(+1.0, +1.0) * texcoordOffset)).xyz; + vec3 rgbM = texture2D(textureSampler, vTexCoord.xy).xyz; + + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot( rgbM, luma); + + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce); + + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * texcoordOffset; + + vec3 rgbA = (1.0/2.0) * ( + texture2D(textureSampler, vTexCoord.xy + dir * (1.0/3.0 - 0.5)).xyz + + texture2D(textureSampler, vTexCoord.xy + dir * (2.0/3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * ( + texture2D(textureSampler, vTexCoord.xy + dir * (0.0/3.0 - 0.5)).xyz + + texture2D(textureSampler, vTexCoord.xy + dir * (3.0/3.0 - 0.5)).xyz); + float lumaB = dot(rgbB, luma); + + if((lumaB < lumaMin) || (lumaB > lumaMax)){ + oColor.xyz=rgbA; + } else { + oColor.xyz=rgbB; + } + oColor.a = 1.0; + +// oColor.xyz = rgbM; +} diff --git a/PluginCollection-PostProcessors/Plugin-FXAA/Shaders/FXAA/screenquad.glsl b/PluginCollection-PostProcessors/Plugin-FXAA/Shaders/FXAA/screenquad.glsl new file mode 100644 index 0000000000000000000000000000000000000000..c6824bc3a7529ed93fd41d5060981cfe5c2660f8 --- /dev/null +++ b/PluginCollection-PostProcessors/Plugin-FXAA/Shaders/FXAA/screenquad.glsl @@ -0,0 +1,10 @@ +#version 150 + +in vec4 inPosition; +out vec2 vTexCoord; + +void main() +{ + gl_Position = inPosition; + vTexCoord = inPosition.xy * 0.5 + vec2(0.5, 0.5); +} \ No newline at end of file