-
-
Save miguelbermudez/4212435 to your computer and use it in GitHub Desktop.
Blur shader 2 passing, ping pong attachments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Blur.h> | |
#define ASSERT_BLUR_SETUP() { \ | |
if(!is_setup) { \ | |
printf("ERROR: not setup.\n"); \ | |
return; \ | |
} \ | |
} | |
Blur::Blur() | |
:blur_vbo(0) | |
,blur_vao(0) | |
,blur_shader_v(0) | |
,blur_shader_h(0) | |
,blur_depth(0) | |
,fbo_w(0) | |
,fbo_h(0) | |
,is_setup(false) | |
,tex_uniform(0) | |
{ | |
blur_tex[0] = blur_tex[1] = 0; | |
} | |
Blur::~Blur() { | |
} | |
void Blur::setup(int fboW, int fboH) { | |
fbo_w = fboW; | |
fbo_h = fboH; | |
setupFBO(); | |
setupShaders(); | |
setupVBO(); | |
is_setup = true; | |
} | |
void Blur::setupFBO() { | |
glGenFramebuffers(1, &blur_fbo); | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blur_fbo); | |
glGenRenderbuffers(1, &blur_depth); | |
glBindRenderbuffer(GL_RENDERBUFFER, blur_depth); | |
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, fbo_w, fbo_h); | |
createTexture(blur_tex[0]); | |
createTexture(blur_tex[1]); | |
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, blur_depth); | |
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blur_tex[0], 0); | |
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, blur_tex[1], 0); | |
eglCheckFramebufferStatus(); | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
} | |
void Blur::setupShaders() { | |
GLuint blur_pass_shader = glCreateShader(GL_VERTEX_SHADER); | |
GLuint blur_ver_shader = glCreateShader(GL_FRAGMENT_SHADER); | |
GLuint blur_hor_shader = glCreateShader(GL_FRAGMENT_SHADER); | |
const char* vss = BLUR_VS.c_str(); | |
const char* hor_fss = BLUR_HOR_FS.c_str(); | |
const char* ver_fss = BLUR_VER_FS.c_str(); | |
glShaderSource(blur_pass_shader, 1, &vss, NULL); | |
glShaderSource(blur_ver_shader, 1, &ver_fss, NULL); | |
glShaderSource(blur_hor_shader, 1, &hor_fss, NULL); | |
glCompileShader(blur_pass_shader); eglGetShaderInfoLog(blur_pass_shader); | |
glCompileShader(blur_ver_shader); eglGetShaderInfoLog(blur_ver_shader); | |
glCompileShader(blur_hor_shader); eglGetShaderInfoLog(blur_hor_shader); | |
// Vertical blur | |
blur_shader_v = glCreateProgram(); | |
glAttachShader(blur_shader_v, blur_pass_shader); | |
glAttachShader(blur_shader_v, blur_ver_shader); | |
glBindAttribLocation(blur_shader_v, 0, "a_pos"); | |
glBindAttribLocation(blur_shader_v, 1, "a_tex"); | |
glLinkProgram(blur_shader_v); eglGetError(); | |
glUseProgram(blur_shader_v); | |
glUniform1i(glGetUniformLocation(blur_shader_v, "u_tex"), 0); | |
glUniform1f(glGetUniformLocation(blur_shader_v, "u_blur_size"), 1.0f/fbo_h); | |
// Horizontal blur | |
blur_shader_h = glCreateProgram(); | |
glAttachShader(blur_shader_h, blur_pass_shader); | |
glAttachShader(blur_shader_h, blur_hor_shader); | |
glBindAttribLocation(blur_shader_h, 0, "a_pos"); | |
glBindAttribLocation(blur_shader_h, 1, "a_tex"); | |
glLinkProgram(blur_shader_h); eglGetError(); | |
glUseProgram(blur_shader_h); | |
glUniform1i(glGetUniformLocation(blur_shader_h, "u_tex"), 0); | |
glUniform1f(glGetUniformLocation(blur_shader_h, "u_blur_size"), 1.0f/fbo_w); | |
} | |
void Blur::setupVBO() { | |
GLfloat quad[] = { | |
-1.0f, -1.0f, 0.0f, 0.0f, // BL | |
1.0f, -1.0f, 1.0f, 0.0f, // BR | |
1.0f, 1.0f, 1.0f, 1.0f, // TR | |
1.0f, 1.0f, 1.0f, 1.0f, // TR | |
-1.0f, 1.0f, 0.0f, 1.0f, // TL | |
-1.0f, -1.0f, 0.0f, 0.0f // BL | |
}; | |
glGenVertexArraysAPPLE(1, &blur_vao); | |
glBindVertexArrayAPPLE(blur_vao); | |
glGenBuffers(1, &blur_vbo); | |
glBindBuffer(GL_ARRAY_BUFFER, blur_vbo); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4 * 6, quad, GL_STATIC_DRAW); | |
glEnableVertexAttribArray(0); // pos | |
glEnableVertexAttribArray(1); // tex | |
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (GLvoid*) 0); | |
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (GLvoid*) (sizeof(GLfloat) * 2)); | |
} | |
void Blur::bind() { | |
ASSERT_BLUR_SETUP(); | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blur_fbo); | |
glDrawBuffer(GL_COLOR_ATTACHMENT0); | |
glClearColor(0.0f, 0.0f, 0.0f,1.0f); | |
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); | |
} | |
void Blur::unbind() { | |
ASSERT_BLUR_SETUP(); | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
} | |
void Blur::draw() { | |
ASSERT_BLUR_SETUP(); | |
glBindVertexArrayAPPLE(blur_vao); | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blur_fbo); | |
// Ping.... | |
// Draw into ATTACHMNET 1 (blur_tex[1]), sample from blur_tex[0] ==> scene | |
glDrawBuffer(GL_COLOR_ATTACHMENT1); | |
glUseProgram(blur_shader_h); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_2D, blur_tex[0]); | |
glDrawArrays(GL_TRIANGLES, 0, 6); | |
// Pong.... | |
// Draw into ATTACHMENT 0 (blur_tex[0]), sample from blur_tex[1] ==> scene + horizontal blur | |
glDrawBuffer(GL_COLOR_ATTACHMENT0); | |
glUseProgram(blur_shader_v); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_2D, blur_tex[1]); | |
glDrawArrays(GL_TRIANGLES, 0, 6); | |
// draw full screen | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
glDrawBuffer(GL_BACK_LEFT); | |
glBindTexture(GL_TEXTURE_2D, blur_tex[1]); | |
glDrawArrays(GL_TRIANGLES, 0, 6); | |
} | |
// -------- | |
void Blur::createTexture(GLuint& tex) { | |
glGenTextures(1, &tex); | |
glBindTexture(GL_TEXTURE_2D, tex); | |
//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_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fbo_w, fbo_h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ROXLU_BLURH | |
#define ROXLU_BLURH | |
#include <roxlu/Roxlu.h> | |
#include <string> | |
const std::string BLUR_VS = "" \ | |
"attribute vec4 a_pos;" \ | |
"attribute vec2 a_tex;" \ | |
"varying vec2 v_tex; " \ | |
" " \ | |
" void main() { " \ | |
" gl_Position = a_pos; " \ | |
" v_tex = a_tex; " \ | |
" } " \ | |
""; | |
// blur from: http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ | |
const std::string BLUR_HOR_FS = "" \ | |
" uniform sampler2D u_tex; " \ | |
" uniform float u_blur_size; " \ | |
" varying vec2 v_tex; " \ | |
" " \ | |
" void main() { " \ | |
" vec4 sum = vec4(0.0); " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x - 4.0 * u_blur_size, v_tex.y)) * 0.05; "\ | |
" sum += texture2D(u_tex, vec2(v_tex.x - 3.0 * u_blur_size, v_tex.y)) * 0.09; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x - 2.0 * u_blur_size, v_tex.y)) * 0.12; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x - u_blur_size, v_tex.y)) * 0.15; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x, v_tex.y)) * 0.16; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x + u_blur_size, v_tex.y)) * 0.15; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x + 2.0 * u_blur_size, v_tex.y)) * 0.12; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x + 3.0 * u_blur_size, v_tex.y)) * 0.09; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x + 4.0 * u_blur_size, v_tex.y)) * 0.05; " \ | |
" gl_FragColor = sum; " \ | |
" } " \ | |
""; | |
const std::string BLUR_VER_FS = "" \ | |
" uniform sampler2D u_tex; " \ | |
" uniform float u_blur_size; " \ | |
" varying vec2 v_tex; " \ | |
" " \ | |
" void main() { " \ | |
" vec4 sum = vec4(0.0); " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x, v_tex.y - 4.0 * u_blur_size)) * 0.05; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x, v_tex.y - 3.0 * u_blur_size)) * 0.09; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x, v_tex.y - 2.0 * u_blur_size)) * 0.12; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x, v_tex.y - u_blur_size)) * 0.15; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x, v_tex.y)) * 0.16; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x, v_tex.y + u_blur_size)) * 0.15; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x, v_tex.y + 2.0* u_blur_size)) * 0.12; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x, v_tex.y + 3.0* u_blur_size)) * 0.09; " \ | |
" sum += texture2D(u_tex, vec2(v_tex.x, v_tex.y + 4.0* u_blur_size)) * 0.05; " \ | |
" gl_FragColor = sum; " \ | |
" } " \ | |
""; | |
class Blur { | |
public: | |
Blur(); | |
~Blur(); | |
void setup(int fboW, int fboH); | |
void bind(); | |
void unbind(); | |
void draw(); | |
private: | |
void setupFBO(); | |
void setupVBO(); | |
void setupShaders(); | |
void createTexture(GLuint& tex); | |
private: | |
bool is_setup; | |
int fbo_w; | |
int fbo_h; | |
GLuint blur_vbo; | |
GLuint blur_vao; | |
GLuint blur_shader_v; | |
GLuint blur_shader_h; | |
GLuint blur_fbo; | |
GLuint blur_depth; | |
GLuint blur_tex[2]; | |
GLuint tex_uniform; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment