diff --git a/effects/audio/paneffect.cpp b/effects/audio/paneffect.cpp index c9c012910..a20593e4c 100644 --- a/effects/audio/paneffect.cpp +++ b/effects/audio/paneffect.cpp @@ -20,7 +20,7 @@ PanEffect::PanEffect(Clip* c) : Effect(c, EFFECT_TYPE_AUDIO, AUDIO_PAN_EFFECT) { connect(pan_val, SIGNAL(changed()), this, SLOT(field_changed())); } -void PanEffect::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count) { +void PanEffect::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int) { double interval = (timecode_end - timecode_start)/nb_bytes; for (int i=0;iget_double_value(timecode_start+(interval*i)); diff --git a/effects/effect.cpp b/effects/effect.cpp index 0dbb702c4..9f3d80fd1 100644 --- a/effects/effect.cpp +++ b/effects/effect.cpp @@ -23,6 +23,9 @@ #include "effects/video/solideffect.h" #include "effects/video/texteffect.h" #include "effects/video/chromakeyeffect.h" +#include "effects/video/gaussianblureffect.h" +#include "effects/video/cropeffect.h" +#include "effects/video/flipeffect.h" #include "effects/audio/paneffect.h" #include "effects/audio/volumeeffect.h" @@ -46,6 +49,9 @@ void init_effects() { video_effect_names[VIDEO_SOLID_EFFECT] = "Solid"; video_effect_names[VIDEO_INVERT_EFFECT] = "Invert"; video_effect_names[VIDEO_CHROMAKEY_EFFECT] = "Chroma Key"; + video_effect_names[VIDEO_GAUSSIANBLUR_EFFECT] = "Gaussian Blur"; + video_effect_names[VIDEO_CROP_EFFECT] = "Crop"; + video_effect_names[VIDEO_FLIP_EFFECT] = "Flip"; audio_effect_names[AUDIO_VOLUME_EFFECT] = "Volume"; audio_effect_names[AUDIO_PAN_EFFECT] = "Pan"; @@ -60,6 +66,9 @@ Effect* create_effect(int effect_id, Clip* c) { case VIDEO_SOLID_EFFECT: return new SolidEffect(c); break; case VIDEO_INVERT_EFFECT: return new InvertEffect(c); break; case VIDEO_CHROMAKEY_EFFECT: return new ChromaKeyEffect(c); break; + 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); } } else { switch (effect_id) { diff --git a/effects/effect.h b/effects/effect.h index 6e19f7b6c..243d31dd9 100644 --- a/effects/effect.h +++ b/effects/effect.h @@ -26,6 +26,9 @@ enum VideoEffects { VIDEO_SOLID_EFFECT, VIDEO_INVERT_EFFECT, VIDEO_CHROMAKEY_EFFECT, + VIDEO_GAUSSIANBLUR_EFFECT, + VIDEO_CROP_EFFECT, + VIDEO_FLIP_EFFECT, VIDEO_EFFECT_COUNT }; diff --git a/effects/video/cropeffect.cpp b/effects/video/cropeffect.cpp new file mode 100644 index 000000000..7d35c0a19 --- /dev/null +++ b/effects/video/cropeffect.cpp @@ -0,0 +1,67 @@ +#include "cropeffect.h" + +CropEffect::CropEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_CROP_EFFECT) { + enable_opengl = true; + + left_field = add_row("Left:")->add_field(EFFECT_FIELD_DOUBLE); + top_field = add_row("Top:")->add_field(EFFECT_FIELD_DOUBLE); + right_field = add_row("Right:")->add_field(EFFECT_FIELD_DOUBLE); + bottom_field = add_row("Bottom:")->add_field(EFFECT_FIELD_DOUBLE); + + left_field->set_double_minimum_value(0); + left_field->set_double_maximum_value(100); + top_field->set_double_minimum_value(0); + top_field->set_double_maximum_value(100); + right_field->set_double_minimum_value(0); + right_field->set_double_maximum_value(100); + bottom_field->set_double_minimum_value(0); + bottom_field->set_double_maximum_value(100); + + connect(left_field, SIGNAL(changed()), this, SLOT(field_changed())); + connect(top_field, SIGNAL(changed()), this, SLOT(field_changed())); + connect(right_field, SIGNAL(changed()), this, SLOT(field_changed())); + connect(bottom_field, SIGNAL(changed()), this, SLOT(field_changed())); +} + +void CropEffect::process_gl(double timecode, QOpenGLShaderProgram&, GLTextureCoords &coords) { + // store initial coord data + int left = coords.vertexTopLeftX; + int top = coords.vertexTopLeftY; + int right = coords.vertexBottomRightX; + int bottom = coords.vertexBottomRightY; + int width = right - left; + int height = bottom - top; + + double texLeft = coords.textureTopLeftX; + double texTop = coords.textureTopLeftY; + double texRight = coords.textureBottomRightX; + double texBottom = coords.textureBottomRightY; + double texWidth = texRight - texLeft; + double texHeight = texBottom - texTop; + + // retrieve values + double left_field_value = (left_field->get_double_value(timecode)*0.01); + double right_field_value = 1-(right_field->get_double_value(timecode)*0.01); + double top_field_value = (top_field->get_double_value(timecode)*0.01); + double bottom_field_value = 1-(bottom_field->get_double_value(timecode)*0.01); + + // validate values + if (left_field_value > right_field_value) right_field_value = left_field_value; + if (top_field_value > bottom_field_value) bottom_field_value = top_field_value; + + // left + coords.textureTopLeftX = coords.textureBottomLeftX = texLeft+(left_field_value*texWidth); + coords.vertexTopLeftX = coords.vertexBottomLeftX = left+(width*left_field_value); + + // right + coords.textureTopRightX = coords.textureBottomRightX = texLeft+(right_field_value*texWidth); + coords.vertexTopRightX = coords.vertexBottomRightX = left+(width*right_field_value); + + // top + coords.textureTopLeftY = coords.textureTopRightY = texTop+(top_field_value*texHeight); + coords.vertexTopLeftY = coords.vertexTopRightY = top+(height*top_field_value); + + // bottom + coords.textureBottomLeftY = coords.textureBottomRightY = texTop+(bottom_field_value*texHeight); + coords.vertexBottomLeftY = coords.vertexBottomRightY = top+(height*bottom_field_value); +} diff --git a/effects/video/cropeffect.h b/effects/video/cropeffect.h new file mode 100644 index 000000000..174220b0e --- /dev/null +++ b/effects/video/cropeffect.h @@ -0,0 +1,18 @@ +#ifndef CROPEFFECT_H +#define CROPEFFECT_H + +#include "../effect.h" + +class CropEffect : public Effect +{ +public: + CropEffect(Clip* c); + void process_gl(double timecode, QOpenGLShaderProgram &shaders, GLTextureCoords &coords); +private: + EffectField* left_field; + EffectField* top_field; + EffectField* right_field; + EffectField* bottom_field; +}; + +#endif // CROPEFFECT_H diff --git a/effects/video/flipeffect.cpp b/effects/video/flipeffect.cpp new file mode 100644 index 000000000..049dcceff --- /dev/null +++ b/effects/video/flipeffect.cpp @@ -0,0 +1,36 @@ +#include "flipeffect.h" + +FlipEffect::FlipEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_FLIP_EFFECT) { + enable_opengl = true; + + horizontal_field = add_row("Horizontal:")->add_field(EFFECT_FIELD_BOOL); + vertical_field = add_row("Vertical:")->add_field(EFFECT_FIELD_BOOL); + + connect(horizontal_field, SIGNAL(changed()), this, SLOT(field_changed())); + connect(vertical_field, SIGNAL(changed()), this, SLOT(field_changed())); +} + +void FlipEffect::process_gl(double timecode, QOpenGLShaderProgram &, GLTextureCoords &coords) { + if (horizontal_field->get_bool_value(timecode)) { + double tlX = coords.textureTopLeftX; + double blX = coords.textureBottomLeftX; + double trX = coords.textureTopRightX; + double brX = coords.textureBottomRightX; + coords.textureTopLeftX = trX; + coords.textureTopRightX = tlX; + coords.textureBottomLeftX = brX; + coords.textureBottomRightX = blX; + } + if (vertical_field->get_bool_value(timecode)) { + double tlY = coords.textureTopLeftY; + double blY = coords.textureBottomLeftY; + double trY = coords.textureTopRightY; + double brY = coords.textureBottomRightY; + coords.textureTopLeftY = blY; + coords.textureTopRightY = brY; + coords.textureBottomLeftY = tlY; + coords.textureBottomRightY = trY; + } +} + + diff --git a/effects/video/flipeffect.h b/effects/video/flipeffect.h new file mode 100644 index 000000000..ac192b3d3 --- /dev/null +++ b/effects/video/flipeffect.h @@ -0,0 +1,16 @@ +#ifndef FLIPEFFECT_H +#define FLIPEFFECT_H + +#include "../effect.h" + +class FlipEffect : public Effect +{ +public: + FlipEffect(Clip* c); + void process_gl(double timecode, QOpenGLShaderProgram &shaders, GLTextureCoords &coords); +private: + EffectField* horizontal_field; + EffectField* vertical_field; +}; + +#endif // FLIPEFFECT_H diff --git a/effects/video/gaussianblureffect.cpp b/effects/video/gaussianblureffect.cpp new file mode 100644 index 000000000..98fb579e3 --- /dev/null +++ b/effects/video/gaussianblureffect.cpp @@ -0,0 +1,12 @@ +#include "gaussianblureffect.h" + +GaussianBlurEffect::GaussianBlurEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_GAUSSIANBLUR_EFFECT) { + enable_opengl = true; +} + +void GaussianBlurEffect::process_gl(double timecode, QOpenGLShaderProgram &shaders, GLTextureCoords &coords) { + shaders.addShaderFromSourceCode(QOpenGLShader::Vertex, "attribute vec2 position;\nvoid main() {\ngl_Position = vec4(position, 1, 1);\n}"); + shaders.addShaderFromSourceCode(QOpenGLShader::Fragment, "uniform vec3 iResolution;\nuniform sampler2D iChannel0;\nuniform bool flip;\nuniform vec2 direction;\nvoid main() {\nvec2 uv = vec2(gl_FragCoord.xy / iResolution.xy);\nif (flip) uv.y = 1.0 - uv.y;\nvec4 color = vec4(0.0);\nvec2 off1 = vec2(1.3846153846) * direction;\nvec2 off2 = vec2(3.2307692308) * direction;\ncolor += texture2D(image, uv) * 0.2270270270;\ncolor += texture2D(image, uv + (off1 / resolution)) * 0.3162162162;\ncolor += texture2D(image, uv - (off1 / resolution)) * 0.3162162162;\ncolor += texture2D(image, uv + (off2 / resolution)) * 0.0702702703;\ncolor += texture2D(image, uv - (off2 / resolution)) * 0.0702702703;\ngl_FragColor = color;}"); +} + + diff --git a/effects/video/gaussianblureffect.h b/effects/video/gaussianblureffect.h new file mode 100644 index 000000000..be0f962a5 --- /dev/null +++ b/effects/video/gaussianblureffect.h @@ -0,0 +1,13 @@ +#ifndef GAUSSIANBLUREFFECT_H +#define GAUSSIANBLUREFFECT_H + +#include "../effect.h" + +class GaussianBlurEffect : public Effect +{ +public: + GaussianBlurEffect(Clip* c); + void process_gl(double timecode, QOpenGLShaderProgram &shaders, GLTextureCoords &coords); +}; + +#endif // GAUSSIANBLUREFFECT_H diff --git a/olive.pro b/olive.pro index bdfe25591..d5b5f0185 100644 --- a/olive.pro +++ b/olive.pro @@ -72,7 +72,10 @@ SOURCES += \ effects/video/inverteffect.cpp \ ui/keyframeview.cpp \ ui/texteditex.cpp \ - effects/video/chromakeyeffect.cpp + effects/video/chromakeyeffect.cpp \ + effects/video/gaussianblureffect.cpp \ + effects/video/cropeffect.cpp \ + effects/video/flipeffect.cpp HEADERS += \ mainwindow.h \ @@ -121,7 +124,10 @@ HEADERS += \ effects/audio/paneffect.h \ ui/keyframeview.h \ ui/texteditex.h \ - effects/video/chromakeyeffect.h + effects/video/chromakeyeffect.h \ + effects/video/gaussianblureffect.h \ + effects/video/cropeffect.h \ + effects/video/flipeffect.h FORMS += \ mainwindow.ui \