From bcc772e95734ec95312794d6259ff6574e24c743 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 28 Jan 2019 15:04:48 +1100 Subject: [PATCH] blending seems mostly complete --- effects/internal/blending.frag | 32 ++++++++++++++--------------- panels/viewer.cpp | 5 ++++- panels/viewer.h | 1 + ui/renderfunctions.cpp | 37 +++++++++++++++++++++++++++------- 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/effects/internal/blending.frag b/effects/internal/blending.frag index ab6171b73..21cdbe8a9 100644 --- a/effects/internal/blending.frag +++ b/effects/internal/blending.frag @@ -35,6 +35,9 @@ uniform float opacity; varying vec2 vTexCoord; +// adapted from https://github.com/jamieowen/glsl-blend +// and http://www.deepskycolors.com/archivo/2010/04/21/formulas-for-Photoshop-blending-modes.html + // float blending functions float blend_color_burn(float base, float blend) { return (blend==0.0)?blend:max((1.0-((1.0-base)/blend)),0.0); @@ -116,7 +119,6 @@ float blend_soft_light(float base, float blend) { return (blend<0.5)?(2.0*base*blend+base*base*(1.0-2.0*blend)):(sqrt(base)*(2.0*blend-1.0)+2.0*base*(1.0-blend)); } -// adapted from https://github.com/jamieowen/glsl-blend // RGB blending function, alpha is handled below vec3 blend(vec3 base, vec3 blend) { switch (blendmode) { @@ -207,33 +209,29 @@ void main(void) { vec3 composite = blend(bg_color.rgb, fg_color.rgb); // add foreground and background alpha's together - vec4 full_composite = vec4(composite, bg_color.a + fg_color.a); + float alpha_opac = fg_color.a*opacity; - // restore background texture based on foreground's alpha - bool restore_bg = true; - - // some blend modes don't need this switch (blendmode) { - case BLEND_MODE_SCREEN: + case BLEND_MODE_OVERLAY: case BLEND_MODE_LIGHTEN: + case BLEND_MODE_SCREEN: case BLEND_MODE_COLORDODGE: case BLEND_MODE_LINEARDODGE: case BLEND_MODE_ADD: - // case BLEND_MODE_OVERLAY: case BLEND_MODE_SOFTLIGHT: - case BLEND_MODE_DIFFERENCE: - case BLEND_MODE_AVERAGE: case BLEND_MODE_NEGATION: - case BLEND_MODE_PHOENIX: - restore_bg = false; + case BLEND_MODE_AVERAGE: + case BLEND_MODE_REFLECT: + case BLEND_MODE_EXCLUSION: + case BLEND_MODE_DIFFERENCE: + composite *= alpha_opac; + break; } - if (restore_bg) { - full_composite += vec4(bg_color.rgb*(1.0-fg_color.a), 0.0); - } + vec4 full_composite = vec4(composite + bg_color.rgb*(1.0-alpha_opac), bg_color.a + fg_color.a); + // vec4 full_composite = vec4(mix(bg_color.rgb, composite, alpha_opac), bg_color.a + alpha_opac); - // mix via opacity - full_composite = mix(bg_color, full_composite, opacity); + // full_composite = mix(bg_color, full_composite, alpha_opac); // output to color gl_FragColor = full_composite; diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 42f05b7a7..35d92bfac 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -263,7 +263,10 @@ void Viewer::seek(long p) { } } reset_all_audio(); - audio_scrub = true; + if (last_playhead != seq->playhead) { + audio_scrub = true; + } + last_playhead = seq->playhead; update_parents(update_fx); } diff --git a/panels/viewer.h b/panels/viewer.h index db95d90ac..002caea1a 100644 --- a/panels/viewer.h +++ b/panels/viewer.h @@ -105,6 +105,7 @@ private: QString panel_name; double minimum_zoom; bool playing_in_to_out; + long last_playhead; void set_zoom_value(double d); void set_sb_max(); void set_playback_speed(int s); diff --git a/ui/renderfunctions.cpp b/ui/renderfunctions.cpp index 261eb2602..9180385d4 100644 --- a/ui/renderfunctions.cpp +++ b/ui/renderfunctions.cpp @@ -299,9 +299,14 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { // prepare framebuffers for backend drawing operations if (c->fbo == nullptr) { - c->fbo = new QOpenGLFramebufferObject* [2]; - c->fbo[0] = new QOpenGLFramebufferObject(video_width, video_height); - c->fbo[1] = new QOpenGLFramebufferObject(video_width, video_height); + // create 3 fbos for nested sequences, 2 for most clips + int fbo_count = (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) ? 3 : 2; + + c->fbo = new QOpenGLFramebufferObject* [fbo_count]; + + for (int j=0;jfbo[j] = new QOpenGLFramebufferObject(video_width, video_height); + } } // if clip should actually be shown on screen in this frame @@ -419,8 +424,22 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { + // use clip textures for nested sequences, otherwise use main frame buffers + GLuint back_buffer_1; + GLuint backend_tex_1; + GLuint backend_tex_2; + if (params.nests.size() > 0) { + back_buffer_1 = params.nests.last()->fbo[1]->handle(); + backend_tex_1 = params.nests.last()->fbo[1]->texture(); + backend_tex_2 = params.nests.last()->fbo[2]->texture(); + } else { + back_buffer_1 = params.backend_buffer1; + backend_tex_1 = params.backend_attachment1; + backend_tex_2 = params.backend_attachment2; + } + // render a backbuffer - params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, params.backend_buffer1); + params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, back_buffer_1); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); @@ -466,7 +485,11 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { // copy front buffer to back buffer - draw_clip(params.ctx, params.backend_buffer2, params.main_attachment, true); + if (params.nests.size() > 0) { + draw_clip(params.ctx, params.nests.last()->fbo[2]->handle(), params.nests.last()->fbo[0]->texture(), true); + } else { + draw_clip(params.ctx, params.backend_buffer2, params.main_attachment, true); + } @@ -479,11 +502,11 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) { // load background texture into texture unit 0 params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0 - params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, params.backend_attachment2); + params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_2); // load foreground texture into texture unit 1 params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1 - params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, params.backend_attachment1); + params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_1); // bind and configure blending mode shader params.blend_mode_program->bind();