From 6495c5768d0491070bafef503f2b45b35fef0d29 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 13 Nov 2018 02:39:15 +1100 Subject: [PATCH] added perspective option to corner pin --- effects/{effects => }/README | 0 effects/{effects => }/boxblur.frag | 0 effects/{effects => }/boxblur.xml | 0 effects/{effects => }/bulge.frag | 0 effects/{effects => }/bulge.xml | 0 effects/{effects => }/colorcorrection.frag | 0 effects/{effects => }/colorcorrection.xml | 0 effects/common.frag | 9 ++ effects/{effects => }/common.vert | 0 effects/cornerpin.frag | 46 +++++++ effects/cornerpin.vert | 60 +++++++++ effects/{effects => }/crop.frag | 0 effects/{effects => }/crop.xml | 0 effects/effects/common.frag | 14 --- effects/effects/invert.frag | 16 --- effects/findedges.frag | 121 +++++++++++++++++++ effects/findedges.xml | 7 ++ effects/{effects => }/flip.frag | 0 effects/{effects => }/flip.xml | 0 effects/{effects => }/gaussianblur.frag | 0 effects/{effects => }/gaussianblur.xml | 0 effects/{effects => }/huesatbri.frag | 0 effects/{effects => }/huesatbri.xml | 0 effects/internal/audionoiseeffect.h | 2 +- effects/internal/cornerpineffect.cpp | 22 +++- effects/internal/cornerpineffect.h | 6 +- effects/internal/crossdissolvetransition.h | 2 +- effects/internal/exponentialfadetransition.h | 2 +- effects/internal/linearfadetransition.h | 2 +- effects/internal/logarithmicfadetransition.h | 2 +- effects/internal/paneffect.h | 2 +- effects/internal/shakeeffect.h | 2 +- effects/internal/solideffect.h | 2 +- effects/internal/texteffect.h | 2 +- effects/internal/toneeffect.h | 2 +- effects/internal/transformeffect.h | 2 +- effects/internal/volumeeffect.h | 2 +- effects/invert.frag | 13 ++ effects/{effects => }/invert.xml | 0 effects/noise.frag | 47 +++++++ effects/noise.xml | 13 ++ effects/shaders.qrc | 1 - effects/{effects => }/swirl.frag | 4 +- effects/{effects => }/swirl.xml | 2 +- effects/{effects => }/wave.frag | 2 - effects/{effects => }/wave.xml | 0 io/previewgenerator.cpp | 2 +- {effects => io}/qpainterwrapper.cpp | 0 {effects => io}/qpainterwrapper.h | 0 olive.pro | 12 +- panels/timeline.cpp | 3 +- playback/audio.cpp | 1 - {effects => project}/effect.cpp | 3 +- {effects => project}/effect.h | 2 +- ui/timelinewidget.cpp | 2 +- ui/viewerwidget.cpp | 62 +++++++--- ui/viewerwidget.h | 2 + 57 files changed, 416 insertions(+), 80 deletions(-) rename effects/{effects => }/README (100%) rename effects/{effects => }/boxblur.frag (100%) rename effects/{effects => }/boxblur.xml (100%) rename effects/{effects => }/bulge.frag (100%) rename effects/{effects => }/bulge.xml (100%) rename effects/{effects => }/colorcorrection.frag (100%) rename effects/{effects => }/colorcorrection.xml (100%) create mode 100644 effects/common.frag rename effects/{effects => }/common.vert (100%) create mode 100644 effects/cornerpin.frag create mode 100644 effects/cornerpin.vert rename effects/{effects => }/crop.frag (100%) rename effects/{effects => }/crop.xml (100%) delete mode 100644 effects/effects/common.frag delete mode 100644 effects/effects/invert.frag create mode 100644 effects/findedges.frag create mode 100644 effects/findedges.xml rename effects/{effects => }/flip.frag (100%) rename effects/{effects => }/flip.xml (100%) rename effects/{effects => }/gaussianblur.frag (100%) rename effects/{effects => }/gaussianblur.xml (100%) rename effects/{effects => }/huesatbri.frag (100%) rename effects/{effects => }/huesatbri.xml (100%) create mode 100644 effects/invert.frag rename effects/{effects => }/invert.xml (100%) create mode 100644 effects/noise.frag create mode 100644 effects/noise.xml delete mode 100644 effects/shaders.qrc rename effects/{effects => }/swirl.frag (85%) rename effects/{effects => }/swirl.xml (83%) rename effects/{effects => }/wave.frag (87%) rename effects/{effects => }/wave.xml (100%) rename {effects => io}/qpainterwrapper.cpp (100%) rename {effects => io}/qpainterwrapper.h (100%) rename {effects => project}/effect.cpp (96%) rename {effects => project}/effect.h (95%) diff --git a/effects/effects/README b/effects/README similarity index 100% rename from effects/effects/README rename to effects/README diff --git a/effects/effects/boxblur.frag b/effects/boxblur.frag similarity index 100% rename from effects/effects/boxblur.frag rename to effects/boxblur.frag diff --git a/effects/effects/boxblur.xml b/effects/boxblur.xml similarity index 100% rename from effects/effects/boxblur.xml rename to effects/boxblur.xml diff --git a/effects/effects/bulge.frag b/effects/bulge.frag similarity index 100% rename from effects/effects/bulge.frag rename to effects/bulge.frag diff --git a/effects/effects/bulge.xml b/effects/bulge.xml similarity index 100% rename from effects/effects/bulge.xml rename to effects/bulge.xml diff --git a/effects/effects/colorcorrection.frag b/effects/colorcorrection.frag similarity index 100% rename from effects/effects/colorcorrection.frag rename to effects/colorcorrection.frag diff --git a/effects/effects/colorcorrection.xml b/effects/colorcorrection.xml similarity index 100% rename from effects/effects/colorcorrection.xml rename to effects/colorcorrection.xml diff --git a/effects/common.frag b/effects/common.frag new file mode 100644 index 000000000..f0a667b18 --- /dev/null +++ b/effects/common.frag @@ -0,0 +1,9 @@ +#version 110 + +uniform sampler2D tex; +varying vec2 vTexCoord; + +void main(void) { + vec4 textureColor = texture2D(tex, vec2(vTexCoord.x, vTexCoord.y)); + gl_FragColor = textureColor; +} \ No newline at end of file diff --git a/effects/effects/common.vert b/effects/common.vert similarity index 100% rename from effects/effects/common.vert rename to effects/common.vert diff --git a/effects/cornerpin.frag b/effects/cornerpin.frag new file mode 100644 index 000000000..c75f18671 --- /dev/null +++ b/effects/cornerpin.frag @@ -0,0 +1,46 @@ +#version 110 + +uniform sampler2D tex; +uniform bool perspective; + +varying vec2 q; +varying vec2 b1; +varying vec2 b2; +varying vec2 b3; +varying vec2 vTexCoord; + +float Wedge2D(vec2 v, vec2 w) { + return (v.x*w.y) - (v.y*w.x); +} + +void main(void) { + if (perspective) { + gl_FragColor = texture2D(tex, vTexCoord); + } else { + float A = Wedge2D(b2, b3); + float B = Wedge2D(b3, q) - Wedge2D(b1, b2); + float C = Wedge2D(b1, q); + + vec2 uv; + + // solve for v + if (abs(A) < 0.001) { + uv.y = -C/B; + } else { + float discrim = B*B - 4.0*A*C; + uv.y = 0.5 * (-B + sqrt(discrim)) / A; + } + + // solve for u + vec2 denom = b1 + uv.y * b3; + if (abs(denom.x) > abs(denom.y)) { + uv.x = (q.x - b2.x * uv.y) / denom.x; + } else { + uv.x = (q.y - b2.y * uv.y) / denom.y; + } + + uv.y = 1.0 - uv.y; + + gl_FragColor = texture2D(tex, uv); + } +} \ No newline at end of file diff --git a/effects/cornerpin.vert b/effects/cornerpin.vert new file mode 100644 index 000000000..ed1ef5f5b --- /dev/null +++ b/effects/cornerpin.vert @@ -0,0 +1,60 @@ +#version 110 +#extension GL_EXT_gpu_shader4 : enable + +uniform bool perspective; +uniform vec2 p0; +uniform vec2 p1; +uniform vec2 p2; +uniform vec2 p3; + +varying vec2 q; +varying vec2 b1; +varying vec2 b2; +varying vec2 b3; +varying vec2 vTexCoord; + +void main() { + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + + if (perspective) { + float m1 = (p3.y - p0.y)/(p3.x - p0.x); + float c1 = p0.y - m1 * p0.x; + float m2 = (p1.y - p2.y)/(p1.x - p2.x); + float c2 = p2.y - m2 * p2.x; + float mid_x = (c2 - c1) / (m1 - m2); + float mid_y = m1 * mid_x + c1; + + float d0 = sqrt(pow(mid_x - p0.x, 2.0) + pow(mid_y - p0.y, 2.0)); + float d1 = sqrt(pow(p1.x - mid_x, 2.0) + pow(mid_y - p1.y, 2.0)); + float d2 = sqrt(pow(p3.x - mid_x, 2.0) + pow(p3.y - mid_y, 2.0)); + float d3 = sqrt(pow(mid_x - p2.x, 2.0) + pow(p2.y - mid_y, 2.0)); + + float q; + + switch (gl_VertexID) { + case 0: q = (d1+d3)/d3; break; + case 1: q = (d0+d2)/d2; break; + case 2: q = (d3+d1)/d1; break; + case 3: q = (d2+d0)/d0; break; + } + + gl_Position[0] *= q; + gl_Position[1] *= q; + gl_Position[3] = q; + + vTexCoord = gl_MultiTexCoord0.xy; + } else { + vec2 pos; + switch (gl_VertexID) { + case 0: pos = p2; break; // top left + case 1: pos = p3; break; // top right + case 2: pos = p1; break; // bottom right + case 3: pos = p0; break; // bottom left + } + + q = pos - p0; + b1 = p1 - p0; + b2 = p2 - p0; + b3 = p0 - p1 - p2 + p3; + } +} \ No newline at end of file diff --git a/effects/effects/crop.frag b/effects/crop.frag similarity index 100% rename from effects/effects/crop.frag rename to effects/crop.frag diff --git a/effects/effects/crop.xml b/effects/crop.xml similarity index 100% rename from effects/effects/crop.xml rename to effects/crop.xml diff --git a/effects/effects/common.frag b/effects/effects/common.frag deleted file mode 100644 index ec9d3f905..000000000 --- a/effects/effects/common.frag +++ /dev/null @@ -1,14 +0,0 @@ -#version 110 - -uniform sampler2D myTexture; -varying vec2 vTexCoord; - -void main(void) { - vec4 textureColor = texture2D(myTexture, vec2(vTexCoord.x, vTexCoord.y)); - gl_FragColor = vec4( - textureColor.r, - textureColor.g, - textureColor.b, - textureColor.a - ); -} \ No newline at end of file diff --git a/effects/effects/invert.frag b/effects/effects/invert.frag deleted file mode 100644 index 4859995f1..000000000 --- a/effects/effects/invert.frag +++ /dev/null @@ -1,16 +0,0 @@ -#version 110 - -uniform mediump float amount; -uniform sampler2D myTexture; -varying vec2 vTexCoord; - -void main(void) { - vec4 textureColor = texture2D(myTexture, vTexCoord); - float amount_val = amount * 0.01; - gl_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 - ); -} \ No newline at end of file diff --git a/effects/findedges.frag b/effects/findedges.frag new file mode 100644 index 000000000..9641cf398 --- /dev/null +++ b/effects/findedges.frag @@ -0,0 +1,121 @@ +#version 110 + +uniform vec2 resolution; + +vec3 mod289(vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 mod289(vec4 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 permute(vec4 x) { + return mod289(((x * 34.0) + 1.0) * x); +} + +vec4 taylorInvSqrt(vec4 r) { + return 1.79284291400159 - 0.85373472095314 * r; +} + +vec3 fade(vec3 t) { + return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); +} + +float noise(vec3 P) { + vec3 Pi0 = floor(P), + Pi1 = Pi0 + vec3(1.0); + + Pi0 = mod289(Pi0); + Pi1 = mod289(Pi1); + + vec3 Pf0 = fract(P), + Pf1 = Pf0 - vec3(1.0); + + vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x), + iy = vec4(Pi0.yy, Pi1.yy), + iz0 = Pi0.zzzz, + iz1 = Pi1.zzzz, + ixy = permute(permute(ix) + iy), + ixy0 = permute(ixy + iz0), + ixy1 = permute(ixy + iz1), + gx0 = ixy0 * (1.0 / 7.0), + gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5; + + gx0 = fract(gx0); + + vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0), + sz0 = step(gz0, vec4(0.0)); + + gx0 -= sz0 * (step(0.0, gx0) - 0.5); + gy0 -= sz0 * (step(0.0, gy0) - 0.5); + + vec4 gx1 = ixy1 * (1.0 / 7.0), + gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5; + + gx1 = fract(gx1); + + vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1), + sz1 = step(gz1, vec4(0.0)); + + gx1 -= sz1 * (step(0.0, gx1) - 0.5); + gy1 -= sz1 * (step(0.0, gy1) - 0.5); + + vec3 g000 = vec3(gx0.x, gy0.x, gz0.x), + g100 = vec3(gx0.y, gy0.y, gz0.y), + g010 = vec3(gx0.z, gy0.z, gz0.z), + g110 = vec3(gx0.w, gy0.w, gz0.w), + g001 = vec3(gx1.x, gy1.x, gz1.x), + g101 = vec3(gx1.y, gy1.y, gz1.y), + g011 = vec3(gx1.z, gy1.z, gz1.z), + g111 = vec3(gx1.w, gy1.w, gz1.w); + + vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + + vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + float n000 = dot(g000, Pf0), + n100 = dot(g100, vec3(Pf1.x, Pf0.yz)), + n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)), + n110 = dot(g110, vec3(Pf1.xy, Pf0.z)), + n001 = dot(g001, vec3(Pf0.xy, Pf1.z)), + n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)), + n011 = dot(g011, vec3(Pf0.x, Pf1.yz)), + n111 = dot(g111, Pf1); + + vec3 fade_xyz = fade(Pf0); + vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); + vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); + + return mix(n_yz.x, n_yz.y, fade_xyz.x); +} + +void main( void ) { + float time = 2.0; + vec2 noiseFactor = vec2(2.0, 2.0); + float noiseFactorTime = 2.0; + + vec2 p = gl_FragCoord.xy / resolution.y; + //p *= vec2(800, 600); + //p += mouse * 1.0; + //float z = 1.0; + //float speed = 1.0; + + //p.y += time * 0.1; + + vec2 nx = vec2(p.x * noiseFactor.x, p.y * noiseFactor.y); + + float v = noise(vec3(nx, time * noiseFactorTime) * 3.0) * 6.28318531; + v = v * 0.15 + 0.5; + + gl_FragColor = vec4(vec3(v), 1.0); + +} \ No newline at end of file diff --git a/effects/findedges.xml b/effects/findedges.xml new file mode 100644 index 000000000..0ea0f822c --- /dev/null +++ b/effects/findedges.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/effects/effects/flip.frag b/effects/flip.frag similarity index 100% rename from effects/effects/flip.frag rename to effects/flip.frag diff --git a/effects/effects/flip.xml b/effects/flip.xml similarity index 100% rename from effects/effects/flip.xml rename to effects/flip.xml diff --git a/effects/effects/gaussianblur.frag b/effects/gaussianblur.frag similarity index 100% rename from effects/effects/gaussianblur.frag rename to effects/gaussianblur.frag diff --git a/effects/effects/gaussianblur.xml b/effects/gaussianblur.xml similarity index 100% rename from effects/effects/gaussianblur.xml rename to effects/gaussianblur.xml diff --git a/effects/effects/huesatbri.frag b/effects/huesatbri.frag similarity index 100% rename from effects/effects/huesatbri.frag rename to effects/huesatbri.frag diff --git a/effects/effects/huesatbri.xml b/effects/huesatbri.xml similarity index 100% rename from effects/effects/huesatbri.xml rename to effects/huesatbri.xml diff --git a/effects/internal/audionoiseeffect.h b/effects/internal/audionoiseeffect.h index 23bd65425..fa1643290 100644 --- a/effects/internal/audionoiseeffect.h +++ b/effects/internal/audionoiseeffect.h @@ -1,7 +1,7 @@ #ifndef AUDIONOISEEFFECT_H #define AUDIONOISEEFFECT_H -#include "../effect.h" +#include "project/effect.h" class AudioNoiseEffect : public Effect { public: diff --git a/effects/internal/cornerpineffect.cpp b/effects/internal/cornerpineffect.cpp index adc43645a..0e4d38870 100644 --- a/effects/internal/cornerpineffect.cpp +++ b/effects/internal/cornerpineffect.cpp @@ -1,7 +1,12 @@ #include "cornerpineffect.h" +#include "io/path.h" +#include "project/clip.h" +#include "debug.h" + CornerPinEffect::CornerPinEffect(Clip *c, const EffectMeta *em) : Effect(c, em) { enable_coords = true; + enable_shader = true; EffectRow* top_left = add_row("Top Left:"); top_left_x = top_left->add_field(EFFECT_FIELD_DOUBLE); @@ -27,6 +32,9 @@ CornerPinEffect::CornerPinEffect(Clip *c, const EffectMeta *em) : Effect(c, em) bottom_right_y = bottom_right->add_field(EFFECT_FIELD_DOUBLE); bottom_right_y->id = "bottomrighty"; + perspective = add_row("Perspective:")->add_field(EFFECT_FIELD_BOOL); + perspective->set_bool_value(false); + connect(top_left_x, SIGNAL(changed()), this, SLOT(field_changed())); connect(top_left_y, SIGNAL(changed()), this, SLOT(field_changed())); connect(top_right_x, SIGNAL(changed()), this, SLOT(field_changed())); @@ -35,6 +43,10 @@ CornerPinEffect::CornerPinEffect(Clip *c, const EffectMeta *em) : Effect(c, em) connect(bottom_left_y, SIGNAL(changed()), this, SLOT(field_changed())); connect(bottom_right_x, SIGNAL(changed()), this, SLOT(field_changed())); connect(bottom_right_y, SIGNAL(changed()), this, SLOT(field_changed())); + connect(perspective, SIGNAL(changed()), this, SLOT(field_changed())); + + vertPath = "cornerpin.vert"; + fragPath = "cornerpin.frag"; } void CornerPinEffect::process_coords(double timecode, GLTextureCoords &coords) { @@ -48,5 +60,13 @@ void CornerPinEffect::process_coords(double timecode, GLTextureCoords &coords) { coords.vertexBottomLeftY += bottom_left_y->get_double_value(timecode); coords.vertexBottomRightX += bottom_right_x->get_double_value(timecode); - coords.vertexBottomRightY += bottom_right_y->get_double_value(timecode); + coords.vertexBottomRightY += bottom_right_y->get_double_value(timecode); +} + +void CornerPinEffect::process_shader(double timecode, GLTextureCoords &coords) { + glslProgram->setUniformValue("p0", (GLfloat) coords.vertexBottomLeftX, (GLfloat) coords.vertexBottomLeftY); + glslProgram->setUniformValue("p1", (GLfloat) coords.vertexBottomRightX, (GLfloat) coords.vertexBottomRightY); + glslProgram->setUniformValue("p2", (GLfloat) coords.vertexTopLeftX, (GLfloat) coords.vertexTopLeftY); + glslProgram->setUniformValue("p3", (GLfloat) coords.vertexTopRightX, (GLfloat) coords.vertexTopRightY); + glslProgram->setUniformValue("perspective", perspective->get_bool_value(timecode)); } diff --git a/effects/internal/cornerpineffect.h b/effects/internal/cornerpineffect.h index 3e1bb0401..0c28f8810 100644 --- a/effects/internal/cornerpineffect.h +++ b/effects/internal/cornerpineffect.h @@ -1,13 +1,14 @@ #ifndef CORNERPINEFFECT_H #define CORNERPINEFFECT_H -#include "../effect.h" +#include "project/effect.h" class CornerPinEffect : public Effect { Q_OBJECT public: CornerPinEffect(Clip* c, const EffectMeta* em); - void process_coords(double timecode, GLTextureCoords& coords); + void process_coords(double timecode, GLTextureCoords& coords); + void process_shader(double timecode, GLTextureCoords& coords); private: EffectField* top_left_x; EffectField* top_left_y; @@ -17,6 +18,7 @@ private: EffectField* bottom_left_y; EffectField* bottom_right_x; EffectField* bottom_right_y; + EffectField* perspective; }; #endif // CORNERPINEFFECT_H diff --git a/effects/internal/crossdissolvetransition.h b/effects/internal/crossdissolvetransition.h index 7792e9199..d51766567 100644 --- a/effects/internal/crossdissolvetransition.h +++ b/effects/internal/crossdissolvetransition.h @@ -1,7 +1,7 @@ #ifndef CROSSDISSOLVETRANSITION_H #define CROSSDISSOLVETRANSITION_H -#include "../effect.h" +#include "project/effect.h" class CrossDissolveTransition : public Effect { public: diff --git a/effects/internal/exponentialfadetransition.h b/effects/internal/exponentialfadetransition.h index a040ceb48..7a44f01cc 100644 --- a/effects/internal/exponentialfadetransition.h +++ b/effects/internal/exponentialfadetransition.h @@ -1,7 +1,7 @@ #ifndef EXPONENTIALFADETRANSITION_H #define EXPONENTIALFADETRANSITION_H -#include "../effect.h" +#include "project/effect.h" class ExponentialFadeTransition : public Effect { public: diff --git a/effects/internal/linearfadetransition.h b/effects/internal/linearfadetransition.h index 92ec16fc8..51b5001be 100644 --- a/effects/internal/linearfadetransition.h +++ b/effects/internal/linearfadetransition.h @@ -1,7 +1,7 @@ #ifndef LINEARFADETRANSITION_H #define LINEARFADETRANSITION_H -#include "../effect.h" +#include "project/effect.h" class LinearFadeTransition : public Effect { public: diff --git a/effects/internal/logarithmicfadetransition.h b/effects/internal/logarithmicfadetransition.h index b758ce1c6..e5a4a260a 100644 --- a/effects/internal/logarithmicfadetransition.h +++ b/effects/internal/logarithmicfadetransition.h @@ -1,7 +1,7 @@ #ifndef LOGARITHMICFADETRANSITION_H #define LOGARITHMICFADETRANSITION_H -#include "../effect.h" +#include "project/effect.h" class LogarithmicFadeTransition : public Effect { public: diff --git a/effects/internal/paneffect.h b/effects/internal/paneffect.h index 60465a63c..b4f7e8b9c 100644 --- a/effects/internal/paneffect.h +++ b/effects/internal/paneffect.h @@ -1,7 +1,7 @@ #ifndef PANEFFECT_H #define PANEFFECT_H -#include "../effect.h" +#include "project/effect.h" class PanEffect : public Effect { public: diff --git a/effects/internal/shakeeffect.h b/effects/internal/shakeeffect.h index f70b22fd9..216e2d53b 100644 --- a/effects/internal/shakeeffect.h +++ b/effects/internal/shakeeffect.h @@ -1,7 +1,7 @@ #ifndef SHAKEEFFECT_H #define SHAKEEFFECT_H -#include "../effect.h" +#include "project/effect.h" #define RANDOM_VAL_SIZE 30 diff --git a/effects/internal/solideffect.h b/effects/internal/solideffect.h index c14056470..7d2d85f1b 100644 --- a/effects/internal/solideffect.h +++ b/effects/internal/solideffect.h @@ -1,7 +1,7 @@ #ifndef SOLIDEFFECT_H #define SOLIDEFFECT_H -#include "../effect.h" +#include "project/effect.h" class QOpenGLTexture; #include diff --git a/effects/internal/texteffect.h b/effects/internal/texteffect.h index d18d26ec8..644d18fff 100644 --- a/effects/internal/texteffect.h +++ b/effects/internal/texteffect.h @@ -1,7 +1,7 @@ #ifndef TEXTEFFECT_H #define TEXTEFFECT_H -#include "../effect.h" +#include "project/effect.h" #include #include diff --git a/effects/internal/toneeffect.h b/effects/internal/toneeffect.h index a08155a29..4ad7492f4 100644 --- a/effects/internal/toneeffect.h +++ b/effects/internal/toneeffect.h @@ -1,7 +1,7 @@ #ifndef TONEEFFECT_H #define TONEEFFECT_H -#include "../effect.h" +#include "project/effect.h" class ToneEffect : public Effect { public: diff --git a/effects/internal/transformeffect.h b/effects/internal/transformeffect.h index 7111f3612..93a67a006 100644 --- a/effects/internal/transformeffect.h +++ b/effects/internal/transformeffect.h @@ -1,7 +1,7 @@ #ifndef TRANSFORMEFFECT_H #define TRANSFORMEFFECT_H -#include "../effect.h" +#include "project/effect.h" class TransformEffect : public Effect { Q_OBJECT diff --git a/effects/internal/volumeeffect.h b/effects/internal/volumeeffect.h index 40b4ad4a7..870f008a9 100644 --- a/effects/internal/volumeeffect.h +++ b/effects/internal/volumeeffect.h @@ -1,7 +1,7 @@ #ifndef VOLUMEEFFECT_H #define VOLUMEEFFECT_H -#include "../effect.h" +#include "project/effect.h" class VolumeEffect : public Effect { public: diff --git a/effects/invert.frag b/effects/invert.frag new file mode 100644 index 000000000..7ad7178a7 --- /dev/null +++ b/effects/invert.frag @@ -0,0 +1,13 @@ +#version 110 + +uniform float amount; + +uniform sampler2D myTexture; +varying vec2 vTexCoord; + +void main(void) { + vec4 textureColor = texture2D(myTexture, vTexCoord); + float amount_val = amount * 0.01; + vec3 col = textureColor.rgb+((vec3(1.0)-textureColor.rgb-textureColor.rgb)*vec3(amount_val)); + gl_FragColor = vec4(col, textureColor.a); +} \ No newline at end of file diff --git a/effects/effects/invert.xml b/effects/invert.xml similarity index 100% rename from effects/effects/invert.xml rename to effects/invert.xml diff --git a/effects/noise.frag b/effects/noise.frag new file mode 100644 index 000000000..9899534b4 --- /dev/null +++ b/effects/noise.frag @@ -0,0 +1,47 @@ +#version 110 + +uniform vec2 resolution; +uniform float time; + +uniform float amount; +uniform bool color; +uniform bool blend; + +uniform sampler2D myTexture; +varying vec2 vTexCoord; + +// precision lowp float; + +float PHI = 1.61803398874989484820459 * 00000.1; // Golden Ratio +float PI = 3.14159265358979323846264 * 00000.1; // PI +float SQ2 = 1.41421356237309504880169 * 10000.0; // Square Root of Two + +float gold_noise(vec2 coordinate, float seed){ + return fract(tan(distance(coordinate*(seed+PHI), vec2(PHI, PI)))*SQ2)*(amount*0.01); +} + +void main(void) { + vec3 noise; + if (color) { + noise = vec3(gold_noise(vTexCoord, time + 42069.0), gold_noise(vTexCoord, time + 69220.0), gold_noise(vTexCoord, time + 1337.0)); + } else { + noise = vec3(gold_noise(vTexCoord, time + 69420.0)); + } + + if (blend) { + noise = (noise - vec3(amount*0.005))*vec3(2.0); + + vec4 textureColor = texture2D(myTexture, vec2(vTexCoord.x, vTexCoord.y)); + gl_FragColor = vec4(textureColor.rgb+noise, textureColor.a); + } else { + gl_FragColor = vec4(noise, 1.0); + } +} + +/*void main(void) { + vec4 textureColor = texture2D(myTexture, vec2(vTexCoord.x, vTexCoord.y)); + textureColor.r += gold_noise(resolution); + textureColor.g += gold_noise(resolution); + textureColor.b += gold_noise(resolution); + gl_FragColor = textureColor; +}*/ \ No newline at end of file diff --git a/effects/noise.xml b/effects/noise.xml new file mode 100644 index 000000000..b90478c03 --- /dev/null +++ b/effects/noise.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/effects/shaders.qrc b/effects/shaders.qrc deleted file mode 100644 index 3fd215d0a..000000000 --- a/effects/shaders.qrc +++ /dev/null @@ -1 +0,0 @@ - diff --git a/effects/effects/swirl.frag b/effects/swirl.frag similarity index 85% rename from effects/effects/swirl.frag rename to effects/swirl.frag index 3c093211e..e820e3394 100644 --- a/effects/effects/swirl.frag +++ b/effects/swirl.frag @@ -11,7 +11,7 @@ uniform sampler2D myTexture; varying vec2 vTexCoord; void main(void) { - vec2 center = vec2(center_x, center_y); + vec2 center = vec2((resolution.x*0.5)+center_x, (resolution.y*0.5)+center_y); vec2 uv = vTexCoord.st; @@ -28,6 +28,4 @@ void main(void) { tc += center; vec3 color = texture2D(myTexture, tc / resolution).rgb; gl_FragColor = vec4(color, 1.0); - - } \ No newline at end of file diff --git a/effects/effects/swirl.xml b/effects/swirl.xml similarity index 83% rename from effects/effects/swirl.xml rename to effects/swirl.xml index 962018379..fad929dfa 100644 --- a/effects/effects/swirl.xml +++ b/effects/swirl.xml @@ -1,7 +1,7 @@ - + diff --git a/effects/effects/wave.frag b/effects/wave.frag similarity index 87% rename from effects/effects/wave.frag rename to effects/wave.frag index 61e698f0d..75a6b1dca 100644 --- a/effects/effects/wave.frag +++ b/effects/wave.frag @@ -1,12 +1,10 @@ #version 110 -// uniform float evolution; uniform float frequency; uniform float intensity; uniform float evolution; uniform bool vertical; -uniform mediump float amount_val; uniform sampler2D myTexture; varying vec2 vTexCoord; diff --git a/effects/effects/wave.xml b/effects/wave.xml similarity index 100% rename from effects/effects/wave.xml rename to effects/wave.xml diff --git a/io/previewgenerator.cpp b/io/previewgenerator.cpp index a6ce4f8ff..883343ed9 100644 --- a/io/previewgenerator.cpp +++ b/io/previewgenerator.cpp @@ -26,7 +26,7 @@ extern "C" { #include } -QSemaphore sem(4); // only 4 preview generators can run at one time +QSemaphore sem(5); // only 5 preview generators can run at one time PreviewGenerator::PreviewGenerator(QTreeWidgetItem* i, Media* m, bool r) : QThread(0), diff --git a/effects/qpainterwrapper.cpp b/io/qpainterwrapper.cpp similarity index 100% rename from effects/qpainterwrapper.cpp rename to io/qpainterwrapper.cpp diff --git a/effects/qpainterwrapper.h b/io/qpainterwrapper.h similarity index 100% rename from effects/qpainterwrapper.h rename to io/qpainterwrapper.h diff --git a/olive.pro b/olive.pro index aa8deb58f..a5d025929 100644 --- a/olive.pro +++ b/olive.pro @@ -59,7 +59,6 @@ SOURCES += \ dialogs/replaceclipmediadialog.cpp \ ui/fontcombobox.cpp \ ui/checkboxex.cpp \ - effects/effect.cpp \ ui/keyframeview.cpp \ ui/texteditex.cpp \ dialogs/demonotice.cpp \ @@ -70,7 +69,6 @@ SOURCES += \ dialogs/loaddialog.cpp \ debug.cpp \ io/path.cpp \ - effects/qpainterwrapper.cpp \ effects/internal/linearfadetransition.cpp \ effects/internal/transformeffect.cpp \ effects/internal/solideffect.cpp \ @@ -84,7 +82,9 @@ SOURCES += \ effects/internal/exponentialfadetransition.cpp \ effects/internal/logarithmicfadetransition.cpp \ effects/internal/cornerpineffect.cpp \ - io/math.cpp + io/math.cpp \ + io/qpainterwrapper.cpp \ + project/effect.cpp HEADERS += \ mainwindow.h \ @@ -122,7 +122,6 @@ HEADERS += \ dialogs/replaceclipmediadialog.h \ ui/fontcombobox.h \ ui/checkboxex.h \ - effects/effect.h \ ui/keyframeview.h \ ui/texteditex.h \ dialogs/demonotice.h \ @@ -135,7 +134,6 @@ HEADERS += \ dialogs/loaddialog.h \ debug.h \ io/path.h \ - effects/qpainterwrapper.h \ effects/internal/transformeffect.h \ effects/internal/solideffect.h \ effects/internal/texteffect.h \ @@ -149,7 +147,9 @@ HEADERS += \ effects/internal/exponentialfadetransition.h \ effects/internal/logarithmicfadetransition.h \ effects/internal/cornerpineffect.h \ - io/math.h + io/math.h \ + io/qpainterwrapper.h \ + project/effect.h FORMS += \ mainwindow.ui \ diff --git a/panels/timeline.cpp b/panels/timeline.cpp index f19414912..addf6d94b 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -29,8 +29,7 @@ #include long refactor_frame_number(long framenumber, double source_frame_rate, double target_frame_rate) { - if (source_frame_rate == target_frame_rate) return framenumber; - return qFloor(((double)framenumber/source_frame_rate)*target_frame_rate); + return qRound(((double)framenumber/source_frame_rate)*target_frame_rate); } void draw_selection_rectangle(QPainter& painter, const QRect& rect) { diff --git a/playback/audio.cpp b/playback/audio.cpp index 9700c359e..bc91d8694 100644 --- a/playback/audio.cpp +++ b/playback/audio.cpp @@ -55,7 +55,6 @@ void init_audio(Sequence* s) { } audio_output = new QAudioOutput(audio_format); - dout << "made output;"; audio_output->setNotifyInterval(5); // connect diff --git a/effects/effect.cpp b/project/effect.cpp similarity index 96% rename from effects/effect.cpp rename to project/effect.cpp index b72c17351..8199e16e8 100644 --- a/effects/effect.cpp +++ b/project/effect.cpp @@ -1,6 +1,5 @@ #include "effect.h" -#include "effects/qpainterwrapper.h" #include "panels/panels.h" #include "panels/viewer.h" #include "ui/viewerwidget.h" @@ -767,7 +766,7 @@ Effect* Effect::copy(Clip* c) { return copy; } -void Effect::process_shader(double timecode) { +void Effect::process_shader(double timecode, GLTextureCoords&) { glslProgram->setUniformValue("resolution", parent_clip->getWidth(), parent_clip->getHeight()); glslProgram->setUniformValue("time", (GLfloat) timecode); diff --git a/effects/effect.h b/project/effect.h similarity index 95% rename from effects/effect.h rename to project/effect.h index 5ac86f3fc..e21cbe3a7 100644 --- a/effects/effect.h +++ b/project/effect.h @@ -245,7 +245,7 @@ public: const char* ffmpeg_filter; - void process_shader(double timecode); + virtual void process_shader(double timecode, GLTextureCoords&); virtual void process_coords(double timecode, GLTextureCoords& coords); virtual GLuint process_superimpose(double timecode); virtual void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 5c6c5c0a2..d02610057 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -17,7 +17,7 @@ #include "ui/viewerwidget.h" #include "debug.h" -#include "effects/effect.h" +#include "project/effect.h" #include "effects/internal/solideffect.h" #include "effects/internal/texteffect.h" diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 5ff44a67b..dd3d91fef 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -5,7 +5,7 @@ #include "panels/timeline.h" #include "panels/project.h" #include "project/sequence.h" -#include "effects/effect.h" +#include "project/effect.h" #include "playback/playback.h" #include "playback/audio.h" #include "io/media.h" @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include extern "C" { #include @@ -44,6 +47,9 @@ ViewerWidget::ViewerWidget(QWidget *parent) : // error handler - retries after 500ms if we couldn't get the entire image retry_timer.setInterval(500); connect(&retry_timer, SIGNAL(timeout()), this, SLOT(retry())); + + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu())); } void ViewerWidget::deleteFunction() { @@ -53,6 +59,34 @@ void ViewerWidget::deleteFunction() { doneCurrent(); } +void ViewerWidget::show_context_menu() { + QMenu menu(this); + + QAction* save_frame_as_image = menu.addAction("Save Frame as Image..."); + connect(save_frame_as_image, SIGNAL(triggered(bool)), this, SLOT(save_frame())); + + menu.exec(QCursor::pos()); +} + +void ViewerWidget::save_frame() { + QString fn = QFileDialog::getSaveFileName(this, "Save Frame", QString(), "Images (*.png *.jpg *.bmp *.tiff *.gif *.pbm *.pgm *.ppm *.xbm *.xpm)"); + + if (!fn.isEmpty()) { + rendering = true; + + paintGL(); + QImage img(viewer->seq->width, viewer->seq->height, QImage::Format_RGBA8888); + + dout << img.width() << img.height(); + + img.fill(Qt::magenta); + glReadPixels(0, 0, img.width(), img.height(), GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); + img.save(fn); + + rendering = false; + } +} + void ViewerWidget::retry() { update(); } @@ -206,7 +240,7 @@ void ViewerWidget::process_effect(Clip* c, Effect* e, double timecode, GLTexture if (e->enable_shader || e->enable_superimpose) { e->startEffect(); if (e->enable_shader) { - e->process_shader(timecode); + e->process_shader(timecode, coords); } composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture); if (e->enable_superimpose) { @@ -437,13 +471,13 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) glBegin(GL_QUADS); - // calculate the Q coordinate - double m1 = ((double)coords.vertexTopRightY - (double)coords.vertexBottomLeftY)/((double)coords.vertexTopRightX - (double)coords.vertexBottomLeftX); + // calculate the Q coordinate + /*double m1 = ((double)coords.vertexTopRightY - (double)coords.vertexBottomLeftY)/((double)coords.vertexTopRightX - (double)coords.vertexBottomLeftX); double c1 = (double)coords.vertexBottomLeftY - m1 * (double)coords.vertexBottomLeftX; double m2 = ((double)coords.vertexBottomRightY - (double)coords.vertexTopLeftY)/((double)coords.vertexBottomRightX - (double)coords.vertexTopLeftX); double c2 = (double)coords.vertexTopLeftY - m2 * (double)coords.vertexTopLeftX; double mid_x = (c2 - c1) / (m1 - m2); - double mid_y = m1 * mid_x + c1; + double mid_y = m1 * mid_x + c1; double d0 = qSqrt(qPow(mid_x - (double)coords.vertexBottomLeftX, 2) + qPow(mid_y - (double)coords.vertexBottomLeftY, 2)); double d1 = qSqrt(qPow((double)coords.vertexBottomRightX - mid_x, 2) + qPow(mid_y - (double)coords.vertexBottomRightY, 2)); @@ -453,18 +487,18 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) double q0 = (d0 + d2)/d2; double q1 = (d1 + d3)/d3; double q2 = (d2 + d0)/d0; - double q3 = (d3 + d1)/d1; + double q3 = (d3 + d1)/d1;*/ - //if (coords.grid_size <= 1) { - glTexCoord4f(coords.textureTopLeftX*q3, coords.textureTopLeftY*q3, 0, q3); // top left + if (coords.grid_size <= 1) { + glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left glVertex2f(coords.vertexTopLeftX, coords.vertexTopLeftY); // top left - glTexCoord4f(coords.textureTopRightX*q2, coords.textureTopRightY*q2, 0, q2); // top right + glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right glVertex2f(coords.vertexTopRightX, coords.vertexTopRightY); // top right - glTexCoord4f(coords.textureBottomRightX*q1, coords.textureBottomRightY*q1, 0, q1); // bottom right + glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right glVertex2f(coords.vertexBottomRightX, coords.vertexBottomRightY); // bottom right - glTexCoord4f(coords.textureBottomLeftX*q0, coords.textureBottomLeftY*q0, 0, q0); // bottom left - glVertex2f(coords.vertexBottomLeftX, coords.vertexBottomLeftY); // bottom left - /*} else { + glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left + glVertex2f(coords.vertexBottomLeftX, coords.vertexBottomLeftY); // bottom left + } else { double rows = coords.grid_size; double cols = coords.grid_size; @@ -495,7 +529,7 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) glVertex2f(double_lerp(vertexBLX, vertexBRX, col_prog), double_lerp(vertexTLY, vertexBLY, next_row_prog)); // bottom left } } - }*/ + } glEnd(); diff --git a/ui/viewerwidget.h b/ui/viewerwidget.h index 64831c28c..15d6e41b7 100644 --- a/ui/viewerwidget.h +++ b/ui/viewerwidget.h @@ -48,6 +48,8 @@ private: private slots: void retry(); void deleteFunction(); + void show_context_menu(); + void save_frame(); }; #endif // VIEWERWIDGET_H