diff --git a/effects/boxblur.frag b/effects/boxblur.frag index ee61b6fb7..2ecbd56a4 100644 --- a/effects/boxblur.frag +++ b/effects/boxblur.frag @@ -1,7 +1,5 @@ #version 110 -#define M_PI 3.1415926535897932384626433832795 - uniform sampler2D image; uniform float radius; diff --git a/effects/dropshadow.frag b/effects/dropshadow.frag new file mode 100644 index 000000000..dc41d000f --- /dev/null +++ b/effects/dropshadow.frag @@ -0,0 +1,44 @@ +#version 110 + +uniform sampler2D image; + +uniform vec2 resolution; + +uniform bool shadow; +uniform vec3 shadowcolor; +uniform float shadowsoftness; +uniform float shadowopacity; +uniform float shadowdistance; + +varying vec2 vTexCoord; + +void main(void) { + vec4 master_px = texture2D(image, vTexCoord); + if (shadow) { + + vec2 shadow_dist = vec2(shadowdistance)/resolution; + + float shadow_opacity = 0.01*shadowopacity; + + vec4 shadowed_px = vec4(shadowcolor.r, shadowcolor.g, shadowcolor.b, shadow_opacity*texture2D(image, vTexCoord-shadow_dist).a); + + float rad = floor(shadowsoftness); + if (rad > 0.0) { + shadowed_px.a = 0.0; + float divider = (1.0 / pow(rad, 2.0))*shadow_opacity; + for (float x=-rad+0.5;x<=rad;x+=2.0) { + for (float y=-rad+0.5;y<=rad;y+=2.0) { + shadowed_px.a += shadow_opacity*texture2D(image, vTexCoord-shadow_dist+(vec2(x, y)/resolution)).a*divider; + } + } + } + + vec4 shadow_blend = (shadowed_px*(1.0-master_px.a)); + + vec4 composition = mix(shadow_blend, master_px, master_px.a); + + gl_FragColor = composition; + } else { + gl_FragColor = master_px; + } +} \ No newline at end of file diff --git a/effects/dropshadow.xml.disabled b/effects/dropshadow.xml.disabled new file mode 100644 index 000000000..9a5278d4d --- /dev/null +++ b/effects/dropshadow.xml.disabled @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/effects/internal/texteffect.cpp b/effects/internal/texteffect.cpp index 2fae8d2f0..66a6a6108 100644 --- a/effects/internal/texteffect.cpp +++ b/effects/internal/texteffect.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "ui/labelslider.h" #include "ui/collapsiblewidget.h" @@ -23,6 +24,7 @@ TextEffect::TextEffect(Clip *c, const EffectMeta* em) : Effect(c, em) { enable_superimpose = true; + enable_shader = true; text_val = add_row("Text:")->add_field(EFFECT_FIELD_STRING, "text", 2); @@ -80,70 +82,9 @@ TextEffect::TextEffect(Clip *c, const EffectMeta* em) : connect(shadow_bool, SIGNAL(toggled(bool)), this, SLOT(shadow_enable(bool))); connect(outline_bool, SIGNAL(toggled(bool)), this, SLOT(outline_enable(bool))); -} -void blurred2(QImage& result, const QRect& rect, int radius, bool alphaOnly = false) { - 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 = rect.top(); - int r2 = rect.bottom(); - int c1 = rect.left(); - int c2 = rect.right(); - - int bpl = result.bytesPerLine(); - int rgba[4]; - unsigned char* p; - - int i1 = 0; - int i2 = 3; - - if (alphaOnly) - i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 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; - } + vertPath = "common.vert"; + fragPath = "dropshadow.frag"; } void TextEffect::redraw(double timecode) { @@ -229,24 +170,7 @@ void TextEffect::redraw(double timecode) { } path.addText(text_x, text_y, font, lines.at(i)); - } - - // draw shadow - if (shadow_bool->get_bool_value(timecode)) { - p.setPen(Qt::NoPen); - int shadow_offset = shadow_distance->get_double_value(timecode); - - QPainterPath shadow_path(path); - shadow_path.translate(shadow_offset, shadow_offset); - - QColor col = shadow_color->get_color_value(timecode); - col.setAlphaF(shadow_opacity->get_double_value(timecode)*0.01); - p.setBrush(col); - p.drawPath(shadow_path); - - int blurSoftness = shadow_softness->get_double_value(timecode); - if (blurSoftness > 0) blurred2(img, img.rect(), blurSoftness, false); - } + } // draw outline int outline_width_val = outline_width->get_double_value(timecode); @@ -261,7 +185,7 @@ void TextEffect::redraw(double timecode) { // draw "master" text p.setPen(Qt::NoPen); p.setBrush(set_color_button->get_color_value(timecode)); - p.drawPath(path); + p.drawPath(path); } void TextEffect::shadow_enable(bool e) { @@ -275,188 +199,3 @@ void TextEffect::outline_enable(bool e) { outline_color->set_enabled(e); outline_width->set_enabled(e); } - -/*QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false) -{ - 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]; - - QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); - int r1 = rect.top(); - int r2 = rect.bottom(); - int c1 = rect.left(); - int c2 = rect.right(); - - int bpl = result.bytesPerLine(); - int rgba[4]; - unsigned char* p; - - int i1 = 0; - int i2 = 3; - - if (alphaOnly) - i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 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; - } - - return result; -}*/ - -/*void TextEffect::process_image(double timecode, uint8_t* data, int w, int h) { - QImage img(data, w, h, QImage::Format_RGBA8888); - QPainter p(&img); - p.setRenderHint(QPainter::Antialiasing); - int width = img.width(); - int height = img.height(); - - // set font - font.setStyleHint(QFont::Helvetica, QFont::PreferAntialias); - font.setFamily(set_font_combobox->get_font_name(timecode)); - font.setPointSize(size_val->get_double_value(timecode)); - p.setFont(font); - QFontMetrics fm(font); - - QStringList lines = text_val->get_string_value(timecode).split('\n'); - - // word wrap function - if (word_wrap_field->get_bool_value(timecode)) { - for (int i=0;i width) { - int last_space_index = 0; - for (int j=0;j width) { - break; - } else { - last_space_index = j; - } - } - } - if (last_space_index > 0) { - lines.insert(i+1, s.mid(last_space_index + 1)); - lines[i] = s.left(last_space_index); - } - } - } - } - - QPainterPath path; - - int text_height = fm.height()*lines.size(); - - for (int i=0;iget_combo_data(timecode).toInt()) { - case Qt::AlignLeft: text_x = 0; break; - case Qt::AlignHCenter: text_x = (width/2) - (fm.width(lines.at(i))/2); break; - case Qt::AlignRight: text_x = width - fm.width(lines.at(i)); break; - case Qt::AlignJustify: - // add spaces until the string is too big - text_x = 0; - while (fm.width(lines.at(i) < width)) { - bool space = false; - QString spaced(lines.at(i)); - for (int i=0;i width || !space) { - break; - } else { - lines[i] = spaced; - } - } - break; - } - - switch (valign_field->get_combo_data(timecode).toInt()) { - case Qt::AlignTop: text_y = (fm.height()*i)+fm.ascent(); break; - case Qt::AlignVCenter: text_y = ((height/2) - (text_height/2) - fm.descent()) + (fm.height()*(i+1)); break; - case Qt::AlignBottom: text_y = (height - text_height - fm.descent()) + (fm.height()*(i+1)); break; - } - - path.addText(text_x, text_y, font, lines.at(i)); - } - - p.setPen(Qt::NoPen); - - // draw shadow - if (shadow_bool->get_bool_value(timecode)) { - QImage shadow(width, height, QImage::Format_ARGB32_Premultiplied); - shadow.fill(Qt::transparent); - QPainter spaint(&shadow); - - int shadow_offset = shadow_distance->get_double_value(timecode); - QColor col = shadow_color->get_color_value(timecode); - col.setAlphaF(shadow_opacity->get_double_value(timecode)*0.01); - spaint.setBrush(col); - spaint.drawPath(path); - - blurred2(shadow, shadow.rect(), shadow_softness->get_double_value(timecode), false); - p.drawImage(shadow_offset, shadow_offset, shadow); - - spaint.end(); - } - - // draw outline - int outline_width_val = outline_width->get_double_value(timecode); - if (outline_bool->get_bool_value(timecode) && outline_width_val > 0) { - QPen outline(outline_color->get_color_value(timecode)); - outline.setWidth(outline_width_val); - p.setPen(outline); - } - - // draw "master" text - p.setBrush(set_color_button->get_color_value(timecode)); - p.drawPath(path); -}*/ diff --git a/effects/internal/texteffect.h b/effects/internal/texteffect.h index 644d18fff..44645051a 100644 --- a/effects/internal/texteffect.h +++ b/effects/internal/texteffect.h @@ -35,6 +35,7 @@ private slots: void shadow_enable(bool); private: QFont font; + QImage shadow; }; #endif // TEXTEFFECT_H diff --git a/project/effectgizmo.h b/project/effectgizmo.h index fc7eb05f3..42c1027c7 100644 --- a/project/effectgizmo.h +++ b/project/effectgizmo.h @@ -12,11 +12,14 @@ #include #include +class EffectField; + class EffectGizmo { public: EffectGizmo(int type); + QVector fields; QVector world_pos; QVector screen_pos; QColor color; diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index c01912839..057fd7f75 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -225,13 +225,14 @@ void ViewerWidget::mouseMoveEvent(QMouseEvent* event) { void ViewerWidget::mouseReleaseEvent(QMouseEvent *event) { if (selected_gizmo != NULL) { - undo_stack.push(new MoveGizmo( + /*undo_stack.push(new MoveGizmo( gizmos, selected_gizmo, gizmo_x_mvmt, gizmo_y_mvmt, get_timecode(gizmos->parent_clip, gizmos->parent_clip->sequence->playhead) - )); + ));*/ + } dragging = false; } @@ -340,18 +341,21 @@ void ViewerWidget::process_effect(Clip* c, Effect* e, double timecode, GLTexture e->process_coords(timecode, coords, data); } if (e->enable_shader || e->enable_superimpose) { - e->startEffect(); - if (e->enable_shader) { - e->process_shader(timecode, coords); + e->startEffect(); + if (e->enable_shader) { + e->process_shader(timecode, coords); composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture, true); fbo_switcher = !fbo_switcher; - } - if (e->enable_superimpose) { - GLuint superimpose_texture = e->process_superimpose(timecode); - if (superimpose_texture != 0) { + } + if (e->enable_superimpose) { + GLuint superimpose_texture = e->process_superimpose(timecode); + if (superimpose_texture == 0) { + texture_failed = true; + } else { composite_texture = draw_clip(c->fbo[!fbo_switcher], superimpose_texture, false); } - } + } + e->endEffect(); } } } @@ -579,13 +583,7 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) if (transition_progress >= 0 && transition_progress < c->get_closing_transition()->get_length()) { process_effect(c, c->get_closing_transition(), (double)transition_progress/(double)c->get_closing_transition()->get_length(), coords, composite_texture, fbo_switcher, TA_CLOSING_TRANSITION); } - } - - 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 (!nests.isEmpty()) {