[gens-sdl] GLShaderFastBlur: Ported the Fast Blur shader from gens-qt4.
authorDavid Korth <gerbilsoft@gerbilsoft.com>
Wed, 2 Sep 2015 01:26:52 +0000 (21:26 -0400)
committerDavid Korth <gerbilsoft@gerbilsoft.com>
Wed, 2 Sep 2015 01:26:52 +0000 (21:26 -0400)
This includes the GLShader base class.

There's a few differences between the gens-sdl version and the
original gens-qt4 version:

- GLEW is no longer conditional. There's no point in supporting
  a build without GLEW, since GLEW makes GL feature detection
  much easier.

- GLBackend handles the shaders directly, instead of using
  a separate GLShaderManager class.

- init() and end() return error codes, as do enable() and disable().

- The two shader name variables have been combined into a single
  variable, m_shaderName. Only one type of each shader can be in
  use at any given time, so there's no point in reserving memory
  for both the ARB fp name and the ATi fragment shader name.

- GLShaderFastBlur: The actual fragment program text is now stored
  in a private class, using const char[] instead of const char *const.
  This reduces memory usage by one pointer.

- sizeof() is used to determine the program size. Note that the NULL
  terminator should not be included. NVIDIA's Windows driver refuses
  to compile the shader if it is included; Mesa's r300g driver doesn't
  care if it is or not.

src/gens-sdl/CMakeLists.txt
src/gens-sdl/GLBackend.cpp
src/gens-sdl/GLShader.cpp [new file with mode: 0644]
src/gens-sdl/GLShader.hpp [new file with mode: 0644]
src/gens-sdl/GLShaderFastBlur.cpp [new file with mode: 0644]
src/gens-sdl/GLShaderFastBlur.hpp [new file with mode: 0644]

index c99089e..59a89b9 100644 (file)
@@ -72,12 +72,26 @@ SET(gens-sdl_OSD_H
        OsdFont_C64.hpp
        )
 
+# Shader sources.
+SET(gens-sdl_SHADER_SRCS
+       GLShader.cpp
+       GLShaderFastBlur.cpp
+       )
+
+# Shader headers.
+SET(gens-sdl_SHADER_H
+       GLShader.hpp
+       GLShaderFastBlur.hpp
+       )
+
 # Main target.
 ADD_EXECUTABLE(gens-sdl
        ${gens-sdl_SRCS}
        ${gens-sdl_H}
        ${gens-sdl_OSD_SRCS}
        ${gens-sdl_OSD_H}
+       ${gens-sdl_SHADER_SRCS}
+       ${gens-sdl_SHADER_H}
        )
 TARGET_LINK_LIBRARIES(gens-sdl compat gens genskeys zomg)
 DO_SPLIT_DEBUG(gens-sdl)
index 6aea678..72538bc 100644 (file)
@@ -43,6 +43,9 @@ using LibGens::FastBlur;
 // GL Texture wrpaper.
 #include "GLTex.hpp"
 
