From 456103df2f9a7088bb43da44abee61bccdd6c665 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sun, 18 Nov 2018 02:22:11 +1100 Subject: [PATCH] added chroma key --- effects/chromakey.frag | 55 ++++++++++++++++++++++++++++++++++++++++++ effects/chromakey.xml | 13 ++++++++++ effects/common.frag | 2 +- project/effect.cpp | 2 +- project/undo.cpp | 3 --- ui/timelinewidget.cpp | 15 ++++++------ ui/timelinewidget.h | 2 +- ui/viewerwidget.cpp | 2 +- 8 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 effects/chromakey.frag create mode 100644 effects/chromakey.xml diff --git a/effects/chromakey.frag b/effects/chromakey.frag new file mode 100644 index 000000000..0365badc7 --- /dev/null +++ b/effects/chromakey.frag @@ -0,0 +1,55 @@ +/*a fast implementation of the chromakey program +(c) 2008 Edward Cannon (adapted to GLSL by Olive Team) +feel free to use or modify at will*/ + +/*the follwing three functions convert RGB into YCbCr in the same manner as in JPEG images*/ + +uniform sampler2D tex; +varying vec2 vTexCoord; + +uniform vec3 key_color; +uniform float tola; +uniform float tolb; +uniform bool opt; + +float rgb2y (vec3 c) { + /*a utility function to convert colors in RGB into YCbCr*/ + return (0.299*c.r + 0.587*c.g + 0.114*c.b); +} + +float rgb2cb (vec3 c) { + /*a utility function to convert colors in RGB into YCbCr*/ + return (0.5 + -0.168736*c.r - 0.331264*c.g + 0.5*c.b); +} + +float rgb2cr (vec3 c) { + /*a utility function to convert colors in RGB into YCbCr*/ + return (0.5 + 0.5*c.r - 0.418688*c.g - 0.081312*c.b); +} + +float colorclose(float Cb_p,float Cr_p,float Cb_key,float Cr_key,float tola,float tolb) { + /*decides if a color is close to the specified hue*/ + float temp = sqrt(((Cb_key-Cb_p)*(Cb_key-Cb_p))+((Cr_key-Cr_p)*(Cr_key-Cr_p))); + if (temp < tola) {return (0.0);} + if (temp < tolb) {return ((temp-tola)/(tolb-tola));} + return (1.0); +} + +void main(void) { + float cb_key = rgb2cb(key_color); + float cr_key = rgb2cr(key_color); + + vec4 texture_color = texture2D(tex, vTexCoord); + + float cb = rgb2cb(texture_color.rgb); + float cr = rgb2cr(texture_color.rgb); + float mask = colorclose(cb, cr, cb_key, cr_key, (tola/100.0), (tolb/100.0)); + float submask = 1.0-mask; + + texture_color.r = max(texture_color.r - submask*key_color.r, 0.0) + submask; + texture_color.g = max(texture_color.g - submask*key_color.g, 0.0) + submask; + texture_color.b = max(texture_color.b - submask*key_color.b, 0.0) + submask; + texture_color.a *= mask; + + gl_FragColor = texture_color; +} \ No newline at end of file diff --git a/effects/chromakey.xml b/effects/chromakey.xml new file mode 100644 index 000000000..0ee7c9dbf --- /dev/null +++ b/effects/chromakey.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/effects/common.frag b/effects/common.frag index f0a667b18..560ccee97 100644 --- a/effects/common.frag +++ b/effects/common.frag @@ -4,6 +4,6 @@ uniform sampler2D tex; varying vec2 vTexCoord; void main(void) { - vec4 textureColor = texture2D(tex, vec2(vTexCoord.x, vTexCoord.y)); + vec4 textureColor = texture2D(tex, vTexCoord); gl_FragColor = textureColor; } \ No newline at end of file diff --git a/project/effect.cpp b/project/effect.cpp index 0c7c55d5b..c52b26d12 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -781,7 +781,7 @@ void Effect::process_shader(double timecode, GLTextureCoords&) { glslProgram->setUniformValue(field->id.toLatin1().constData(), (GLfloat) field->get_double_value(timecode)); break; case EFFECT_FIELD_COLOR: - glslProgram->setUniformValue(field->id.toLatin1().constData(), field->get_color_value(timecode)); + glslProgram->setUniformValue(field->id.toLatin1().constData(), field->get_color_value(timecode).redF(), field->get_color_value(timecode).greenF(), field->get_color_value(timecode).blueF()); break; case EFFECT_FIELD_STRING: break; // can you even send a string to a uniform value? case EFFECT_FIELD_BOOL: diff --git a/project/undo.cpp b/project/undo.cpp index 780bac2d7..c7aeca279 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -116,10 +116,7 @@ void DeleteClipAction::redo() { // remove ref to clip ref = seq->clips.at(index); if (ref->open) { - dout << "closing clip before deleting"; close_clip(ref); - if (ref->multithreaded) ref->cacher->wait(); - dout << "FINISHED closing clip before deleting"; } seq->clips[index] = NULL; diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index f8586f85b..ab2e6bb84 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -324,7 +324,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) { void TimelineWidget::dragMoveEvent(QDragMoveEvent *event) { if (sequence != NULL && panel_timeline->importing) { QPoint pos = event->pos(); - update_ghosts(pos); + update_ghosts(pos, event->keyboardModifiers() & Qt::ShiftModifier); panel_timeline->move_insert = ((event->keyboardModifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing)); update_ui(false); } @@ -1101,9 +1101,9 @@ void TimelineWidget::init_ghosts() { } } -void TimelineWidget::update_ghosts(const QPoint& mouse_pos) { - int mouse_track = getTrackFromScreenPoint(mouse_pos.y()); - long frame_diff = panel_timeline->getTimelineFrameFromScreenPoint(mouse_pos.x()) - panel_timeline->drag_frame_start; +void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { + int mouse_track = getTrackFromScreenPoint(mouse_pos.y()); + long frame_diff = (lock_frame) ? 0 : panel_timeline->getTimelineFrameFromScreenPoint(mouse_pos.x()) - panel_timeline->drag_frame_start; int track_diff = ((panel_timeline->tool == TIMELINE_TOOL_SLIDE || panel_timeline->transition_select != TA_NO_TRANSITION) && !panel_timeline->importing) ? 0 : mouse_track - panel_timeline->drag_track_start; long validator; long earliest_in_point = LONG_MAX; @@ -1411,7 +1411,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { if (sequence != NULL) { bool alt = (event->modifiers() & Qt::AltModifier); - panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); + panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x()); panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y()); panel_timeline->move_insert = ((event->modifiers() & Qt::ControlModifier) && (panel_timeline->tool == TIMELINE_TOOL_POINTER || panel_timeline->importing || panel_timeline->creating)); @@ -1491,8 +1491,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { panel_timeline->calculate_track_height(track_target, new_height); update(); } else if (panel_timeline->moving_proc) { - QPoint pos = event->pos(); - update_ghosts(pos); + update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); } else { // set up movement // create ghosts @@ -1907,7 +1906,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { } else if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION) { if (panel_timeline->transition_tool_init) { if (panel_timeline->transition_tool_proc) { - update_ghosts(event->pos()); + update_ghosts(event->pos(), event->modifiers() & Qt::ShiftModifier); } else { Clip* c = sequence->clips.at(panel_timeline->transition_tool_pre_clip); diff --git a/ui/timelinewidget.h b/ui/timelinewidget.h index 29db1b980..07c6b6248 100644 --- a/ui/timelinewidget.h +++ b/ui/timelinewidget.h @@ -46,7 +46,7 @@ protected: void wheelEvent(QWheelEvent *event); private: void init_ghosts(); - void update_ghosts(const QPoint &mouse_pos); + void update_ghosts(const QPoint& mouse_pos, bool lock_frame); bool is_track_visible(int track); int getTrackFromScreenPoint(int y); int getScreenPointFromTrack(int track); diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index fe36a4bbc..e1bfe35d2 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -352,7 +352,7 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) int half_height = s->height/2; if (rendering || !nests.isEmpty()) half_height = -half_height; // invert vertical glPushMatrix(); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(1.0, 1.0, 1.0, 1.0); glLoadIdentity(); glOrtho(-half_width, half_width, half_height, -half_height, -1, 1);