From d44309c2cd7e0329be346f3a0aefea835dbb59ba Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 4 Nov 2018 11:57:53 +1100 Subject: [PATCH] added more effects --- effects/effect.cpp | 1 + effects/effects/bulge.frag | 31 ++++ effects/effects/bulge.xml | 7 + effects/effects/colorcorrection.frag | 74 ++++++++ effects/effects/colorcorrection.xml | 31 ++++ effects/effects/common.frag | 14 ++ effects/effects/flip.frag | 23 +++ effects/effects/flip.xml | 10 + panels/effectcontrols.cpp | 2 +- ui/viewerwidget.cpp | 264 +++++++++++++-------------- 10 files changed, 324 insertions(+), 133 deletions(-) create mode 100644 effects/effects/bulge.frag create mode 100644 effects/effects/bulge.xml create mode 100644 effects/effects/colorcorrection.frag create mode 100644 effects/effects/colorcorrection.xml create mode 100644 effects/effects/common.frag create mode 100644 effects/effects/flip.frag create mode 100644 effects/effects/flip.xml diff --git a/effects/effect.cpp b/effects/effect.cpp index 230c5a115..9336ef3c8 100644 --- a/effects/effect.cpp +++ b/effects/effect.cpp @@ -873,6 +873,7 @@ bool Effect::valueHasChanged(double timecode) { void Effect::delete_texture() { if (texture != NULL) { + texture->destroy(); delete texture; texture = NULL; } diff --git a/effects/effects/bulge.frag b/effects/effects/bulge.frag new file mode 100644 index 000000000..98f44d3fd --- /dev/null +++ b/effects/effects/bulge.frag @@ -0,0 +1,31 @@ +#version 110 + +uniform float amount; + +uniform sampler2D myTexture; +varying vec2 vTexCoord; + +void main(void) { + float x = vTexCoord.x; + float y = vTexCoord.y; + + float r = sqrt(pow(x - 0.5, 2.0) + pow(y - 0.5, 2.0)); + float a = atan(y - 0.5, x - 0.5); + float rn = pow(r, (amount*0.1))/0.5; + //float a = atan(x - 0.5, y - 0.5); + + x = rn * cos(a) + 0.5; + y = rn * sin(a) + 0.5; + + if (y < 0.0 || y > 1.0 || x < 0.0 || x > 1.0) { + gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); + } else { + vec4 textureColor = texture2D(myTexture, vec2(x, y)); + gl_FragColor = vec4( + textureColor.r, + textureColor.g, + textureColor.b, + textureColor.a + ); + } +} \ No newline at end of file diff --git a/effects/effects/bulge.xml b/effects/effects/bulge.xml new file mode 100644 index 000000000..c49b15df9 --- /dev/null +++ b/effects/effects/bulge.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/effects/effects/colorcorrection.frag b/effects/effects/colorcorrection.frag new file mode 100644 index 000000000..46f2713f6 --- /dev/null +++ b/effects/effects/colorcorrection.frag @@ -0,0 +1,74 @@ +#version 110 + +uniform float temperature; +uniform float tint; +uniform float exposure; +uniform float contrast; +uniform float highlights; +uniform float shadows; +uniform float whites; +uniform float blacks; +uniform float saturation; + +uniform sampler2D myTexture; +varying vec2 vTexCoord; + +void main(void) { + vec4 textureColor = texture2D(myTexture, vTexCoord); + + vec3 rgb = textureColor.rgb; + + // temperature + float temp = temperature * 0.01; + float redTemp = (temp <= 66.0) ? 1.0 : min(1.0, max(0.0, + (1.2929361861 * pow(temp - 60.0, -0.1332047592)) + )); + float greenTemp = min(1.0, max(0.0, + (temp <= 66.0) ? (0.3900815788 * log(temp) - 0.6318414438) : (1.1298908609 * pow(temp - 60.0, -0.0755148492)) + )); + float blueTemp = (temp >= 66.0) ? 1.0 : min(1.0, max(0.0, + (0.5432067891 * log(temp - 10.0) - 1.1962540891) + )); + rgb *= vec3(redTemp, greenTemp, blueTemp); + + // tint + rgb.g *= ((tint*0.01)+1.0); + + // exposure + rgb *= pow(2.0, exposure*0.01); + + // contrast + float contr_val = (contrast*0.01); + rgb = (rgb*contr_val)-((contr_val-1.0)*0.5); + + + // shadows/highlights + //float luma = 0.33*rgb.r + 0.5*rgb.g + 0.16*rgb.b; + if (rgb.r < 0.5 && rgb.g < 0.5 && rgb.b < 0.5) { + float shadow_val = 1.0-(shadows*0.01); + rgb = vec3(pow(rgb.r*2.0, shadow_val)*0.5, pow(rgb.g*2.0, shadow_val)*0.5, pow(rgb.b*2.0, shadow_val)*0.5); + } else if (rgb.r > 0.5 && rgb.g > 0.5 && rgb.b > 0.5) { + float highlight_val = 1.0-(highlights*0.01); + rgb = vec3((pow((rgb.r-0.5)*2.0, highlight_val)*0.5)+0.5, (pow((rgb.g-0.5)*2.0, highlight_val)*0.5)+0.5, (pow((rgb.b-0.5)*2.0, highlight_val)*0.5)+0.5); + } + + + // whites + rgb *= (whites*0.01); + + // blacks + float black_val = 2.0-(blacks*0.01); + rgb = (rgb*black_val)-(black_val-1.0); + + // saturation + const vec3 W = vec3(0.2125, 0.7154, 0.0721); + vec3 intensity = vec3(dot(rgb, W)); + rgb = mix(intensity, rgb, saturation*0.01); + + gl_FragColor = vec4( + rgb.r, + rgb.g, + rgb.b, + textureColor.a + ); +} diff --git a/effects/effects/colorcorrection.xml b/effects/effects/colorcorrection.xml new file mode 100644 index 000000000..f103f3d82 --- /dev/null +++ b/effects/effects/colorcorrection.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/effects/effects/common.frag b/effects/effects/common.frag new file mode 100644 index 000000000..ec9d3f905 --- /dev/null +++ b/effects/effects/common.frag @@ -0,0 +1,14 @@ +#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/flip.frag b/effects/effects/flip.frag new file mode 100644 index 000000000..6a55cc8ca --- /dev/null +++ b/effects/effects/flip.frag @@ -0,0 +1,23 @@ +#version 110 + +uniform bool horiz; +uniform bool vert; + +uniform sampler2D myTexture; +varying vec2 vTexCoord; + +void main(void) { + float x = vTexCoord.x; + float y = vTexCoord.y; + + if (horiz) x = 1.0 - x; + if (vert) y = 1.0 - y; + + vec4 textureColor = texture2D(myTexture, vec2(x, y)); + gl_FragColor = vec4( + textureColor.r, + textureColor.g, + textureColor.b, + textureColor.a + ); +} \ No newline at end of file diff --git a/effects/effects/flip.xml b/effects/effects/flip.xml new file mode 100644 index 000000000..f3d762733 --- /dev/null +++ b/effects/effects/flip.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 59866e70d..7e2826225 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -296,7 +296,7 @@ void EffectControls::load_effects() { } } if (selected_clips.size() > 0) { - ui->verticalScrollBar->setMaximum(qMax(0, ui->effects_area->height() - ui->keyframeView->height() - ui->headers->height())); + ui->verticalScrollBar->setMaximum(qMax(0, ui->effects_area->sizeHint().height() - ui->headers->height() + ui->scrollArea->horizontalScrollBar()->height()/* - ui->keyframeView->height() - ui->headers->height()*/)); ui->keyframeView->setEnabled(true); ui->headers->setVisible(true); ui->keyframeView->update(); diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 48163a31f..7d9e43b1c 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -176,6 +176,8 @@ GLuint ViewerWidget::draw_clip(QOpenGLFramebufferObject* fbo, GLuint texture) { fbo->bind(); + glClear(GL_COLOR_BUFFER_BIT); + glBindTexture(GL_TEXTURE_2D, texture); glBegin(GL_QUADS); glTexCoord2f(0, 0); // top left @@ -301,140 +303,138 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) { textureID = -1; } - if (!texture_failed) { - if (textureID == 0 && c->media_type != MEDIA_TYPE_SOLID) { - dout << "[WARNING] Texture hasn't been created yet"; - texture_failed = true; - } else if (playhead >= c->timeline_in) { - glPushMatrix(); + if (textureID == 0 && c->media_type != MEDIA_TYPE_SOLID) { + dout << "[WARNING] Texture hasn't been created yet"; + texture_failed = true; + } else if (playhead >= c->timeline_in) { + glPushMatrix(); - // start preparing cache - if (c->fbo == NULL) { - c->fbo = new QOpenGLFramebufferObject* [2]; - c->fbo[0] = new QOpenGLFramebufferObject(video_width, video_height); - c->fbo[1] = new QOpenGLFramebufferObject(video_width, video_height); - } - - // clear fbos - c->fbo[0]->bind(); - glClear(GL_COLOR_BUFFER_BIT); - c->fbo[0]->release(); - c->fbo[1]->bind(); - glClear(GL_COLOR_BUFFER_BIT); - c->fbo[1]->release(); - - bool fbo_switcher = false; - - glViewport(0, 0, video_width, video_height); - - // for nested sequences - if (c->media_type == MEDIA_TYPE_SEQUENCE) { - textureID = compose_sequence(c, render_audio); - fbo_switcher = true; - } - - GLuint composite_texture; - if (c->media_type == MEDIA_TYPE_SOLID) { - composite_texture = c->fbo[fbo_switcher]->texture(); - } else { - composite_texture = draw_clip(c->fbo[fbo_switcher], textureID); - } - - fbo_switcher = !fbo_switcher; - - GLTextureCoords coords; - coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2; - coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2; - coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2; - coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; - coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0; - coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0; - - if (c->autoscale && (video_width != s->width || video_height != s->height)) { - double width_multiplier = (double) s->width / (double) video_width; - double height_multiplier = (double) s->height / (double) video_height; - double scale_multiplier = qMin(width_multiplier, height_multiplier); - glScalef(scale_multiplier, scale_multiplier, 1); - } - - // EFFECT CODE START - for (int j=0;jeffects.size();j++) { - Effect* e = c->effects.at(j); - if (e->is_enabled()) { - double timecode = ((double)(playhead-c->timeline_in+c->clip_in)/(double)c->sequence->frame_rate); - if (e->enable_coords) { - e->process_coords(timecode, coords); - } - if (e->enable_shader || e->enable_superimpose) { - e->startEffect(); - if (e->enable_shader) { - e->process_shader(timecode); - } - composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture); - if (e->enable_superimpose) { - GLuint superimpose_texture = e->process_superimpose(timecode); - if (superimpose_texture != 0) draw_clip(c->fbo[fbo_switcher], superimpose_texture); - } - fbo_switcher = !fbo_switcher; - } - } - } - - if (c->opening_transition != NULL) { - int transition_progress = playhead - c->timeline_in; - if (transition_progress < c->opening_transition->length) { - c->opening_transition->process_transition((double)transition_progress/(double)c->opening_transition->length); - } - } - - if (c->closing_transition != NULL) { - int transition_progress = c->closing_transition->length - (playhead - c->timeline_in - c->getLength() + c->closing_transition->length); - if (transition_progress < c->closing_transition->length) { - c->closing_transition->process_transition((double)transition_progress/(double)c->closing_transition->length); - } - } - - for (int j=0;jeffects.size();j++) { - if ((c->effects.at(j)->enable_shader || c->effects.at(j)->enable_superimpose) && c->effects.at(j)->is_enabled()) { - c->effects.at(j)->endEffect(); - } - } - // EFFECT CODE END - - if (nest != NULL) { - nest->fbo[0]->bind(); - glViewport(0, 0, s->width, s->height); - } else if (rendering) { - glViewport(0, 0, s->width, s->height); - } else { - glViewport(0, 0, width(), height()); - } - - glBindTexture(GL_TEXTURE_2D, composite_texture); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glBegin(GL_QUADS); - glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left - glVertex2f(coords.vertexTopLeftX, coords.vertexTopLeftY); // top left - glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right - glVertex2f(coords.vertexTopRightX, coords.vertexTopRightY); // top right - glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right - glVertex2f(coords.vertexBottomRightX, coords.vertexBottomRightY); // bottom right - glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left - glVertex2f(coords.vertexBottomLeftX, coords.vertexBottomLeftY); // bottom left - glEnd(); - - glBindTexture(GL_TEXTURE_2D, 0); - - if (nest != NULL) { - nest->fbo[0]->release(); - if (default_fbo != NULL) default_fbo->bind(); - } - - glPopMatrix(); + // start preparing cache + if (c->fbo == NULL) { + c->fbo = new QOpenGLFramebufferObject* [2]; + c->fbo[0] = new QOpenGLFramebufferObject(video_width, video_height); + c->fbo[1] = new QOpenGLFramebufferObject(video_width, video_height); } + + // clear fbos + /*c->fbo[0]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + c->fbo[0]->release(); + c->fbo[1]->bind(); + glClear(GL_COLOR_BUFFER_BIT); + c->fbo[1]->release();*/ + + bool fbo_switcher = false; + + glViewport(0, 0, video_width, video_height); + + // for nested sequences + if (c->media_type == MEDIA_TYPE_SEQUENCE) { + textureID = compose_sequence(c, render_audio); + fbo_switcher = true; + } + + GLuint composite_texture; + if (c->media_type == MEDIA_TYPE_SOLID) { + composite_texture = c->fbo[fbo_switcher]->texture(); + } else { + composite_texture = draw_clip(c->fbo[fbo_switcher], textureID); + } + + fbo_switcher = !fbo_switcher; + + GLTextureCoords coords; + coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2; + coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2; + coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2; + coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; + coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0; + coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0; + + if (c->autoscale && (video_width != s->width || video_height != s->height)) { + double width_multiplier = (double) s->width / (double) video_width; + double height_multiplier = (double) s->height / (double) video_height; + double scale_multiplier = qMin(width_multiplier, height_multiplier); + glScalef(scale_multiplier, scale_multiplier, 1); + } + + // EFFECT CODE START + for (int j=0;jeffects.size();j++) { + Effect* e = c->effects.at(j); + if (e->is_enabled()) { + double timecode = ((double)(playhead-c->timeline_in+c->clip_in)/(double)c->sequence->frame_rate); + if (e->enable_coords) { + e->process_coords(timecode, coords); + } + if (e->enable_shader || e->enable_superimpose) { + e->startEffect(); + if (e->enable_shader) { + e->process_shader(timecode); + } + composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture); + if (e->enable_superimpose) { + GLuint superimpose_texture = e->process_superimpose(timecode); + if (superimpose_texture != 0) draw_clip(c->fbo[fbo_switcher], superimpose_texture); + } + fbo_switcher = !fbo_switcher; + } + } + } + + if (c->opening_transition != NULL) { + int transition_progress = playhead - c->timeline_in; + if (transition_progress < c->opening_transition->length) { + c->opening_transition->process_transition((double)transition_progress/(double)c->opening_transition->length); + } + } + + if (c->closing_transition != NULL) { + int transition_progress = c->closing_transition->length - (playhead - c->timeline_in - c->getLength() + c->closing_transition->length); + if (transition_progress < c->closing_transition->length) { + c->closing_transition->process_transition((double)transition_progress/(double)c->closing_transition->length); + } + } + + for (int j=0;jeffects.size();j++) { + if ((c->effects.at(j)->enable_shader || c->effects.at(j)->enable_superimpose) && c->effects.at(j)->is_enabled()) { + c->effects.at(j)->endEffect(); + } + } + // EFFECT CODE END + + if (nest != NULL) { + nest->fbo[0]->bind(); + glViewport(0, 0, s->width, s->height); + } else if (rendering) { + glViewport(0, 0, s->width, s->height); + } else { + glViewport(0, 0, width(), height()); + } + + glBindTexture(GL_TEXTURE_2D, composite_texture); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glBegin(GL_QUADS); + glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left + glVertex2f(coords.vertexTopLeftX, coords.vertexTopLeftY); // top left + glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right + glVertex2f(coords.vertexTopRightX, coords.vertexTopRightY); // top right + glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right + glVertex2f(coords.vertexBottomRightX, coords.vertexBottomRightY); // bottom right + glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left + glVertex2f(coords.vertexBottomLeftX, coords.vertexBottomLeftY); // bottom left + glEnd(); + + glBindTexture(GL_TEXTURE_2D, 0); + + if (nest != NULL) { + nest->fbo[0]->release(); + if (default_fbo != NULL) default_fbo->bind(); + } + + glPopMatrix(); } } else { if (render_audio || (config.enable_audio_scrubbing && audio_scrub)) {