+// GL shaders.
+#include "GLShaderFastBlur.hpp"
+
 namespace GensSdl {
 
 class GLBackendPrivate {
@@ -77,6 +80,9 @@ class GLBackendPrivate {
                // Onscreen Display.
                OsdGL *osd;
 
+               // GL shaders.
+               GLShaderFastBlur *fastBlurShader;
+
        public:
                /**
                 * Reallocate the OpenGL texture.
@@ -123,11 +129,13 @@ GLBackendPrivate::GLBackendPrivate(GLBackend *q)
        , prevStretchMode(VBackend::STRETCH_MAX)
        , prevAspectRatioConstraint(true)
        , osd(new OsdGL())
+       , fastBlurShader(new GLShaderFastBlur())
 { }
 
 GLBackendPrivate::~GLBackendPrivate()
 {
        delete osd;
+       delete fastBlurShader;
 }
 
 /**
@@ -308,7 +316,7 @@ const MdFb *GLBackendPrivate::applySoftwareEffects(void)
        MdFb *fb = q->m_fb;     // FB to use.
        bool isIntFb = false;
 
-       if (q->m_fastBlur) {
+       if (q->m_fastBlur  && !fastBlurShader->isUsable()) {
                // Make sure we have an internal framebuffer.
                if (!q->m_int_fb) {
                        q->m_int_fb = new MdFb();
@@ -348,7 +356,10 @@ const MdFb *GLBackendPrivate::applySoftwareEffects(void)
  */
 void GLBackendPrivate::startShaderEffects(void)
 {
-       // TODO
+       if (q->m_fastBlur && fastBlurShader->isUsable()) {
+               // Enable the Fast Blur effect.
+               fastBlurShader->enable();
+       }
 }
 
 /**
@@ -356,7 +367,10 @@ void GLBackendPrivate::startShaderEffects(void)
  */
 void GLBackendPrivate::stopShaderEffects(void)
 {
-       // TODO
+       if (q->m_fastBlur && fastBlurShader->isUsable()) {
+               // Disable the Fast Blur effect.
+               fastBlurShader->disable();
+       }
 }
 
 /** GLBackend **/
@@ -540,6 +554,9 @@ void GLBackend::initGL(void)
 
        // Initialize the OSD.
        d->osd->init();
+
+       // Initialize the shaders.
+       d->fastBlurShader->init();
 }
 
 /**
@@ -550,6 +567,9 @@ void GLBackend::endGL(void)
 {
        // TODO: makeCurrent()?
 
+       // Shut down the shaders.
+       d->fastBlurShader->end();
+
        // Shut down the OSD.
        d->osd->end();
 
diff --git a/src/gens-sdl/GLShader.cpp b/src/gens-sdl/GLShader.cpp
new file mode 100644 (file)
index 0000000..31868e5
--- /dev/null
@@ -0,0 +1,179 @@
+/***************************************************************************
+ * gens-sdl: Gens/GS II basic SDL frontend.                                *
+ * GLShader.cpp: OpenGL Shader. (Base Class)                               *
+ *                                                                         *
+ * Copyright (c) 2010-2015 by David Korth.                                 *
+ *                                                                         *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU General Public License as published by the   *
+ * Free Software Foundation; either version 2 of the License, or (at your  *
+ * option) any later version.                                              *
+ *                                                                         *
+ * This program 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 General Public License for more details.                            *
+ *                                                                         *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.           *
+ ***************************************************************************/
+
+#include "GLShader.hpp"
+
+namespace GensSdl {
+
+GLShader::GLShader()
+       : m_shaderType(ST_NONE)
+       , m_shaderName(0)
+{ }
+
+GLShader::~GLShader()
+{
+       end();
+}
+
+
+/**
+ * Shut down the shader.
+ * This must be run from within a valid GL context!
+ * @return 0 on success; non-zero on error.
+ */
+int GLShader::end(void)
+{
+       if (m_shaderName == 0) {
+               // No shader.
+               // TODO: POSIX error code?
+               return -1;
+       }
+
+       int ret = 0;
+       switch (m_shaderType) {
+               case ST_GL_ARB_FRAGMENT_PROGRAM:
+#ifdef ENABLE_ATI_TEXT_FRAGMENT_SHADER
+               case ST_GL_ATI_TEXT_FRAGMENT_SHADER:
+#endif
+                       // Delete the ARB program.
+                       // (Also used for ATI text fragment shaders.)
+                       glDeleteProgramsARB(1, &m_shaderName);
+                       break;
+
+               case ST_GL_ATI_FRAGMENT_SHADER:
+                       glDeleteFragmentShaderATI(m_shaderName);
+                       break;
+
+               default:
+                       ret = -1;
+                       break;
+       }
+
+       // Shader has been deleted.
+       m_shaderType = ST_NONE;
+       m_shaderName = 0;
+       return ret;
+}
+
+/**
+ * Enable the shader.
+ * @return 0 on success; non-zero on error.
+ */
+int GLShader::enable(void)
+{
+       if (m_shaderName == 0) {
+               // No shader has been compiled.
+               // TODO: POSIX error code?
+               return -1;
+       }
+
+       int ret = 0;
+       switch (m_shaderType) {
+               case ST_GL_ARB_FRAGMENT_PROGRAM:
+#ifdef ENABLE_ATI_TEXT_FRAGMENT_SHADER
+               case ST_GL_ATI_TEXT_FRAGMENT_SHADER:
+#endif /* ENABLE_ATI_TEXT_FRAGMENT_SHADER */
+               {
+#ifdef ENABLE_ATI_TEXT_FRAGMENT_SHADER
+                       const GLenum prgType = (m_shaderType == ST_GL_ARB_FRAGMENT_PROGRAM
+                                               ? GL_FRAGMENT_PROGRAM_ARB
+                                               : GL_TEXT_FRAGMENT_SHADER_ATI);
+#else /* !ENABLE_ATI_TEXT_FRAGMENT_SHADER */
+                       const GLenum prgType = GL_FRAGMENT_PROGRAM_ARB;
+#endif /* ENABLE_ATI_TEXT_FRAGMENT_SHADER */
+
+                       // Enable the shader.
+                       glEnable(prgType);
+                       glBindProgramARB(prgType, m_shaderName);
+                       break;
+               }
+
+               case ST_GL_ATI_FRAGMENT_SHADER:
+                       glEnable(GL_FRAGMENT_SHADER_ATI);
+                       glBindFragmentShaderATI(m_shaderName);
+                       break;
+
+               default:
+                       // TODO: POSIX error code?
+                       ret = -1;
+                       break;
+       }
+
+       return ret;
+}
+
+
+/**
+ * Disable the shader.
+ * @return 0 on success; non-zero on error.
+ */
+int GLShader::disable(void)
+{
+       if (m_shaderName == 0) {
+               // No shader has been compiled.
+               // TODO: POSIX error code?
+               return -1;
+       }
+
+       int ret = 0;
+       switch (m_shaderType) {
+               case ST_GL_ARB_FRAGMENT_PROGRAM:
+#ifdef ENABLE_ATI_TEXT_FRAGMENT_SHADER
+               case ST_GL_ATI_TEXT_FRAGMENT_SHADER:
+#endif /* ENABLE_ATI_TEXT_FRAGMENT_SHADER */
+               {
+#ifdef ENABLE_ATI_TEXT_FRAGMENT_SHADER
+                       const GLenum prgType = (m_shaderType == ST_GL_ARB_FRAGMENT_PROGRAM
+                                               ? GL_FRAGMENT_PROGRAM_ARB
+                                               : GL_TEXT_FRAGMENT_SHADER_ATI);
+#else /* !ENABLE_ATI_TEXT_FRAGMENT_SHADER */
+                       const GLenum prgType = GL_FRAGMENT_PROGRAM_ARB;
+#endif /* ENABLE_ATI_TEXT_FRAGMENT_SHADER */
+
+                       // Disable the shader.
+                       glDisable(prgType);
+#ifdef ENABLE_ATI_TEXT_FRAGMENT_SHADER
+                       if (m_shaderType == ST_GL_ATI_TEXT_FRAGMENT_SHADER) {
+                               // HACK: at least the Mac OS X 10.5 PPC Radeon drivers are broken and
+                               // without this disable the texture units while the program is still
+                               // running (10.4 PPC seems to work without this though).
+                               // Reference: http://git.mplayerhq.hu/?p=mplayer;a=blob;f=libvo/gl_common.c;hb=HEAD
+                               // NOTE: It doesn't seem to help any...
+                               glFlush();
+                       }
+#endif /* ENABLE_ATI_TEXT_FRAGMENT_SHADER */
+                       break;
+               }
+
+               case ST_GL_ATI_FRAGMENT_SHADER:
+                       glDisable(GL_FRAGMENT_SHADER_ATI);
+                       break;
+
+               default:
+                       // TODO: POSIX error code?
+                       ret = -1;
+                       break;
+       }
+
+       return ret;
+}
+
+}
diff --git a/src/gens-sdl/GLShader.hpp b/src/gens-sdl/GLShader.hpp
new file mode 100644 (file)
index 0000000..af3df4b
--- /dev/null
@@ -0,0 +1,140 @@
+/***************************************************************************
+ * gens-sdl: Gens/GS II basic SDL frontend.                                *
+ * GLShader.hpp: OpenGL Shader. (Base Class)                               *
+ *                                                                         *
+ * Copyright (c) 2010-2015 by David Korth.                                 *
+ *                                                                         *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU General Public License as published by the   *
+ * Free Software Foundation; either version 2 of the License, or (at your  *
+ * option) any later version.                                              *
+ *                                                                         *
+ * This program 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 General Public License for more details.                            *
+ *                                                                         *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.           *
+ ***************************************************************************/
+
+#ifndef __GENS_SDL_GLSHADER_HPP__
+#define __GENS_SDL_GLSHADER_HPP__
+
+// OpenGL. (GLEW)
+#include <GL/glew.h>
+
+// Disabled for now due to problems with Mac OS X 10.5.7 PPC.
+// (Radeon 9000 series video card)
+//#define ENABLE_ATI_TEXT_FRAGMENT_SHADER
+
+namespace GensSdl {
+
+class GLShader
+{
+       public:
+               GLShader();
+               virtual ~GLShader();
+
+               /**
+                * Initialize the shader.
+                * This must be run from within a valid GL context!
+                * @return 0 on success; non-zero on error.
+                */
+               virtual int init(void) = 0;
+
+               /**
+                * Shut down the shader.
+                * This must be run from within a valid GL context!
+                * @return 0 on success; non-zero on error.
+                */
+               virtual int end(void);
+
+               /**
+                * Enable the shader.
+                * @return 0 on success; non-zero on error.
+                */
+               virtual int enable(void);
+
+               /**
+                * Disable the shader.
+                * @return 0 on success; non-zero on error.
+                */
+               int disable(void);
+
+               /**
+                * GL Shader type.
+                * Indicates the type of shader in use.
+                */
+               enum GLShaderType {
+                       ST_NONE                         = 0,
+                       ST_GL_ARB_FRAGMENT_PROGRAM,
+                       ST_GL_ATI_FRAGMENT_SHADER,
+#ifdef ENABLE_ATI_TEXT_FRAGMENT_SHADER
+                       ST_GL_ATI_TEXT_FRAGMENT_SHADER,
+#endif
+
+                       ST_MAX
+               };
+
+               /**
+                * Get the GL shader type.
+                * @return Shader type.
+                */
+               inline GLShaderType shaderType(void) const;
+
+               /**
+                * Is the shader usable?
+                * @return True if usable; false if not.
+                */
+               inline bool isUsable(void) const;
+
+       private:
+               // Shader type.
+               GLShaderType m_shaderType;
+
+       protected:
+               /**
+                * Set the shader type.
+                * @param shaderType New shader type.
+                */
+               inline void setShaderType(GLShaderType shaderType);
+
+               // Shader name.
+               // Type of object depends on m_shaderType.
+               // TODO: Make private with accessors, like m_shaderType?
+               GLuint m_shaderName;
+};
+
+/**
+ * Get the GL shader type.
+ * @return Shader type.
+ */
+inline GLShader::GLShaderType GLShader::shaderType(void) const
+       { return m_shaderType; }
+
+/**
+ * Set the GL shader type.
+ * @param shaderType New shader type.
+ */
+inline void GLShader::setShaderType(GLShaderType shaderType)
+{
+       // TODO: If m_shaderName != 0, deallocate it.
+       m_shaderType = shaderType;
+}
+
+/**
+ * Is the shader usable?
+ * @return True if usable; false if not.
+ */
+inline bool GLShader::isUsable(void) const
+{
+       // NOTE: Only checking m_shaderType.
+       // TODO: Also check m_shaderName != 0?
+       return (m_shaderType != ST_NONE);
+}
+
+}
+
+#endif /* __GENS_SDL_GLSHADER_HPP__ */
diff --git a/src/gens-sdl/GLShaderFastBlur.cpp b/src/gens-sdl/GLShaderFastBlur.cpp
new file mode 100644 (file)
index 0000000..141bf76
--- /dev/null
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * gens-sdl: Gens/GS II basic SDL frontend.                                *
+ * GLShaderFastBlur.cpp: OpenGL Shader. (Fast Blur)                        *
+ *                                                                         *
+ * Copyright (c) 2010-2011 by David Korth.                                 *
+ *                                                                         *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU General Public License as published by the   *
+ * Free Software Foundation; either version 2 of the License, or (at your  *
+ * option) any later version.                                              *
+ *                                                                         *
+ * This program 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 General Public License for more details.                            *
+ *                                                                         *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.           *
+ ***************************************************************************/
+
+#include "GLShaderFastBlur.hpp"
+
+// LOG_MSG() subsystem.
+#include "libgens/macros/log_msg.h"
+
+// C includes.
+#include <string.h>
+
+namespace GensSdl {
+
+class GLShaderFastBlurPrivate {
+       private:
+               GLShaderFastBlurPrivate() { }
+               ~GLShaderFastBlurPrivate() { }
+       private:
+               // Q_DISABLE_COPY() equivalent.
+               // TODO: Add GensSdl-specific version of Q_DISABLE_COPY().
+               GLShaderFastBlurPrivate(const GLShaderFastBlurPrivate &);
+               GLShaderFastBlurPrivate &operator=(const GLShaderFastBlurPrivate &);
+
+       public:
+               // GL_ARB_fragment_program implementation.
+               static const char FastBlur_ARB_fragment_program[];
+};
+
+/** Shaders. **/
+
+/**
+ * GL_ARB_fragment_program implementation.
+ * Based on GLSL code by Damizean.
+ */
+const char GLShaderFastBlurPrivate::FastBlur_ARB_fragment_program[] =
+       "!!ARBfp1.0\n"
+       "OPTION ARB_precision_hint_fastest;\n"
+       "PARAM div2 = {0.5, 0.5, 0.5, 0.0};\n"                  // Divide by 2 vector.
+       "PARAM offset = program.local[0];\n"                    // Texture offset vector.
+       "TEMP t0, tx1, t1;\n"
+       "TEX t0, fragment.texcoord[0], texture[0], 2D;\n"       // Get first pixel.
+       "ADD tx1, fragment.texcoord[0], offset;\n"              // Calculate offset of next pixel.
+       "TEX t1, tx1, texture[0], 2D;\n"                        // Get second pixel.
+       "ADD t0, t0, t1;\n"                                     // Add the two colors together.
+       "MUL result.color, t0, div2;\n"                         // Divide the result by two.
+       "END\n";
+
+/**
+ * Initialize the shader.
+ * This must be run from within a valid GL context!
+ * @return 0 on success; non-zero on error.
+ */
+int GLShaderFastBlur::init()
+{
+       if (!GLEW_VERSION_2_0 && !GLEW_ARB_fragment_program) {
+               // GL_ARB_fragment_program is NOT supported.
+               // TODO: POSIX error code?
+               return -1;
+       }
+
+       // Load the Fast Blur fragment program.
+       int ret = 0;
+
+       // TODO: Check for errors!
+       GLuint shaderName;
+       glGenProgramsARB(1, &shaderName);
+       glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, shaderName);
+       glGetError();   // Clear the error flag.
+       // NOTE: sizeof(str)-1 - NVIDIA's Windows driver doesn't like
+       // the NULL terminator, and refuses to compile the shader if
+       // it's included. Mesa's r300g driver doesn't care if the NULL
+       // terminator is present.
+       glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+                               sizeof(GLShaderFastBlurPrivate::FastBlur_ARB_fragment_program)-1,
+                               GLShaderFastBlurPrivate::FastBlur_ARB_fragment_program);
+
+       GLenum err = glGetError();
+       if (err == GL_NO_ERROR) {
+               // Fragment program loaded.
+               m_shaderName = shaderName;
+               setShaderType(ST_GL_ARB_FRAGMENT_PROGRAM);
+       } else {
+               // An error occured while loading the fragment program.
+               // TODO: Remove the extra newline at the end of err_str.
+               // TODO: POSIX error code?
+               ret = -1;
+               const char *err_str = (const char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB);
+               LOG_MSG(video, LOG_MSG_LEVEL_ERROR,
+                       "Error creating Fast Blur effect ARB FP: %s", (err_str ? err_str : "(unknown)"));
+
+               // Delete the fragment program.
+               if (shaderName > 0) {
+                       glDeleteProgramsARB(1, &shaderName);
+                       m_shaderName = 0;
+                       setShaderType(ST_NONE);
+               }
+       }
+
+       return ret;
+}
+
+
+/**
+ * Enable the shader.
+ * @return 0 on success; non-zero on error.
+ */
+int GLShaderFastBlur::enable(void)
+{
+       if (shaderType() != ST_GL_ARB_FRAGMENT_PROGRAM ||
+           m_shaderName == 0)
+       {
+               // Shader has not been loaded.
+               // TODO: POSIX error code?
+               return -1;
+       }
+       
+       // Enable the shader.
+       // TODO: Get texture width for the parameter!
+       glEnable(GL_FRAGMENT_PROGRAM_ARB);
+       glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, (1/512.0f), 0, 0, 0);
+       glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_shaderName);
+       return 0;
+}
+
+}
diff --git a/src/gens-sdl/GLShaderFastBlur.hpp b/src/gens-sdl/GLShaderFastBlur.hpp
new file mode 100644 (file)
index 0000000..e21c1a4
--- /dev/null
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * gens-sdl: Gens/GS II basic SDL frontend.                                *
+ * GLShaderFastBlur.hpp: OpenGL Shader. (Fast Blur)                        *
+ *                                                                         *
+ * Copyright (c) 2010-2015 by David Korth.                                 *
+ *                                                                         *
+ * This program is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU General Public License as published by the   *
+ * Free Software Foundation; either version 2 of the License, or (at your  *
+ * option) any later version.                                              *
+ *                                                                         *
+ * This program 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 General Public License for more details.                            *
+ *                                                                         *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.           *
+ ***************************************************************************/
+
+#ifndef __GENS_SDL_GLSHADERFASTBLUR_HPP__
+#define __GENS_SDL_GLSHADERFASTBLUR_HPP__
+
+#include "GLShader.hpp"
+
+namespace GensSdl {
+
+class GLShaderFastBlur : public GLShader
+{
+       public:
+               /**
+                * Initialize the shader.
+                * This must be run from within a valid GL context!
+                * @return 0 on success; non-zero on error.
+                */
+               virtual int init(void) final;
+
+               /**
+                * Enable the shader.
+                * @return 0 on success; non-zero on error.
+                */
+               virtual int enable(void) final;
+};
+
+}
+
+#endif /* __GENS_SDL_GLSHADERFASTBLUR_HPP__ */