diff --git a/effects/effect.cpp b/effects/effect.cpp index 91985d6b5..202458a3f 100644 --- a/effects/effect.cpp +++ b/effects/effect.cpp @@ -26,6 +26,7 @@ #include "effects/video/gaussianblureffect.h" #include "effects/video/cropeffect.h" #include "effects/video/flipeffect.h" +#include "effects/video/boxblureffect.h" #include "effects/audio/paneffect.h" #include "effects/audio/volumeeffect.h" @@ -53,6 +54,7 @@ void init_effects() { video_effect_names[VIDEO_GAUSSIANBLUR_EFFECT] = "Gaussian Blur"; video_effect_names[VIDEO_CROP_EFFECT] = "Crop"; video_effect_names[VIDEO_FLIP_EFFECT] = "Flip"; + video_effect_names[VIDEO_BOXBLUR_EFFECT] = "Box Blur"; audio_effect_names[AUDIO_VOLUME_EFFECT] = "Volume"; audio_effect_names[AUDIO_PAN_EFFECT] = "Pan"; @@ -71,6 +73,7 @@ Effect* create_effect(int effect_id, Clip* c) { case VIDEO_GAUSSIANBLUR_EFFECT: return new GaussianBlurEffect(c); break; case VIDEO_CROP_EFFECT: return new CropEffect(c); case VIDEO_FLIP_EFFECT: return new FlipEffect(c); + case VIDEO_BOXBLUR_EFFECT: return new BoxBlurEffect(c); } } else { switch (effect_id) { diff --git a/effects/effect.h b/effects/effect.h index 99bdea52e..c16d7d142 100644 --- a/effects/effect.h +++ b/effects/effect.h @@ -29,6 +29,7 @@ enum VideoEffects { VIDEO_GAUSSIANBLUR_EFFECT, VIDEO_CROP_EFFECT, VIDEO_FLIP_EFFECT, + VIDEO_BOXBLUR_EFFECT, VIDEO_EFFECT_COUNT }; diff --git a/effects/video/boxblureffect.cpp b/effects/video/boxblureffect.cpp new file mode 100644 index 000000000..02ffad4d9 --- /dev/null +++ b/effects/video/boxblureffect.cpp @@ -0,0 +1,45 @@ +#include "boxblureffect.h" + +#include "project/clip.h" + +BoxBlurEffect::BoxBlurEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_BOXBLUR_EFFECT), vert(QOpenGLShader::Vertex), frag(QOpenGLShader::Fragment) { + enable_opengl = true; + + radius_val = add_row("Radius:")->add_field(EFFECT_FIELD_DOUBLE); +// iteration_val = add_row("Iterations:")->add_field(EFFECT_FIELD_DOUBLE); + horiz_val = add_row("Horizontal:")->add_field(EFFECT_FIELD_BOOL); + vert_val = add_row("Vertical:")->add_field(EFFECT_FIELD_BOOL); + + radius_val->set_double_default_value(9); + radius_val->set_double_minimum_value(0); + +// iteration_val->set_double_default_value(1); +// iteration_val->set_double_minimum_value(0); + + horiz_val->set_bool_value(true); + vert_val->set_bool_value(true); + + vert.compileSourceFile(":/shaders/common.vert"); + frag.compileSourceFile(":/shaders/boxblureffect.frag"); + program.addShader(&vert); + program.addShader(&frag); + program.link(); + + connect(radius_val, SIGNAL(changed()), this, SLOT(field_changed())); +// connect(iteration_val, SIGNAL(changed()), this, SLOT(field_changed())); + connect(horiz_val, SIGNAL(changed()), this, SLOT(field_changed())); + connect(vert_val, SIGNAL(changed()), this, SLOT(field_changed())); +} + +void BoxBlurEffect::process_gl(double timecode, GLTextureCoords &coords) { + program.bind(); + + program.setUniformValue("resolution", parent_clip->getWidth(), parent_clip->getHeight()); + program.setUniformValue("radius", (GLfloat) radius_val->get_double_value(timecode)); + program.setUniformValue("horiz_blur", horiz_val->get_bool_value(timecode)); + program.setUniformValue("vert_blur", vert_val->get_bool_value(timecode)); +} + +void BoxBlurEffect::clean_gl() { + program.release(); +} diff --git a/effects/video/boxblureffect.h b/effects/video/boxblureffect.h new file mode 100644 index 000000000..73e800894 --- /dev/null +++ b/effects/video/boxblureffect.h @@ -0,0 +1,24 @@ +#ifndef BOXBLUREFFECT_H +#define BOXBLUREFFECT_H + +#include "../effect.h" + +class BoxBlurEffect : public Effect +{ +public: + BoxBlurEffect(Clip* c); + + void process_gl(double timecode, GLTextureCoords &coords); + void clean_gl(); +private: + QOpenGLShaderProgram program; + QOpenGLShader vert; + QOpenGLShader frag; + + EffectField* radius_val; + EffectField* iteration_val; + EffectField* horiz_val; + EffectField* vert_val; +}; + +#endif // BOXBLUREFFECT_H diff --git a/effects/video/gaussianblureffect.cpp b/effects/video/gaussianblureffect.cpp index 9dbf25cec..ba88e11e4 100644 --- a/effects/video/gaussianblureffect.cpp +++ b/effects/video/gaussianblureffect.cpp @@ -4,19 +4,18 @@ #include -GaussianBlurEffect::GaussianBlurEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_GAUSSIANBLUR_EFFECT), frag(QOpenGLShader::Fragment), vert(QOpenGLShader::Vertex), bound(false) { - enable_opengl = true; - enable_image = false; +GaussianBlurEffect::GaussianBlurEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_GAUSSIANBLUR_EFFECT), frag(QOpenGLShader::Fragment), vert(QOpenGLShader::Vertex) { + enable_opengl = true; - kernelsz_val = add_row("Kernel Size:")->add_field(EFFECT_FIELD_DOUBLE); + radius_val = add_row("Radius:")->add_field(EFFECT_FIELD_DOUBLE); sigma_val = add_row("Sigma:")->add_field(EFFECT_FIELD_DOUBLE); horiz_val = add_row("Horizontal:")->add_field(EFFECT_FIELD_BOOL); vert_val = add_row("Vertical:")->add_field(EFFECT_FIELD_BOOL); - kernelsz_val->set_double_minimum_value(0); + radius_val->set_double_minimum_value(0); sigma_val->set_double_minimum_value(0); - kernelsz_val->set_double_default_value(9); + radius_val->set_double_default_value(9); sigma_val->set_double_default_value(5.5); horiz_val->set_bool_value(true); @@ -28,19 +27,17 @@ GaussianBlurEffect::GaussianBlurEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, V program.addShader(&frag); program.link(); - connect(kernelsz_val, SIGNAL(changed()), this, SLOT(field_changed())); + connect(radius_val, SIGNAL(changed()), this, SLOT(field_changed())); connect(sigma_val, SIGNAL(changed()), this, SLOT(field_changed())); connect(horiz_val, SIGNAL(changed()), this, SLOT(field_changed())); - connect(vert_val, SIGNAL(changed()), this, SLOT(field_changed())); - - refresh(); + connect(vert_val, SIGNAL(changed()), this, SLOT(field_changed())); } void GaussianBlurEffect::process_gl(double timecode, GLTextureCoords &coords) { program.bind(); program.setUniformValue("resolution", parent_clip->getWidth(), parent_clip->getHeight()); - program.setUniformValue("kernel_size", (GLfloat) kernelsz_val->get_double_value(timecode)); + program.setUniformValue("radius", (GLfloat) radius_val->get_double_value(timecode)); program.setUniformValue("sigma", (GLfloat) sigma_val->get_double_value(timecode)); program.setUniformValue("horiz_blur", horiz_val->get_bool_value(timecode)); program.setUniformValue("vert_blur", vert_val->get_bool_value(timecode)); diff --git a/effects/video/gaussianblureffect.h b/effects/video/gaussianblureffect.h index bdcbb75b1..2be320be8 100644 --- a/effects/video/gaussianblureffect.h +++ b/effects/video/gaussianblureffect.h @@ -14,12 +14,10 @@ private: QOpenGLShader vert; QOpenGLShader frag; - EffectField* kernelsz_val; + EffectField* radius_val; EffectField* sigma_val; EffectField* horiz_val; - EffectField* vert_val; - - bool bound; + EffectField* vert_val; }; #endif // GAUSSIANBLUREFFECT_H diff --git a/effects/video/glsl/boxblureffect.frag b/effects/video/glsl/boxblureffect.frag new file mode 100644 index 000000000..ecf51b97a --- /dev/null +++ b/effects/video/glsl/boxblureffect.frag @@ -0,0 +1,51 @@ +#version 110 + +#define M_PI 3.1415926535897932384626433832795 + +uniform sampler2D image; + +uniform float radius; +uniform vec2 resolution; +uniform bool horiz_blur; +uniform bool vert_blur; + +void main(void) { + if (radius == 0.0 || (!horiz_blur && !vert_blur)) { + gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution); + } else { + float divider = 1.0 / ((radius*2.0)+1.0); + if (horiz_blur && vert_blur) { + divider *= divider; + + gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution)*divider; + + for (float i=1.0;i<=radius;i++) { + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-i, gl_FragCoord.y))/resolution)*(divider); + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x+i, gl_FragCoord.y))/resolution)*(divider); + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x, gl_FragCoord.y+i))/resolution)*(divider); + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x, gl_FragCoord.y-i))/resolution)*(divider); + } + + for (float x=1.0;x<=radius;x++) { + for (float y=1.0;y<=radius;y++) { + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-x, gl_FragCoord.y-y))/resolution)*(divider); + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x+x, gl_FragCoord.y+y))/resolution)*(divider); + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-x, gl_FragCoord.y+y))/resolution)*(divider); + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x+x, gl_FragCoord.y-y))/resolution)*(divider); + } + } + } else { + gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution)*(divider); + + for (float i=1.0;i<=radius;i++) { + if (horiz_blur) { + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x-i, gl_FragCoord.y))/resolution)*(divider); + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x+i, gl_FragCoord.y))/resolution)*(divider); + } else { + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x, gl_FragCoord.y-i))/resolution)*(divider); + gl_FragColor += texture2D(image, (vec2(gl_FragCoord.x, gl_FragCoord.y+i))/resolution)*(divider); + } + } + } + } +} \ No newline at end of file diff --git a/effects/video/glsl/gaussianblureffect.frag b/effects/video/glsl/gaussianblureffect.frag index 4a1cbddb7..6da8a136a 100644 --- a/effects/video/glsl/gaussianblureffect.frag +++ b/effects/video/glsl/gaussianblureffect.frag @@ -4,7 +4,7 @@ uniform sampler2D image; -uniform float kernel_size; +uniform float radius; uniform float sigma; uniform vec2 resolution; uniform bool horiz_blur; @@ -19,25 +19,35 @@ float gaussian2(float x, float y, float sigma) { } void main(void) { - if (kernel_size == 0.0 || sigma == 0.0 || (!horiz_blur && !vert_blur)) { + if (radius == 0.0 || sigma == 0.0 || (!horiz_blur && !vert_blur)) { gl_FragColor = texture2D(image, gl_FragCoord.xy/resolution); } else { - float half_kernel = floor(kernel_size*0.5); - float middleWeight = gaussian(0.0, sigma); float sum = middleWeight; if (horiz_blur && vert_blur) { - for (float x=0.0;xinverteffect.frag chromakeyeffect.frag solideffect.frag + boxblureffect.frag diff --git a/olive.pro b/olive.pro index 902d9dcd9..8fd5b6f2d 100644 --- a/olive.pro +++ b/olive.pro @@ -76,7 +76,8 @@ SOURCES += \ effects/video/gaussianblureffect.cpp \ effects/video/cropeffect.cpp \ effects/video/flipeffect.cpp \ - effects/audio/audionoiseeffect.cpp + effects/audio/audionoiseeffect.cpp \ + effects/video/boxblureffect.cpp HEADERS += \ mainwindow.h \ @@ -129,7 +130,8 @@ HEADERS += \ effects/video/gaussianblureffect.h \ effects/video/cropeffect.h \ effects/video/flipeffect.h \ - effects/audio/audionoiseeffect.h + effects/audio/audionoiseeffect.h \ + effects/video/boxblureffect.h FORMS += \ mainwindow.ui \