diff --git a/effects/shaders.qrc b/effects/shaders.qrc
new file mode 100644
index 000000000..3fd215d0a
--- /dev/null
+++ b/effects/shaders.qrc
@@ -0,0 +1 @@
+
diff --git a/effects/video/chromakeyeffect.cpp b/effects/video/chromakeyeffect.cpp
index 1d65a3b2e..bb3c09b1d 100644
--- a/effects/video/chromakeyeffect.cpp
+++ b/effects/video/chromakeyeffect.cpp
@@ -12,8 +12,8 @@ ChromaKeyEffect::ChromaKeyEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_C
tolerance_field->set_double_minimum_value(0);
tolerance_field->set_double_maximum_value(100);
- vert.compileSourceCode("varying vec2 vTexCoord;\nvoid main() {\n\tvTexCoord = gl_MultiTexCoord0.xy;\n\tgl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n}");
- frag.compileSourceCode("uniform vec4 keyColor;\nuniform float threshold;\nuniform sampler2D myTexture;\nvarying vec2 vTexCoord;\nvoid main(void) {\n\tvec4 textureColor = texture2D(myTexture, vTexCoord);\nfloat diff = length(keyColor - textureColor);\nif (diff < threshold) {gl_FragColor = vec4(0, 0, 0, 0);} else {gl_FragColor = textureColor;}\n}");
+ vert.compileSourceFile(":/shaders/common.vert");
+ frag.compileSourceFile(":/shaders/chromakeyeffect.frag");
program.addShader(&vert);
program.addShader(&frag);
program.link();
diff --git a/effects/video/gaussianblureffect.cpp b/effects/video/gaussianblureffect.cpp
index cf7937e8a..9dbf25cec 100644
--- a/effects/video/gaussianblureffect.cpp
+++ b/effects/video/gaussianblureffect.cpp
@@ -8,108 +8,44 @@ GaussianBlurEffect::GaussianBlurEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, V
enable_opengl = true;
enable_image = false;
- amount_val = add_row("Amount:")->add_field(EFFECT_FIELD_DOUBLE);
+ kernelsz_val = add_row("Kernel Size:")->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);
- amount_val->set_double_minimum_value(0);
- amount_val->set_double_default_value(20);
+ kernelsz_val->set_double_minimum_value(0);
+ sigma_val->set_double_minimum_value(0);
+
+ kernelsz_val->set_double_default_value(9);
+ sigma_val->set_double_default_value(5.5);
+
horiz_val->set_bool_value(true);
vert_val->set_bool_value(true);
- vert.compileSourceCode("void main() {\ngl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n}");
-// vert.compileSourceCode("#version 330 core\nin vec2 VertexPosition;\nvoid main(void) {\ngl_Position = vec4(VertexPosition, 0.0, 1.0);\n}");
-// frag.compileSourceCode("#version 330 core\n\nuniform sampler2D image;\n\nout vec4 FragmentColor;\n\nuniform float offset[3] = float[]( 0.0, 1.3846153846, 3.2307692308 );\nuniform float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 );\n\nvoid main(void)\n{\n FragmentColor = texture2D( image, vec2(gl_FragCoord)/vec2(640.0, 360.0) ) * weight[0];\n for (int i=1; i<3; i++) {\n FragmentColor += texture2D( image, ( vec2(gl_FragCoord)+vec2(offset[i], 0.0) )/vec2(640.0, 360.0) ) * weight[i];\n FragmentColor += texture2D( image, ( vec2(gl_FragCoord)-vec2(offset[i], 0.0) )/vec2(640.0, 360.0) ) * weight[i];\n }\n}");
- frag.compileSourceCode("#version 330 core\n\nuniform sampler2D image;\n\nout vec4 FragmentColor;\n\nuniform float offset[3] = float[]( 0.0, 1.3846153846, 3.2307692308 );\nuniform float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 );\nuniform float halfweight[3] = float[]( 0.1135135135, 0.1581081081, 0.03513513515 );\n\nuniform vec2 resolution;\nuniform bool horiz_blur;\nuniform bool vert_blur;\n\nvoid main(void) {\n FragmentColor = texture2D( image, vec2(gl_FragCoord)/resolution ) * weight[0];\n for (int i=1; i<3; i++) {\n float weight = (horiz_blur && vert_blur) ? halfweight[i] : weight[i];\n\n if (horiz_blur) {\n FragmentColor += texture2D( image, ( vec2(gl_FragCoord)+vec2(offset[i], 0.0) )/resolution ) * weight;\n FragmentColor += texture2D( image, ( vec2(gl_FragCoord)-vec2(offset[i], 0.0) )/resolution ) * weight;\n }\n \n if (vert_blur) {\n FragmentColor += texture2D( image, ( vec2(gl_FragCoord)+vec2(0.0, offset[i]) )/resolution ) * weight;\n FragmentColor += texture2D( image, ( vec2(gl_FragCoord)-vec2(0.0, offset[i]) )/resolution ) * weight;\n } \n }\n}");
+ vert.compileSourceFile(":/shaders/common.vert");
+ frag.compileSourceFile(":/shaders/gaussianblureffect.frag");
program.addShader(&vert);
program.addShader(&frag);
- program.link();
+ program.link();
- connect(amount_val, SIGNAL(changed()), this, SLOT(field_changed()));
+ connect(kernelsz_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();
}
-void GaussianBlurEffect::process_image(double timecode, uint8_t *data, int width, int height) {
- QImage result(data, width, height, QImage::Format_RGBA8888); // create QImage wrapper
- int radius = 5;
-
- int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
- int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
-
- int r1 = result.rect().top();
- int r2 = result.rect().bottom();
- int c1 = result.rect().left();
- int c2 = result.rect().right();
-
- int bpl = result.bytesPerLine();
- int rgba[4];
- unsigned char* p;
-
- int i1 = 0;
- int i2 = 3;
-
- for (int col = c1; col <= c2; col++) {
- p = result.scanLine(r1) + col * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
-
- p += bpl;
- for (int j = r1; j < r2; j++, p += bpl)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
- }
-
- for (int row = r1; row <= r2; row++) {
- p = result.scanLine(row) + c1 * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
-
- p += 4;
- for (int j = c1; j < c2; j++, p += 4)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
- }
-
- for (int col = c1; col <= c2; col++) {
- p = result.scanLine(r2) + col * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
-
- p -= bpl;
- for (int j = r1; j < r2; j++, p -= bpl)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
- }
-
- for (int row = r1; row <= r2; row++) {
- p = result.scanLine(row) + c2 * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
-
- p -= 4;
- for (int j = c1; j < c2; j++, p -= 4)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
- }
-}
-
void GaussianBlurEffect::process_gl(double timecode, GLTextureCoords &coords) {
- bound = false;
- bool horiz = horiz_val->get_bool_value(timecode);
- bool vert = vert_val->get_bool_value(timecode);
- int iterationCount = amount_val->get_double_value(timecode);
- if (iterationCount > 0 && (horiz || vert)) {
- bound = program.bind();
- setIterations(iterationCount);
- program.setUniformValue("resolution", parent_clip->getWidth(), parent_clip->getHeight());
- program.setUniformValue("horiz_blur", horiz);
- program.setUniformValue("vert_blur", vert);
- }
+ program.bind();
+
+ program.setUniformValue("resolution", parent_clip->getWidth(), parent_clip->getHeight());
+ program.setUniformValue("kernel_size", (GLfloat) kernelsz_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));
}
-void GaussianBlurEffect::clean_gl() {
- if (bound) program.release();
+void GaussianBlurEffect::clean_gl() {
+ program.release();
}
diff --git a/effects/video/gaussianblureffect.h b/effects/video/gaussianblureffect.h
index 7212d8876..bdcbb75b1 100644
--- a/effects/video/gaussianblureffect.h
+++ b/effects/video/gaussianblureffect.h
@@ -6,8 +6,7 @@
class GaussianBlurEffect : public Effect
{
public:
- GaussianBlurEffect(Clip* c);
- void process_image(double timecode, uint8_t *data, int width, int height);
+ GaussianBlurEffect(Clip* c);
void process_gl(double timecode, GLTextureCoords &coords);
void clean_gl();
private:
@@ -15,7 +14,8 @@ private:
QOpenGLShader vert;
QOpenGLShader frag;
- EffectField* amount_val;
+ EffectField* kernelsz_val;
+ EffectField* sigma_val;
EffectField* horiz_val;
EffectField* vert_val;
diff --git a/effects/video/glsl/chromakeyeffect.frag b/effects/video/glsl/chromakeyeffect.frag
new file mode 100644
index 000000000..7c44e43f4
--- /dev/null
+++ b/effects/video/glsl/chromakeyeffect.frag
@@ -0,0 +1,16 @@
+#version 110
+
+uniform vec4 keyColor;
+uniform float threshold;
+uniform sampler2D myTexture;
+varying vec2 vTexCoord;
+
+void main(void) {
+ vec4 textureColor = texture2D(myTexture, vTexCoord);
+ float diff = length(keyColor - textureColor);
+ if (diff < threshold) {
+ gl_FragColor = vec4(0, 0, 0, 0);
+ } else {
+ gl_FragColor = textureColor;
+ }
+}
\ No newline at end of file
diff --git a/effects/video/glsl/common.vert b/effects/video/glsl/common.vert
new file mode 100644
index 000000000..2d088fa2f
--- /dev/null
+++ b/effects/video/glsl/common.vert
@@ -0,0 +1,8 @@
+#version 110
+
+varying vec2 vTexCoord;
+
+void main() {
+ vTexCoord = gl_MultiTexCoord0.xy;
+ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+}
\ No newline at end of file
diff --git a/effects/video/glsl/gaussianblureffect.frag b/effects/video/glsl/gaussianblureffect.frag
new file mode 100644
index 000000000..4a1cbddb7
--- /dev/null
+++ b/effects/video/glsl/gaussianblureffect.frag
@@ -0,0 +1,67 @@
+#version 110
+
+#define M_PI 3.1415926535897932384626433832795
+
+uniform sampler2D image;
+
+uniform float kernel_size;
+uniform float sigma;
+uniform vec2 resolution;
+uniform bool horiz_blur;
+uniform bool vert_blur;
+
+float gaussian(float x, float sigma) {
+ return (1.0/(sigma*sqrt(2.0*M_PI)))*exp(-0.5*pow(x/sigma, 2.0));
+}
+
+float gaussian2(float x, float y, float sigma) {
+ return (1.0/(pow(sigma, 2.0)*2.0*M_PI))*exp(-0.5*((pow(x, 2.0) + pow(y, 2.0))/pow(sigma, 2.0)));
+}
+
+void main(void) {
+ if (kernel_size == 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;x
+
+ gaussianblureffect.frag
+ common.vert
+ inverteffect.frag
+ chromakeyeffect.frag
+ solideffect.frag
+
+
diff --git a/effects/video/glsl/solideffect.frag b/effects/video/glsl/solideffect.frag
new file mode 100644
index 000000000..cda8aafe0
--- /dev/null
+++ b/effects/video/glsl/solideffect.frag
@@ -0,0 +1,16 @@
+#version 110
+
+uniform vec4 solidColor;
+uniform float amount_val;
+uniform sampler2D myTexture;
+varying vec2 vTexCoord;
+
+void main(void) {
+ vec4 textureColor = texture2D(myTexture, vTexCoord);
+ gl_FragColor = vec4(
+ textureColor.r+((solidColor.r-textureColor.r)*amount_val),
+ textureColor.g+((solidColor.g-textureColor.g)*amount_val),
+ textureColor.b+((solidColor.b-textureColor.b)*amount_val),
+ textureColor.a
+ );
+}
\ No newline at end of file
diff --git a/effects/video/inverteffect.cpp b/effects/video/inverteffect.cpp
index 8d596f224..1d682fe72 100644
--- a/effects/video/inverteffect.cpp
+++ b/effects/video/inverteffect.cpp
@@ -22,8 +22,8 @@ InvertEffect::InvertEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_INVERT_
connect(amount_val, SIGNAL(changed()), this, SLOT(field_changed()));
- vert.compileSourceCode("varying vec2 vTexCoord;\nvoid main() {\n\tvTexCoord = gl_MultiTexCoord0.xy;\n\tgl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n}");
- frag.compileSourceCode("uniform mediump float amount_val;\nuniform sampler2D myTexture;\nvarying vec2 vTexCoord;\nvoid main(void) {\n\tvec4 textureColor = texture2D(myTexture, vTexCoord);\n\tgl_FragColor = vec4(textureColor.r+((1.0-textureColor.r-textureColor.r)*amount_val), textureColor.g+((1.0-textureColor.g-textureColor.g)*amount_val), textureColor.b+((1.0-textureColor.b-textureColor.b)*amount_val), textureColor.a);\n}");
+ vert.compileSourceFile(":/shaders/common.vert");
+ frag.compileSourceFile(":/shaders/inverteffect.frag");
program.addShader(&vert);
program.addShader(&frag);
program.link();
diff --git a/effects/video/inverteffect.h b/effects/video/inverteffect.h
index 82e9811ae..47743810a 100644
--- a/effects/video/inverteffect.h
+++ b/effects/video/inverteffect.h
@@ -3,8 +3,6 @@
#include "../effect.h"
-//#include
-
class InvertEffect : public Effect {
Q_OBJECT
public:
diff --git a/effects/video/solideffect.cpp b/effects/video/solideffect.cpp
index c0bc14814..d83f041f3 100644
--- a/effects/video/solideffect.cpp
+++ b/effects/video/solideffect.cpp
@@ -34,8 +34,8 @@ SolidEffect::SolidEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_SOLID_EFF
connect(solid_color_field, SIGNAL(changed()), this, SLOT(field_changed()));
connect(opacity_field, SIGNAL(changed()), this, SLOT(field_changed()));
- vert.compileSourceCode("varying vec2 vTexCoord;\nvoid main() {\n\tvTexCoord = gl_MultiTexCoord0.xy;\n\tgl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n}");
- frag.compileSourceCode("uniform vec4 solidColor;\nuniform float amount_val;\nuniform sampler2D myTexture;\nvarying vec2 vTexCoord;\nvoid main(void) {\n\tvec4 textureColor = texture2D(myTexture, vTexCoord);\n\tgl_FragColor = vec4(textureColor.r+((solidColor.r-textureColor.r)*amount_val), textureColor.g+((solidColor.g-textureColor.g)*amount_val), textureColor.b+((solidColor.b-textureColor.b)*amount_val), textureColor.a);\n}");
+ vert.compileSourceFile(":/shaders/common.vert");
+ frag.compileSourceFile(":/shaders/solideffect.frag");
program.addShader(&vert);
program.addShader(&frag);
}
diff --git a/olive.pro b/olive.pro
index 264a011ad..902d9dcd9 100644
--- a/olive.pro
+++ b/olive.pro
@@ -159,4 +159,5 @@ linux {
}
RESOURCES += \
- icons/icons.qrc
+ icons/icons.qrc \
+ effects/video/glsl/shaders.qrc
diff --git a/project/clip.cpp b/project/clip.cpp
index 53a69241f..0813909da 100644
--- a/project/clip.cpp
+++ b/project/clip.cpp
@@ -192,6 +192,7 @@ int Clip::getWidth() {
{
MediaStream* ms = static_cast(media)->get_stream_from_file_index(track < 0, media_stream);
if (ms != NULL) return ms->video_width;
+ if (sequence != NULL) return sequence->width;
}
case MEDIA_TYPE_SEQUENCE:
{
@@ -209,6 +210,7 @@ int Clip::getHeight() {
{
MediaStream* ms = static_cast(media)->get_stream_from_file_index(track < 0, media_stream);
if (ms != NULL) return ms->video_height;
+ if (sequence != NULL) return sequence->height;
}
case MEDIA_TYPE_SEQUENCE:
{