diff --git a/debug.cpp b/debug.cpp
index e948b5e51..b64e38ecd 100644
--- a/debug.cpp
+++ b/debug.cpp
@@ -34,79 +34,79 @@ QFile debug_file;
QTextStream debug_stream;
void open_debug_file() {
- QDir debug_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
- debug_dir.mkpath(".");
- if (debug_dir.exists()) {
- debug_file.setFileName(debug_dir.path() + "/debug_log");
- if (debug_file.open(QFile::WriteOnly)) {
- debug_stream.setDevice(&debug_file);
- } else {
- qWarning() << "Couldn't open debug log file, debug log will not be saved";
- }
+ QDir debug_dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
+ debug_dir.mkpath(".");
+ if (debug_dir.exists()) {
+ debug_file.setFileName(debug_dir.path() + "/debug_log");
+ if (debug_file.open(QFile::WriteOnly)) {
+ debug_stream.setDevice(&debug_file);
+ } else {
+ qWarning() << "Couldn't open debug log file, debug log will not be saved";
}
+ }
}
void close_debug_file()
{
- if (debug_file.isOpen()) {
- debug_file.close();
- }
+ if (debug_file.isOpen()) {
+ debug_file.close();
+ }
}
void debug_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
- debug_mutex.lock();
- const QByteArray localMsg = msg.toLocal8Bit();
- const QDateTime now = QDateTime::currentDateTime();
- const QByteArray timeRepr(now.toString(Qt::ISODate).toLocal8Bit());
- QString msgTag;
- QString fontColor;
- switch (type) {
- case QtDebugMsg:
- msgTag = "DEBUG";
- fontColor = "grey";
- break;
- case QtInfoMsg:
- msgTag = "INFO";
- fontColor = "blue";
- break;
- case QtWarningMsg:
- msgTag = "WARNING";
- fontColor = "yellow";
- break;
- case QtCriticalMsg:
- msgTag = "ERROR";
- fontColor = "red";
- break;
- case QtFatalMsg:
- msgTag = "FATAL";
- fontColor = "red";
- break;
- default:
- fprintf(stderr, "Unknown debug msg type");
- fflush(stderr);
- break;
- }//switch
+ debug_mutex.lock();
+ const QByteArray localMsg = msg.toLocal8Bit();
+ const QDateTime now = QDateTime::currentDateTime();
+ const QByteArray timeRepr(now.toString(Qt::ISODate).toLocal8Bit());
+ QString msgTag;
+ QString fontColor;
+ switch (type) {
+ case QtDebugMsg:
+ msgTag = "DEBUG";
+ fontColor = "grey";
+ break;
+ case QtInfoMsg:
+ msgTag = "INFO";
+ fontColor = "blue";
+ break;
+ case QtWarningMsg:
+ msgTag = "WARNING";
+ fontColor = "yellow";
+ break;
+ case QtCriticalMsg:
+ msgTag = "ERROR";
+ fontColor = "red";
+ break;
+ case QtFatalMsg:
+ msgTag = "FATAL";
+ fontColor = "red";
+ break;
+ default:
+ fprintf(stderr, "Unknown debug msg type");
+ fflush(stderr);
+ break;
+ }//switch
- /*fprintf(stderr, "%s [%s] %s (%s:%u, %s)\n", timeRepr.data(), msgTag.toLocal8Bit().constData(), localMsg.data(),
+ /*fprintf(stderr, "%s [%s] %s (%s:%u, %s)\n", timeRepr.data(), msgTag.toLocal8Bit().constData(), localMsg.data(),
context.file, context.line, context.function);*/
- fprintf(stderr, "%s [%s] %s\n", timeRepr.data(), msgTag.toLocal8Bit().constData(), localMsg.data());
+ fprintf(stderr, "%s [%s] %s\n", timeRepr.data(), msgTag.toLocal8Bit().constData(), localMsg.data());
- if (debug_file.isOpen()) {
- debug_stream << QString("[%1] %2 (%3:%4, %5)\n")
- .arg(msgTag, localMsg, context.file, QString::number(context.line), context.function);
- }
- debug_info.prepend(QString("[%2] %3 (%4:%5, %6)
")
- .arg(fontColor, msgTag, localMsg, context.file, QString::number(context.line), context.function));
- fflush(stderr);
- if (olive::DebugDialog != nullptr && olive::DebugDialog->isVisible()) {
- QMetaObject::invokeMethod(olive::DebugDialog, "update_log", Qt::QueuedConnection);
- }
- debug_mutex.unlock();
+ if (debug_file.isOpen()) {
+ debug_stream << QString("[%1] %2 (%3:%4, %5)\n")
+ .arg(msgTag, localMsg, context.file, QString::number(context.line), context.function);
+ }
+ debug_info.prepend(QString("[%2] %3 (%4:%5, %6)
")
+ .arg(fontColor, msgTag, localMsg, context.file, QString::number(context.line), context.function));
+ fflush(stderr);
+ if (olive::DebugDialog != nullptr && olive::DebugDialog->isVisible()) {
+ QMetaObject::invokeMethod(olive::DebugDialog, "update_log", Qt::QueuedConnection);
+ }
+ debug_mutex.unlock();
}
const QString &get_debug_str()
{
- return debug_info;
+ return debug_info;
}
diff --git a/effects/internal/blending.frag b/effects/internal/blending.frag
index c8d14d593..8f4dd3201 100644
--- a/effects/internal/blending.frag
+++ b/effects/internal/blending.frag
@@ -1,176 +1,13 @@
#version 110
-const int BLEND_MODE_ADD = 0;
-const int BLEND_MODE_AVERAGE = 1;
-const int BLEND_MODE_COLORBURN = 2;
-const int BLEND_MODE_COLORDODGE = 3;
-const int BLEND_MODE_DARKEN = 4;
-const int BLEND_MODE_DIFFERENCE = 5;
-const int BLEND_MODE_EXCLUSION = 6;
-const int BLEND_MODE_GLOW = 7;
-const int BLEND_MODE_HARDLIGHT = 8;
-const int BLEND_MODE_HARDMIX = 9;
-const int BLEND_MODE_LIGHTEN = 10;
-const int BLEND_MODE_LINEARBURN = 11;
-const int BLEND_MODE_LINEARDODGE = 12;
-const int BLEND_MODE_LINEARLIGHT = 13;
-const int BLEND_MODE_MULTIPLY = 14;
-const int BLEND_MODE_NEGATION = 15;
-const int BLEND_MODE_NORMAL = 16;
-const int BLEND_MODE_OVERLAY = 17;
-const int BLEND_MODE_PHOENIX = 18;
-const int BLEND_MODE_PINLIGHT = 19;
-const int BLEND_MODE_REFLECT = 20;
-const int BLEND_MODE_SCREEN = 21;
-const int BLEND_MODE_SOFTLIGHT = 22;
-const int BLEND_MODE_SUBSTRACT = 23;
-const int BLEND_MODE_SUBTRACT = 24;
-const int BLEND_MODE_VIVIDLIGHT = 25;
+/*
+ This main stump is combined with another shader loaded externally to produce a blending mode.
-uniform sampler2D background;
-uniform sampler2D foreground;
+ For a custom blend mode, the function blend() MUST be available, and use the following syntax:
-uniform int blendmode;
-uniform float opacity;
+ blend(vec3 base_color, vec3 blend_color, 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);
-}
-
-float blend_color_dodge(float base, float blend) {
- return (blend==1.0)?blend:min(base/(1.0-blend),1.0);
-}
-
-float blend_vivid_light(float base, float blend) {
- return (blend<0.5)?blend_color_burn(base,(2.0*blend)):blend_color_dodge(base,(2.0*(blend-0.5)));
-}
-
-vec3 blend_vivid_light(vec3 base, vec3 blend) {
- return vec3(blend_vivid_light(base.r,blend.r),blend_vivid_light(base.g,blend.g),blend_vivid_light(base.b,blend.b));
-}
-
-float blend_hard_mix(float base, float blend) {
- return (blend_vivid_light(base,blend)<0.5)?0.0:1.0;
-}
-
-float blend_lighten(float base, float blend) {
- return max(blend,base);
-}
-
-float blend_overlay(float base, float blend) {
- return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend));
-}
-
-vec3 blend_overlay(vec3 base, vec3 blend) {
- return vec3(blend_overlay(base.r,blend.r),blend_overlay(base.g,blend.g),blend_overlay(base.b,blend.b));
-}
-
-float blend_darken(float base, float blend) {
- return min(blend, base);
-}
-
-float blend_linear_burn(float base, float blend) {
- return max(base+blend-1.0,0.0);
-}
-
-vec3 blend_linear_burn(vec3 base, vec3 blend) {
- return max(base+blend-vec3(1.0),vec3(0.0));
-}
-
-float blend_linear_dodge(float base, float blend) {
- return min(base+blend,1.0);
-}
-
-vec3 blend_linear_dodge(vec3 base, vec3 blend) {
- return min(base+blend,vec3(1.0));
-}
-
-float blend_linear_light(float base, float blend) {
- return blend<0.5?blend_linear_burn(base,(2.0*blend)):blend_linear_dodge(base,(2.0*(blend-0.5)));
-}
-
-float blend_pin_light(float base, float blend) {
- return (blend<0.5)?blend_darken(base,(2.0*blend)):blend_lighten(base,(2.0*(blend-0.5)));
-}
-
-float blend_reflect(float base, float blend) {
- return (blend==1.0)?blend:min(base*base/(1.0-blend),1.0);
-}
-
-vec3 blend_reflect(vec3 base, vec3 blend) {
- return vec3(blend_reflect(base.r,blend.r),blend_reflect(base.g,blend.g),blend_reflect(base.b,blend.b));
-}
-
-float blend_screen(float base, float blend) {
- return 1.0-((1.0-base)*(1.0-blend));
-}
-
-float blend_substract(float base, float blend) {
- return max(base+blend-1.0,0.0);
-}
-
-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));
-}
-
-// RGB blending function, alpha is handled below
-vec3 blend(vec3 base, vec3 blend) {
- if (blendmode == BLEND_MODE_AVERAGE) {
- return (base+blend)/2.0;
- } else if (blendmode == BLEND_MODE_COLORBURN) {
- return vec3(blend_color_burn(base.r, blend.r), blend_color_burn(base.g, blend.g), blend_color_burn(base.b, blend.b));
- } else if (blendmode == BLEND_MODE_COLORDODGE) {
- return vec3(blend_color_dodge(base.r, blend.r), blend_color_dodge(base.g, blend.g), blend_color_dodge(base.b, blend.b));
- } else if (blendmode == BLEND_MODE_DARKEN) {
- return vec3(blend_darken(base.r, blend.r), blend_darken(base.g, blend.g), blend_darken(base.b, blend.b));
- } else if (blendmode == BLEND_MODE_DIFFERENCE) {
- return abs(base-blend);
- } else if (blendmode == BLEND_MODE_EXCLUSION) {
- return base+blend-2.0*base*blend;
- } else if (blendmode == BLEND_MODE_GLOW) {
- return blend_reflect(blend, base);
- } else if (blendmode == BLEND_MODE_HARDLIGHT) {
- return blend_overlay(blend,base);
- } else if (blendmode == BLEND_MODE_HARDMIX) {
- return vec3(blend_hard_mix(base.r,blend.r),blend_hard_mix(base.g,blend.g),blend_hard_mix(base.b,blend.b));
- } else if (blendmode == BLEND_MODE_LIGHTEN) {
- return vec3(blend_lighten(base.r,blend.r),blend_lighten(base.g,blend.g),blend_lighten(base.b,blend.b));
- } else if (blendmode == BLEND_MODE_LINEARBURN || blendmode == BLEND_MODE_SUBTRACT) {
- return blend_linear_burn(base, blend);
- } else if (blendmode == BLEND_MODE_LINEARDODGE || blendmode == BLEND_MODE_ADD) {
- return blend_linear_dodge(base, blend);
- } else if (blendmode == BLEND_MODE_LINEARLIGHT) {
- return vec3(blend_linear_light(base.r,blend.r),blend_linear_light(base.g,blend.g),blend_linear_light(base.b,blend.b));
- } else if (blendmode == BLEND_MODE_MULTIPLY) {
- return (base * blend);
- } else if (blendmode == BLEND_MODE_NEGATION) {
- return vec3(1.0)-abs(vec3(1.0)-base-blend);
- } else if (blendmode == BLEND_MODE_OVERLAY) {
- return blend_overlay(base, blend);
- } else if (blendmode == BLEND_MODE_PHOENIX) {
- return min(base,blend)-max(base,blend)+vec3(1.0);
- } else if (blendmode == BLEND_MODE_PINLIGHT) {
- return vec3(blend_pin_light(base.r,blend.r),blend_pin_light(base.g,blend.g),blend_pin_light(base.b,blend.b));
- } else if (blendmode == BLEND_MODE_REFLECT) {
- return blend_reflect(base, blend);
- } else if (blendmode == BLEND_MODE_SCREEN) {
- return vec3(blend_screen(base.r,blend.r),blend_screen(base.g,blend.g),blend_screen(base.b,blend.b));
- } else if (blendmode == BLEND_MODE_SUBSTRACT) {
- return max(base+blend-vec3(1.0),vec3(0.0));
- } else if (blendmode == BLEND_MODE_SOFTLIGHT) {
- return vec3(blend_soft_light(base.r,blend.r),blend_soft_light(base.g,blend.g),blend_soft_light(base.b,blend.b));
- } else if (blendmode == BLEND_MODE_VIVIDLIGHT) {
- return vec3(blend_vivid_light(base.r,blend.r),blend_vivid_light(base.g,blend.g),blend_vivid_light(base.b,blend.b));
- } else {
- return blend;
- }
-}
+*/
void main(void) {
vec4 bg_color = texture2D(background, vTexCoord);
@@ -179,9 +16,6 @@ void main(void) {
// blend textures together
vec3 composite = blend(bg_color.rgb, fg_color.rgb);
- // add foreground and background alpha's together
- // float alpha_opac = fg_color.a*opacity;
-
if (blendmode == BLEND_MODE_OVERLAY
|| blendmode == BLEND_MODE_LIGHTEN
|| blendmode == BLEND_MODE_SCREEN
@@ -198,7 +32,6 @@ void main(void) {
}
vec4 full_composite = vec4(composite + bg_color.rgb*(1.0-fg_color.a), bg_color.a + fg_color.a);
- // vec4 full_composite = vec4(mix(bg_color.rgb, composite, alpha_opac), bg_color.a + alpha_opac);
full_composite = mix(bg_color, full_composite, opacity);
diff --git a/effects/internal/transformeffect.cpp b/effects/internal/transformeffect.cpp
index 07dd08d3f..f4065ba1e 100644
--- a/effects/internal/transformeffect.cpp
+++ b/effects/internal/transformeffect.cpp
@@ -44,230 +44,210 @@
#include "ui/viewerwidget.h"
TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em) {
- enable_coords = true;
+ enable_coords = true;
- EffectRow* position_row = add_row(tr("Position"));
- position_x = position_row->add_field(EFFECT_FIELD_DOUBLE, "posx"); // position X
- position_y = position_row->add_field(EFFECT_FIELD_DOUBLE, "posy"); // position Y
+ EffectRow* position_row = add_row(tr("Position"));
+ position_x = position_row->add_field(EFFECT_FIELD_DOUBLE, "posx"); // position X
+ position_y = position_row->add_field(EFFECT_FIELD_DOUBLE, "posy"); // position Y
- EffectRow* scale_row = add_row(tr("Scale"));
- scale_x = scale_row->add_field(EFFECT_FIELD_DOUBLE, "scalex"); // scale X (and Y is uniform scale is selected)
- scale_x->set_double_minimum_value(0);
- scale_x->set_double_maximum_value(3000);
- scale_y = scale_row->add_field(EFFECT_FIELD_DOUBLE, "scaley"); // scale Y (disabled if uniform scale is selected)
- scale_y->set_double_minimum_value(0);
- scale_y->set_double_maximum_value(3000);
+ EffectRow* scale_row = add_row(tr("Scale"));
+ scale_x = scale_row->add_field(EFFECT_FIELD_DOUBLE, "scalex"); // scale X (and Y is uniform scale is selected)
+ scale_x->set_double_minimum_value(0);
+ scale_x->set_double_maximum_value(3000);
+ scale_y = scale_row->add_field(EFFECT_FIELD_DOUBLE, "scaley"); // scale Y (disabled if uniform scale is selected)
+ scale_y->set_double_minimum_value(0);
+ scale_y->set_double_maximum_value(3000);
- EffectRow* uniform_scale_row = add_row(tr("Uniform Scale"));
- uniform_scale_field = uniform_scale_row->add_field(EFFECT_FIELD_BOOL, "uniformscale"); // uniform scale option
+ EffectRow* uniform_scale_row = add_row(tr("Uniform Scale"));
+ uniform_scale_field = uniform_scale_row->add_field(EFFECT_FIELD_BOOL, "uniformscale"); // uniform scale option
- EffectRow* rotation_row = add_row(tr("Rotation"));
- rotation = rotation_row->add_field(EFFECT_FIELD_DOUBLE, "rotation");
+ EffectRow* rotation_row = add_row(tr("Rotation"));
+ rotation = rotation_row->add_field(EFFECT_FIELD_DOUBLE, "rotation");
- EffectRow* anchor_point_row = add_row(tr("Anchor Point"));
- anchor_x_box = anchor_point_row->add_field(EFFECT_FIELD_DOUBLE, "anchorx"); // anchor point X
- anchor_y_box = anchor_point_row->add_field(EFFECT_FIELD_DOUBLE, "anchory"); // anchor point Y
+ EffectRow* anchor_point_row = add_row(tr("Anchor Point"));
+ anchor_x_box = anchor_point_row->add_field(EFFECT_FIELD_DOUBLE, "anchorx"); // anchor point X
+ anchor_y_box = anchor_point_row->add_field(EFFECT_FIELD_DOUBLE, "anchory"); // anchor point Y
- EffectRow* opacity_row = add_row(tr("Opacity"));
- opacity = opacity_row->add_field(EFFECT_FIELD_DOUBLE, "opacity"); // opacity
- opacity->set_double_minimum_value(0);
- opacity->set_double_maximum_value(100);
+ EffectRow* opacity_row = add_row(tr("Opacity"));
+ opacity = opacity_row->add_field(EFFECT_FIELD_DOUBLE, "opacity"); // opacity
+ opacity->set_double_minimum_value(0);
+ opacity->set_double_maximum_value(100);
- EffectRow* blend_mode_row = add_row(tr("Blend Mode"));
- blend_mode_box = blend_mode_row->add_field(EFFECT_FIELD_COMBO, "blendmode", 2); // blend mode
- blend_mode_box->add_combo_item(tr("Normal"), BLEND_MODE_NORMAL);
- blend_mode_box->add_combo_item(tr("Darken"), BLEND_MODE_DARKEN);
- blend_mode_box->add_combo_item(tr("Multiply"), BLEND_MODE_MULTIPLY);
- blend_mode_box->add_combo_item(tr("Color Burn"), BLEND_MODE_COLORBURN);
- blend_mode_box->add_combo_item(tr("Linear Burn"), BLEND_MODE_LINEARBURN);
- blend_mode_box->add_combo_item(tr("Lighten"), BLEND_MODE_LIGHTEN);
- blend_mode_box->add_combo_item(tr("Screen"), BLEND_MODE_SCREEN);
- blend_mode_box->add_combo_item(tr("Color Dodge"), BLEND_MODE_COLORDODGE);
- blend_mode_box->add_combo_item(tr("Linear Dodge (Add)"), BLEND_MODE_LINEARDODGE);
- blend_mode_box->add_combo_item(tr("Overlay"), BLEND_MODE_OVERLAY);
- blend_mode_box->add_combo_item(tr("Soft Light"), BLEND_MODE_SOFTLIGHT);
- blend_mode_box->add_combo_item(tr("Hard Light"), BLEND_MODE_HARDLIGHT);
- blend_mode_box->add_combo_item(tr("Vivid Light"), BLEND_MODE_VIVIDLIGHT);
- blend_mode_box->add_combo_item(tr("Linear Light"), BLEND_MODE_LINEARLIGHT);
- blend_mode_box->add_combo_item(tr("Pin Light"), BLEND_MODE_PINLIGHT);
- blend_mode_box->add_combo_item(tr("Hard Mix"), BLEND_MODE_HARDMIX);
- blend_mode_box->add_combo_item(tr("Difference"), BLEND_MODE_DIFFERENCE);
- blend_mode_box->add_combo_item(tr("Exclusion"), BLEND_MODE_EXCLUSION);
- blend_mode_box->add_combo_item(tr("Reflect"), BLEND_MODE_REFLECT);
-// blend_mode_box->add_combo_item(tr("Subtract"), BLEND_MODE_SUBTRACT);
- blend_mode_box->add_combo_item(tr("Substract"), BLEND_MODE_SUBSTRACT);
-// blend_mode_box->add_combo_item(tr("Add"), BLEND_MODE_ADD);
- blend_mode_box->add_combo_item(tr("Average"), BLEND_MODE_AVERAGE);
- blend_mode_box->add_combo_item(tr("Glow"), BLEND_MODE_GLOW);
- blend_mode_box->add_combo_item(tr("Negation"), BLEND_MODE_NEGATION);
- blend_mode_box->add_combo_item(tr("Phoenix"), BLEND_MODE_PHOENIX);
+ EffectRow* blend_mode_row = add_row(tr("Blend Mode"));
+ blend_mode_box = blend_mode_row->add_field(EFFECT_FIELD_COMBO, "blendmode", 2); // blend mode
+ blend_mode_box->add_combo_item(tr("Normal"), -1);
- // set up gizmos
- top_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
- top_left_gizmo->set_cursor(Qt::SizeFDiagCursor);
- top_left_gizmo->x_field1 = scale_x;
+ // add loaded blending modes
+ for (int i=0;iadd_combo_item(olive::blend_modes.at(i).name, i);
+ }
- top_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
- top_center_gizmo->set_cursor(Qt::SizeVerCursor);
- top_center_gizmo->y_field1 = scale_x;
+ // set up gizmos
+ top_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
+ top_left_gizmo->set_cursor(Qt::SizeFDiagCursor);
+ top_left_gizmo->x_field1 = scale_x;
- top_right_gizmo = add_gizmo(GIZMO_TYPE_DOT);
- top_right_gizmo->set_cursor(Qt::SizeBDiagCursor);
- top_right_gizmo->x_field1 = scale_x;
+ top_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
+ top_center_gizmo->set_cursor(Qt::SizeVerCursor);
+ top_center_gizmo->y_field1 = scale_x;
- bottom_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
- bottom_left_gizmo->set_cursor(Qt::SizeBDiagCursor);
- bottom_left_gizmo->x_field1 = scale_x;
+ top_right_gizmo = add_gizmo(GIZMO_TYPE_DOT);
+ top_right_gizmo->set_cursor(Qt::SizeBDiagCursor);
+ top_right_gizmo->x_field1 = scale_x;
- bottom_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
- bottom_center_gizmo->set_cursor(Qt::SizeVerCursor);
- bottom_center_gizmo->y_field1 = scale_x;
+ bottom_left_gizmo = add_gizmo(GIZMO_TYPE_DOT);
+ bottom_left_gizmo->set_cursor(Qt::SizeBDiagCursor);
+ bottom_left_gizmo->x_field1 = scale_x;
- bottom_right_gizmo = add_gizmo(GIZMO_TYPE_DOT);
- bottom_right_gizmo->set_cursor(Qt::SizeFDiagCursor);
- bottom_right_gizmo->x_field1 = scale_x;
+ bottom_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
+ bottom_center_gizmo->set_cursor(Qt::SizeVerCursor);
+ bottom_center_gizmo->y_field1 = scale_x;
- left_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
- left_center_gizmo->set_cursor(Qt::SizeHorCursor);
- left_center_gizmo->x_field1 = scale_x;
+ bottom_right_gizmo = add_gizmo(GIZMO_TYPE_DOT);
+ bottom_right_gizmo->set_cursor(Qt::SizeFDiagCursor);
+ bottom_right_gizmo->x_field1 = scale_x;
- right_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
- right_center_gizmo->set_cursor(Qt::SizeHorCursor);
- right_center_gizmo->x_field1 = scale_x;
+ left_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
+ left_center_gizmo->set_cursor(Qt::SizeHorCursor);
+ left_center_gizmo->x_field1 = scale_x;
- anchor_gizmo = add_gizmo(GIZMO_TYPE_TARGET);
- anchor_gizmo->set_cursor(Qt::SizeAllCursor);
- anchor_gizmo->x_field1 = anchor_x_box;
- anchor_gizmo->y_field1 = anchor_y_box;
- anchor_gizmo->x_field2 = position_x;
- anchor_gizmo->y_field2 = position_y;
+ right_center_gizmo = add_gizmo(GIZMO_TYPE_DOT);
+ right_center_gizmo->set_cursor(Qt::SizeHorCursor);
+ right_center_gizmo->x_field1 = scale_x;
- rotate_gizmo = add_gizmo(GIZMO_TYPE_DOT);
- rotate_gizmo->color = Qt::green;
- rotate_gizmo->set_cursor(Qt::SizeAllCursor);
- rotate_gizmo->x_field1 = rotation;
+ anchor_gizmo = add_gizmo(GIZMO_TYPE_TARGET);
+ anchor_gizmo->set_cursor(Qt::SizeAllCursor);
+ anchor_gizmo->x_field1 = anchor_x_box;
+ anchor_gizmo->y_field1 = anchor_y_box;
+ anchor_gizmo->x_field2 = position_x;
+ anchor_gizmo->y_field2 = position_y;
- rect_gizmo = add_gizmo(GIZMO_TYPE_POLY);
- rect_gizmo->x_field1 = position_x;
- rect_gizmo->y_field1 = position_y;
+ rotate_gizmo = add_gizmo(GIZMO_TYPE_DOT);
+ rotate_gizmo->color = Qt::green;
+ rotate_gizmo->set_cursor(Qt::SizeAllCursor);
+ rotate_gizmo->x_field1 = rotation;
- connect(uniform_scale_field, SIGNAL(toggled(bool)), this, SLOT(toggle_uniform_scale(bool)));
+ rect_gizmo = add_gizmo(GIZMO_TYPE_POLY);
+ rect_gizmo->x_field1 = position_x;
+ rect_gizmo->y_field1 = position_y;
- // set defaults
- uniform_scale_field->set_bool_value(true);
- blend_mode_box->set_combo_index(0);
- set = false;
- refresh();
+ connect(uniform_scale_field, SIGNAL(toggled(bool)), this, SLOT(toggle_uniform_scale(bool)));
+
+ // set defaults
+ uniform_scale_field->set_bool_value(true);
+ blend_mode_box->set_combo_index(0);
+ set = false;
+ refresh();
}
void adjust_field(EffectField* field, double old_offset, double new_offset) {
- if (field->keyframes.size() > 0) {
- for (int i=0;ikeyframes.size();i++) {
- field->keyframes[i].data = field->keyframes.at(i).data.toDouble() - old_offset + new_offset;
- }
- } else {
- field->set_current_data(field->get_current_data().toDouble() - old_offset + new_offset);
- }
+ if (field->keyframes.size() > 0) {
+ for (int i=0;ikeyframes.size();i++) {
+ field->keyframes[i].data = field->keyframes.at(i).data.toDouble() - old_offset + new_offset;
+ }
+ } else {
+ field->set_current_data(field->get_current_data().toDouble() - old_offset + new_offset);
+ }
}
void TransformEffect::refresh() {
- if (parent_clip != nullptr && parent_clip->sequence != nullptr) {
- double new_default_pos_x = parent_clip->sequence->width/2;
- double new_default_pos_y = parent_clip->sequence->height/2;
+ if (parent_clip != nullptr && parent_clip->sequence != nullptr) {
+ double new_default_pos_x = parent_clip->sequence->width/2;
+ double new_default_pos_y = parent_clip->sequence->height/2;
- /*if (set) {
- adjust_field(position_x, default_pos_x, new_default_pos_x);
- adjust_field(position_y, default_pos_y, new_default_pos_y);
- }*/
+ /*if (set) {
+ adjust_field(position_x, default_pos_x, new_default_pos_x);
+ adjust_field(position_y, default_pos_y, new_default_pos_y);
+ }*/
- double default_pos_x = new_default_pos_x;
- double default_pos_y = new_default_pos_y;
+ double default_pos_x = new_default_pos_x;
+ double default_pos_y = new_default_pos_y;
- position_x->set_double_default_value(default_pos_x);
- position_y->set_double_default_value(default_pos_y);
- scale_x->set_double_default_value(100);
- scale_y->set_double_default_value(100);
+ position_x->set_double_default_value(default_pos_x);
+ position_y->set_double_default_value(default_pos_y);
+ scale_x->set_double_default_value(100);
+ scale_y->set_double_default_value(100);
- anchor_x_box->set_double_default_value(0);
- anchor_y_box->set_double_default_value(0);
- opacity->set_double_default_value(100);
+ anchor_x_box->set_double_default_value(0);
+ anchor_y_box->set_double_default_value(0);
+ opacity->set_double_default_value(100);
- double x_percent_multipler = 200.0 / parent_clip->sequence->width;
- double y_percent_multipler = 200.0 / parent_clip->sequence->height;
- top_left_gizmo->x_field_multi1 = -x_percent_multipler;
- top_left_gizmo->y_field_multi1 = -y_percent_multipler;
- top_center_gizmo->y_field_multi1 = -y_percent_multipler;
- top_right_gizmo->x_field_multi1 = x_percent_multipler;
- top_right_gizmo->y_field_multi1 = -y_percent_multipler;
- bottom_left_gizmo->x_field_multi1 = -x_percent_multipler;
- bottom_left_gizmo->y_field_multi1 = y_percent_multipler;
- bottom_center_gizmo->y_field_multi1 = y_percent_multipler;
- bottom_right_gizmo->x_field_multi1 = x_percent_multipler;
- bottom_right_gizmo->y_field_multi1 = y_percent_multipler;
- left_center_gizmo->x_field_multi1 = -x_percent_multipler;
- right_center_gizmo->x_field_multi1 = x_percent_multipler;
- rotate_gizmo->x_field_multi1 = x_percent_multipler;
+ double x_percent_multipler = 200.0 / parent_clip->sequence->width;
+ double y_percent_multipler = 200.0 / parent_clip->sequence->height;
+ top_left_gizmo->x_field_multi1 = -x_percent_multipler;
+ top_left_gizmo->y_field_multi1 = -y_percent_multipler;
+ top_center_gizmo->y_field_multi1 = -y_percent_multipler;
+ top_right_gizmo->x_field_multi1 = x_percent_multipler;
+ top_right_gizmo->y_field_multi1 = -y_percent_multipler;
+ bottom_left_gizmo->x_field_multi1 = -x_percent_multipler;
+ bottom_left_gizmo->y_field_multi1 = y_percent_multipler;
+ bottom_center_gizmo->y_field_multi1 = y_percent_multipler;
+ bottom_right_gizmo->x_field_multi1 = x_percent_multipler;
+ bottom_right_gizmo->y_field_multi1 = y_percent_multipler;
+ left_center_gizmo->x_field_multi1 = -x_percent_multipler;
+ right_center_gizmo->x_field_multi1 = x_percent_multipler;
+ rotate_gizmo->x_field_multi1 = x_percent_multipler;
- set = true;
- }
+ set = true;
+ }
}
void TransformEffect::toggle_uniform_scale(bool enabled) {
- scale_y->set_enabled(!enabled);
+ scale_y->set_enabled(!enabled);
- top_center_gizmo->y_field1 = enabled ? scale_x : scale_y;
- bottom_center_gizmo->y_field1 = enabled ? scale_x : scale_y;
- top_left_gizmo->y_field1 = enabled ? nullptr : scale_y;
- top_right_gizmo->y_field1 = enabled ? nullptr : scale_y;
- bottom_left_gizmo->y_field1 = enabled ? nullptr : scale_y;
- bottom_right_gizmo->y_field1 = enabled ? nullptr : scale_y;
+ top_center_gizmo->y_field1 = enabled ? scale_x : scale_y;
+ bottom_center_gizmo->y_field1 = enabled ? scale_x : scale_y;
+ top_left_gizmo->y_field1 = enabled ? nullptr : scale_y;
+ top_right_gizmo->y_field1 = enabled ? nullptr : scale_y;
+ bottom_left_gizmo->y_field1 = enabled ? nullptr : scale_y;
+ bottom_right_gizmo->y_field1 = enabled ? nullptr : scale_y;
}
void TransformEffect::process_coords(double timecode, GLTextureCoords& coords, int) {
- // position
- glTranslated(position_x->get_double_value(timecode)-(parent_clip->sequence->width/2), position_y->get_double_value(timecode)-(parent_clip->sequence->height/2), 0);
+ // position
+ glTranslated(position_x->get_double_value(timecode)-(parent_clip->sequence->width/2), position_y->get_double_value(timecode)-(parent_clip->sequence->height/2), 0);
- // anchor point
- int anchor_x_offset = qRound(anchor_x_box->get_double_value(timecode));
- int anchor_y_offset = qRound(anchor_y_box->get_double_value(timecode));
- coords.vertexTopLeftX -= anchor_x_offset;
- coords.vertexTopRightX -= anchor_x_offset;
- coords.vertexBottomLeftX -= anchor_x_offset;
- coords.vertexBottomRightX -= anchor_x_offset;
- coords.vertexTopLeftY -= anchor_y_offset;
- coords.vertexTopRightY -= anchor_y_offset;
- coords.vertexBottomLeftY -= anchor_y_offset;
- coords.vertexBottomRightY -= anchor_y_offset;
+ // anchor point
+ int anchor_x_offset = qRound(anchor_x_box->get_double_value(timecode));
+ int anchor_y_offset = qRound(anchor_y_box->get_double_value(timecode));
+ coords.vertexTopLeftX -= anchor_x_offset;
+ coords.vertexTopRightX -= anchor_x_offset;
+ coords.vertexBottomLeftX -= anchor_x_offset;
+ coords.vertexBottomRightX -= anchor_x_offset;
+ coords.vertexTopLeftY -= anchor_y_offset;
+ coords.vertexTopRightY -= anchor_y_offset;
+ coords.vertexBottomLeftY -= anchor_y_offset;
+ coords.vertexBottomRightY -= anchor_y_offset;
- // rotation
- glRotated(rotation->get_double_value(timecode), 0, 0, 1);
+ // rotation
+ glRotated(rotation->get_double_value(timecode), 0, 0, 1);
- // scale
- double sx = scale_x->get_double_value(timecode)*0.01;
- double sy = (uniform_scale_field->get_bool_value(timecode)) ? sx : scale_y->get_double_value(timecode)*0.01;
- glScaled(sx, sy, 1);
+ // scale
+ double sx = scale_x->get_double_value(timecode)*0.01;
+ double sy = (uniform_scale_field->get_bool_value(timecode)) ? sx : scale_y->get_double_value(timecode)*0.01;
+ glScaled(sx, sy, 1);
- // blend mode
- coords.blendmode = blend_mode_box->get_combo_data(timecode).toInt();
+ // blend mode
+ coords.blendmode = blend_mode_box->get_combo_data(timecode).toInt();
- // opacity
- coords.opacity *= float(opacity->get_double_value(timecode)*0.01);
+ // opacity
+ coords.opacity *= float(opacity->get_double_value(timecode)*0.01);
}
void TransformEffect::gizmo_draw(double, GLTextureCoords& coords) {
- top_left_gizmo->world_pos[0] = QPoint(coords.vertexTopLeftX, coords.vertexTopLeftY);
- top_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexTopLeftX, coords.vertexTopRightX, 0.5), lerp(coords.vertexTopLeftY, coords.vertexTopRightY, 0.5));
- top_right_gizmo->world_pos[0] = QPoint(coords.vertexTopRightX, coords.vertexTopRightY);
- right_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexTopRightX, coords.vertexBottomRightX, 0.5), lerp(coords.vertexTopRightY, coords.vertexBottomRightY, 0.5));
- bottom_right_gizmo->world_pos[0] = QPoint(coords.vertexBottomRightX, coords.vertexBottomRightY);
- bottom_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexBottomRightX, coords.vertexBottomLeftX, 0.5), lerp(coords.vertexBottomRightY, coords.vertexBottomLeftY, 0.5));
- bottom_left_gizmo->world_pos[0] = QPoint(coords.vertexBottomLeftX, coords.vertexBottomLeftY);
- left_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexBottomLeftX, coords.vertexTopLeftX, 0.5), lerp(coords.vertexBottomLeftY, coords.vertexTopLeftY, 0.5));
+ top_left_gizmo->world_pos[0] = QPoint(coords.vertexTopLeftX, coords.vertexTopLeftY);
+ top_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexTopLeftX, coords.vertexTopRightX, 0.5), lerp(coords.vertexTopLeftY, coords.vertexTopRightY, 0.5));
+ top_right_gizmo->world_pos[0] = QPoint(coords.vertexTopRightX, coords.vertexTopRightY);
+ right_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexTopRightX, coords.vertexBottomRightX, 0.5), lerp(coords.vertexTopRightY, coords.vertexBottomRightY, 0.5));
+ bottom_right_gizmo->world_pos[0] = QPoint(coords.vertexBottomRightX, coords.vertexBottomRightY);
+ bottom_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexBottomRightX, coords.vertexBottomLeftX, 0.5), lerp(coords.vertexBottomRightY, coords.vertexBottomLeftY, 0.5));
+ bottom_left_gizmo->world_pos[0] = QPoint(coords.vertexBottomLeftX, coords.vertexBottomLeftY);
+ left_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexBottomLeftX, coords.vertexTopLeftX, 0.5), lerp(coords.vertexBottomLeftY, coords.vertexTopLeftY, 0.5));
- rotate_gizmo->world_pos[0] = QPoint(lerp(top_center_gizmo->world_pos[0].x(), bottom_center_gizmo->world_pos[0].x(), -0.1), lerp(top_center_gizmo->world_pos[0].y(), bottom_center_gizmo->world_pos[0].y(), -0.1));
+ rotate_gizmo->world_pos[0] = QPoint(lerp(top_center_gizmo->world_pos[0].x(), bottom_center_gizmo->world_pos[0].x(), -0.1), lerp(top_center_gizmo->world_pos[0].y(), bottom_center_gizmo->world_pos[0].y(), -0.1));
- rect_gizmo->world_pos[0] = QPoint(coords.vertexTopLeftX, coords.vertexTopLeftY);
- rect_gizmo->world_pos[1] = QPoint(coords.vertexTopRightX, coords.vertexTopRightY);
- rect_gizmo->world_pos[2] = QPoint(coords.vertexBottomRightX, coords.vertexBottomRightY);
- rect_gizmo->world_pos[3] = QPoint(coords.vertexBottomLeftX, coords.vertexBottomLeftY);
+ rect_gizmo->world_pos[0] = QPoint(coords.vertexTopLeftX, coords.vertexTopLeftY);
+ rect_gizmo->world_pos[1] = QPoint(coords.vertexTopRightX, coords.vertexTopRightY);
+ rect_gizmo->world_pos[2] = QPoint(coords.vertexBottomRightX, coords.vertexBottomRightY);
+ rect_gizmo->world_pos[3] = QPoint(coords.vertexBottomLeftX, coords.vertexBottomLeftY);
}
diff --git a/effects/multiply.blend b/effects/multiply.blend
new file mode 100644
index 000000000..0da71e49d
--- /dev/null
+++ b/effects/multiply.blend
@@ -0,0 +1,9 @@
+vec3 blendMultiply(vec3 base, vec3 blend) {
+ return base*blend;
+}
+
+vec3 blendMultiply(vec3 base, vec3 blend, float opacity) {
+ return (blendMultiply(base, blend) * opacity + base * (1.0 - opacity));
+}
+
+#pragma glslify: export(blendMultiply)
\ No newline at end of file
diff --git a/io/config.cpp b/io/config.cpp
index 5b09d877b..1490ddcbd 100644
--- a/io/config.cpp
+++ b/io/config.cpp
@@ -285,6 +285,5 @@ void Config::save(QString path) {
}
RuntimeConfig::RuntimeConfig() :
- shaders_are_enabled(true),
- disable_blending(false)
+ shaders_are_enabled(true)
{}
diff --git a/io/config.h b/io/config.h
index a83eb30d7..c9fc41d92 100644
--- a/io/config.h
+++ b/io/config.h
@@ -561,14 +561,6 @@ struct RuntimeConfig {
*/
bool shaders_are_enabled;
- /**
- * @brief Disable blending modes
- *
- * Some users had difficulty utilizing blending modes (provided by shaders). Set this to **TRUE** to bypass
- * shader-based blending modes and utilize standard (less versatile) OpenGL blending instead.
- */
- bool disable_blending;
-
/**
* @brief Load an external translation file
*
diff --git a/main.cpp b/main.cpp
index 69f99ee5e..e36f50fe0 100644
--- a/main.cpp
+++ b/main.cpp
@@ -34,7 +34,7 @@ extern "C" {
#include
}
-int main(int argc, char *argv[]) {
+int main(int argc, char *argv[]) {
olive::Global = std::unique_ptr(new OliveGlobal);
bool launch_fullscreen = false;
@@ -60,7 +60,6 @@ int main(int argc, char *argv[]) {
"\t-f, --fullscreen\tStart in full screen mode\n"
"\t--disable-shaders\tDisable OpenGL shaders (for debugging)\n"
"\t--no-debug\t\tDisable internal debug log and output directly to console\n"
- "\t--disable-blend-modes\tDisable shader-based blending for older GPUs\n"
"\t--translation \tSet an external language file to use\n"
"\n"
"Environment Variables:\n"
@@ -75,8 +74,6 @@ int main(int argc, char *argv[]) {
olive::CurrentRuntimeConfig.shaders_are_enabled = false;
} else if (!strcmp(argv[i], "--no-debug")) {
use_internal_logger = false;
- } else if (!strcmp(argv[i], "--disable-blend-modes")) {
- olive::CurrentRuntimeConfig.disable_blending = true;
} else if (!strcmp(argv[i], "--translation")) {
if (i + 1 < argc && argv[i + 1][0] != '-') {
// load translation file
diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp
index 174baa795..1f0088ed1 100644
--- a/panels/effectcontrols.cpp
+++ b/panels/effectcontrols.cpp
@@ -199,8 +199,8 @@ void EffectControls::show_effect_menu(int type, int subtype) {
QMenu effects_menu(this);
effects_menu.setToolTipsVisible(true);
- for (int i=0;isetObjectName("v");
@@ -1803,8 +1803,8 @@ void Timeline::transition_tool_click() {
transition_menu.addSeparator();
- for (int i=0;isetObjectName("a");
diff --git a/project/effect.cpp b/project/effect.cpp
index a49ae6977..4cf2bdc22 100644
--- a/project/effect.cpp
+++ b/project/effect.cpp
@@ -67,12 +67,13 @@
#include
#include
-QVector effects;
+QVector olive::effects;
+QVector olive::blend_modes;
EffectPtr Effect::Create(Clip* c, const EffectMeta* em) {
- if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) {
- // must be an internal effect
- switch (em->internal) {
+ if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) {
+ // must be an internal effect
+ switch (em->internal) {
case EFFECT_INTERNAL_TRANSFORM: return EffectPtr(new TransformEffect(c, em));
case EFFECT_INTERNAL_TEXT: return EffectPtr(new TextEffect(c, em));
case EFFECT_INTERNAL_TIMECODE: return EffectPtr(new TimecodeEffect(c, em));
@@ -90,851 +91,851 @@ EffectPtr Effect::Create(Clip* c, const EffectMeta* em) {
#ifndef NOFREI0R
case EFFECT_INTERNAL_FREI0R: return EffectPtr(new Frei0rEffect(c, em));
#endif
- }
- } else if (!em->filename.isEmpty()) {
- // load effect from file
+ }
+ } else if (!em->filename.isEmpty()) {
+ // load effect from file
return EffectPtr(new Effect(c, em));
- } else {
- qCritical() << "Invalid effect data";
+ } else {
+ qCritical() << "Invalid effect data";
QMessageBox::critical(olive::MainWindow,
- QCoreApplication::translate("Effect", "Invalid effect"),
- QCoreApplication::translate("Effect", "No candidate for effect '%1'. This effect may be corrupt. Try reinstalling it or Olive.").arg(em->name));
- }
- return nullptr;
+ QCoreApplication::translate("Effect", "Invalid effect"),
+ QCoreApplication::translate("Effect", "No candidate for effect '%1'. This effect may be corrupt. Try reinstalling it or Olive.").arg(em->name));
+ }
+ return nullptr;
}
const EffectMeta* Effect::GetInternalMeta(int internal_id, int type) {
- for (int i=0;ienabled_check, SIGNAL(clicked(bool)), this, SLOT(field_changed()));
- ui = new QWidget(container);
- ui_layout = new QGridLayout(ui);
- ui_layout->setSpacing(4);
- container->setContents(ui);
+ // set up base UI
+ container = new CollapsibleWidget();
+ connect(container->enabled_check, SIGNAL(clicked(bool)), this, SLOT(field_changed()));
+ ui = new QWidget(container);
+ ui_layout = new QGridLayout(ui);
+ ui_layout->setSpacing(4);
+ container->setContents(ui);
- connect(container->title_bar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&)));
+ connect(container->title_bar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu(const QPoint&)));
- if (em != nullptr) {
- // set up UI from effect file
- container->setText(em->name);
+ if (em != nullptr) {
+ // set up UI from effect file
+ container->setText(em->name);
- if (!em->filename.isEmpty() && em->internal == -1) {
- QFile effect_file(em->filename);
- if (effect_file.open(QFile::ReadOnly)) {
- QXmlStreamReader reader(&effect_file);
+ if (!em->filename.isEmpty() && em->internal == -1) {
+ QFile effect_file(em->filename);
+ if (effect_file.open(QFile::ReadOnly)) {
+ QXmlStreamReader reader(&effect_file);
- while (!reader.atEnd()) {
- if (reader.name() == "row" && reader.isStartElement()) {
- QString row_name;
- const QXmlStreamAttributes& attributes = reader.attributes();
- for (int i=0;ifilename << "- ID cannot be empty.";
- } else if (type > -1) {
- EffectField* field = row->add_field(type, id);
- connect(field, SIGNAL(changed()), this, SLOT(field_changed()));
- switch (type) {
- case EFFECT_FIELD_DOUBLE:
- for (int i=0;iset_double_default_value(attr.value().toDouble());
- } else if (attr.name() == "min") {
- field->set_double_minimum_value(attr.value().toDouble());
- } else if (attr.name() == "max") {
- field->set_double_maximum_value(attr.value().toDouble());
- }
- }
- break;
- case EFFECT_FIELD_COLOR:
- {
- QColor color;
- for (int i=0;iset_color_value(color);
- }
- break;
- case EFFECT_FIELD_STRING:
- for (int i=0;iset_string_value(attr.value().toString());
- }
- }
- break;
- case EFFECT_FIELD_BOOL:
- for (int i=0;iset_bool_value(attr.value() == "1");
- }
- }
- break;
- case EFFECT_FIELD_COMBO:
- {
- int combo_index = 0;
- for (int i=0;iadd_combo_item(reader.text().toString(), 0);
- }
- }
- field->set_combo_index(combo_index);
- }
- break;
- case EFFECT_FIELD_FONT:
- for (int i=0;iset_font_name(attr.value().toString());
- }
- }
- break;
- case EFFECT_FIELD_FILE:
- for (int i=0;iset_filename(attr.value().toString());
- }
- }
- break;
- }
- }
- }
- }
- }
- } else if (reader.name() == "shader" && reader.isStartElement()) {
- enable_shader = true;
- const QXmlStreamAttributes& attributes = reader.attributes();
- for (int i=0;ifilename;
- enable_superimpose = false;
- }
- break;
- }
- }
- }*/
- reader.readNext();
- }
+ if (id.isEmpty()) {
+ qCritical() << "Couldn't load field from" << em->filename << "- ID cannot be empty.";
+ } else if (type > -1) {
+ EffectField* field = row->add_field(type, id);
+ connect(field, SIGNAL(changed()), this, SLOT(field_changed()));
+ switch (type) {
+ case EFFECT_FIELD_DOUBLE:
+ for (int i=0;iset_double_default_value(attr.value().toDouble());
+ } else if (attr.name() == "min") {
+ field->set_double_minimum_value(attr.value().toDouble());
+ } else if (attr.name() == "max") {
+ field->set_double_maximum_value(attr.value().toDouble());
+ }
+ }
+ break;
+ case EFFECT_FIELD_COLOR:
+ {
+ QColor color;
+ for (int i=0;iset_color_value(color);
+ }
+ break;
+ case EFFECT_FIELD_STRING:
+ for (int i=0;iset_string_value(attr.value().toString());
+ }
+ }
+ break;
+ case EFFECT_FIELD_BOOL:
+ for (int i=0;iset_bool_value(attr.value() == "1");
+ }
+ }
+ break;
+ case EFFECT_FIELD_COMBO:
+ {
+ int combo_index = 0;
+ for (int i=0;iadd_combo_item(reader.text().toString(), 0);
+ }
+ }
+ field->set_combo_index(combo_index);
+ }
+ break;
+ case EFFECT_FIELD_FONT:
+ for (int i=0;iset_font_name(attr.value().toString());
+ }
+ }
+ break;
+ case EFFECT_FIELD_FILE:
+ for (int i=0;iset_filename(attr.value().toString());
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ } else if (reader.name() == "shader" && reader.isStartElement()) {
+ enable_shader = true;
+ const QXmlStreamAttributes& attributes = reader.attributes();
+ for (int i=0;ifilename;
+ enable_superimpose = false;
+ }
+ break;
+ }
+ }
+ }*/
+ reader.readNext();
+ }
- effect_file.close();
- } else {
- qCritical() << "Failed to open effect file" << em->filename;
- }
- }
- }
+ effect_file.close();
+ } else {
+ qCritical() << "Failed to open effect file" << em->filename;
+ }
+ }
+ }
}
Effect::~Effect() {
- if (isOpen) {
- close();
- }
+ if (isOpen) {
+ close();
+ }
- delete container;
+ delete container;
- for (int i=0;irows.at(i);
- copy_row->setKeyframing(row->isKeyframing());
- for (int j=0;jfieldCount();j++) {
- EffectField* field = row->field(j);
- EffectField* copy_field = copy_row->field(j);
- copy_field->keyframes = field->keyframes;
- copy_field->set_current_data(field->get_current_data());
- }
- }
+ for (int i=0;irows.at(i);
+ copy_row->setKeyframing(row->isKeyframing());
+ for (int j=0;jfieldCount();j++) {
+ EffectField* field = row->field(j);
+ EffectField* copy_field = copy_row->field(j);
+ copy_field->keyframes = field->keyframes;
+ copy_field->set_current_data(field->get_current_data());
+ }
+ }
}
EffectRow* Effect::add_row(const QString& name, bool savable, bool keyframable) {
- EffectRow* row = new EffectRow(this, savable, ui_layout, name, rows.size(), keyframable);
- rows.append(row);
- return row;
+ EffectRow* row = new EffectRow(this, savable, ui_layout, name, rows.size(), keyframable);
+ rows.append(row);
+ return row;
}
EffectRow* Effect::row(int i) {
- return rows.at(i);
+ return rows.at(i);
}
int Effect::row_count() {
- return rows.size();
+ return rows.size();
}
EffectGizmo *Effect::add_gizmo(int type) {
- EffectGizmo* gizmo = new EffectGizmo(type);
- gizmos.append(gizmo);
- return gizmo;
+ EffectGizmo* gizmo = new EffectGizmo(type);
+ gizmos.append(gizmo);
+ return gizmo;
}
EffectGizmo *Effect::gizmo(int i) {
- return gizmos.at(i);
+ return gizmos.at(i);
}
int Effect::gizmo_count() {
- return gizmos.size();
+ return gizmos.size();
}
void Effect::refresh() {}
void Effect::field_changed() {
- panel_sequence_viewer->viewer_widget->frame_update();
- panel_graph_editor->update_panel();
+ panel_sequence_viewer->viewer_widget->frame_update();
+ panel_graph_editor->update_panel();
}
void Effect::show_context_menu(const QPoint& pos) {
- if (meta->type == EFFECT_TYPE_EFFECT) {
+ if (meta->type == EFFECT_TYPE_EFFECT) {
QMenu menu(olive::MainWindow);
- int index = get_index_in_clip();
+ int index = get_index_in_clip();
- menu.addAction(tr("Cu&t"), panel_effect_controls, SLOT(cut()));
- menu.addAction(tr("&Copy"), panel_effect_controls, SLOT(copy(bool)));
+ menu.addAction(tr("Cu&t"), panel_effect_controls, SLOT(cut()));
+ menu.addAction(tr("&Copy"), panel_effect_controls, SLOT(copy(bool)));
- panel_effect_controls->add_effect_paste_action(&menu);
+ panel_effect_controls->add_effect_paste_action(&menu);
- menu.addSeparator();
+ menu.addSeparator();
- if (index > 0) {
- menu.addAction(tr("Move &Up"), this, SLOT(move_up()));
- }
+ if (index > 0) {
+ menu.addAction(tr("Move &Up"), this, SLOT(move_up()));
+ }
- if (index < parent_clip->effects.size() - 1) {
- menu.addAction(tr("Move &Down"), this, SLOT(move_down()));
- }
+ if (index < parent_clip->effects.size() - 1) {
+ menu.addAction(tr("Move &Down"), this, SLOT(move_down()));
+ }
- menu.addSeparator();
+ menu.addSeparator();
- menu.addAction(tr("D&elete"), this, SLOT(delete_self()));
+ menu.addAction(tr("D&elete"), this, SLOT(delete_self()));
- menu.addSeparator();
+ menu.addSeparator();
- menu.addAction(tr("Load Settings From File"), this, SLOT(load_from_file()));
+ menu.addAction(tr("Load Settings From File"), this, SLOT(load_from_file()));
- menu.addAction(tr("Save Settings to File"), this, SLOT(save_to_file()));
+ menu.addAction(tr("Save Settings to File"), this, SLOT(save_to_file()));
- menu.exec(container->title_bar->mapToGlobal(pos));
- }
+ menu.exec(container->title_bar->mapToGlobal(pos));
+ }
}
void Effect::delete_self() {
- EffectDeleteCommand* command = new EffectDeleteCommand();
- command->clips.append(parent_clip);
- command->fx.append(get_index_in_clip());
- olive::UndoStack.push(command);
- update_ui(true);
+ EffectDeleteCommand* command = new EffectDeleteCommand();
+ command->clips.append(parent_clip);
+ command->fx.append(get_index_in_clip());
+ olive::UndoStack.push(command);
+ update_ui(true);
}
void Effect::move_up() {
- MoveEffectCommand* command = new MoveEffectCommand();
- command->clip = parent_clip;
- command->from = get_index_in_clip();
- command->to = command->from - 1;
- olive::UndoStack.push(command);
- panel_effect_controls->reload_clips();
- panel_sequence_viewer->viewer_widget->frame_update();
+ MoveEffectCommand* command = new MoveEffectCommand();
+ command->clip = parent_clip;
+ command->from = get_index_in_clip();
+ command->to = command->from - 1;
+ olive::UndoStack.push(command);
+ panel_effect_controls->reload_clips();
+ panel_sequence_viewer->viewer_widget->frame_update();
}
void Effect::move_down() {
- MoveEffectCommand* command = new MoveEffectCommand();
- command->clip = parent_clip;
- command->from = get_index_in_clip();
- command->to = command->from + 1;
- olive::UndoStack.push(command);
- panel_effect_controls->reload_clips();
- panel_sequence_viewer->viewer_widget->frame_update();
+ MoveEffectCommand* command = new MoveEffectCommand();
+ command->clip = parent_clip;
+ command->from = get_index_in_clip();
+ command->to = command->from + 1;
+ olive::UndoStack.push(command);
+ panel_effect_controls->reload_clips();
+ panel_sequence_viewer->viewer_widget->frame_update();
}
void Effect::save_to_file() {
- // save effect settings to file
+ // save effect settings to file
QString file = QFileDialog::getSaveFileName(olive::MainWindow,
- tr("Save Effect Settings"),
- QString(),
- tr("Effect XML Settings %1").arg("(*.xml)"));
+ tr("Save Effect Settings"),
+ QString(),
+ tr("Effect XML Settings %1").arg("(*.xml)"));
- // if the user picked a file
- if (!file.isEmpty()) {
+ // if the user picked a file
+ if (!file.isEmpty()) {
// ensure file ends with .xml extension
if (!file.endsWith(".xml", Qt::CaseInsensitive)) {
file.append(".xml");
}
- QFile file_handle(file);
- if (file_handle.open(QFile::WriteOnly)) {
+ QFile file_handle(file);
+ if (file_handle.open(QFile::WriteOnly)) {
- file_handle.write(save_to_string());
+ file_handle.write(save_to_string());
- file_handle.close();
- } else {
+ file_handle.close();
+ } else {
QMessageBox::critical(olive::MainWindow,
- tr("Save Settings Failed"),
- tr("Failed to open \"%1\" for writing.").arg(file),
- QMessageBox::Ok);
- }
- }
+ tr("Save Settings Failed"),
+ tr("Failed to open \"%1\" for writing.").arg(file),
+ QMessageBox::Ok);
+ }
+ }
}
void Effect::load_from_file() {
- // load effect settings from file
+ // load effect settings from file
QString file = QFileDialog::getOpenFileName(olive::MainWindow,
- tr("Load Effect Settings"),
- QString(),
- tr("Effect XML Settings %1").arg("(*.xml)"));
+ tr("Load Effect Settings"),
+ QString(),
+ tr("Effect XML Settings %1").arg("(*.xml)"));
- // if the user picked a file
- if (!file.isEmpty()) {
- QFile file_handle(file);
- if (file_handle.open(QFile::ReadOnly)) {
+ // if the user picked a file
+ if (!file.isEmpty()) {
+ QFile file_handle(file);
+ if (file_handle.open(QFile::ReadOnly)) {
olive::UndoStack.push(new SetEffectData(EffectPtr(this), file_handle.readAll()));
- file_handle.close();
+ file_handle.close();
- update_ui(false);
- } else {
+ update_ui(false);
+ } else {
QMessageBox::critical(olive::MainWindow,
- tr("Load Settings Failed"),
- tr("Failed to open \"%1\" for reading.").arg(file),
- QMessageBox::Ok);
- }
- }
+ tr("Load Settings Failed"),
+ tr("Failed to open \"%1\" for reading.").arg(file),
+ QMessageBox::Ok);
+ }
+ }
}
int Effect::get_index_in_clip() {
- if (parent_clip != nullptr) {
- for (int i=0;ieffects.size();i++) {
+ if (parent_clip != nullptr) {
+ for (int i=0;ieffects.size();i++) {
if (parent_clip->effects.at(i).get() == this) {
- return i;
- }
- }
- }
- return -1;
+ return i;
+ }
+ }
+ }
+ return -1;
}
bool Effect::is_enabled() {
- return container->enabled_check->isChecked();
+ return container->enabled_check->isChecked();
}
void Effect::set_enabled(bool b) {
- container->enabled_check->setChecked(b);
+ container->enabled_check->setChecked(b);
}
QVariant load_data_from_string(int type, const QString& string) {
- switch (type) {
- case EFFECT_FIELD_DOUBLE: return string.toDouble();
- case EFFECT_FIELD_COLOR: return QColor(string);
- case EFFECT_FIELD_BOOL: return (string == "1");
- case EFFECT_FIELD_COMBO: return string.toInt();
- case EFFECT_FIELD_STRING:
- case EFFECT_FIELD_FONT:
- case EFFECT_FIELD_FILE:
- return string;
- }
- return QVariant();
+ switch (type) {
+ case EFFECT_FIELD_DOUBLE: return string.toDouble();
+ case EFFECT_FIELD_COLOR: return QColor(string);
+ case EFFECT_FIELD_BOOL: return (string == "1");
+ case EFFECT_FIELD_COMBO: return string.toInt();
+ case EFFECT_FIELD_STRING:
+ case EFFECT_FIELD_FONT:
+ case EFFECT_FIELD_FILE:
+ return string;
+ }
+ return QVariant();
}
QString save_data_to_string(int type, const QVariant& data) {
- switch (type) {
- case EFFECT_FIELD_DOUBLE: return QString::number(data.toDouble());
- case EFFECT_FIELD_COLOR: return data.value().name();
- case EFFECT_FIELD_BOOL: return QString::number(data.toBool());
- case EFFECT_FIELD_COMBO: return QString::number(data.toInt());
- case EFFECT_FIELD_STRING:
- case EFFECT_FIELD_FONT:
- case EFFECT_FIELD_FILE:
- return data.toString();
- }
- return QString();
+ switch (type) {
+ case EFFECT_FIELD_DOUBLE: return QString::number(data.toDouble());
+ case EFFECT_FIELD_COLOR: return data.value().name();
+ case EFFECT_FIELD_BOOL: return QString::number(data.toBool());
+ case EFFECT_FIELD_COMBO: return QString::number(data.toInt());
+ case EFFECT_FIELD_STRING:
+ case EFFECT_FIELD_FONT:
+ case EFFECT_FIELD_FILE:
+ return data.toString();
+ }
+ return QString();
}
void Effect::load(QXmlStreamReader& stream) {
- int row_count = 0;
+ int row_count = 0;
- QString tag = stream.name().toString();
+ QString tag = stream.name().toString();
- while (!stream.atEnd() && !(stream.name() == tag && stream.isEndElement())) {
- stream.readNext();
- if (stream.name() == "row" && stream.isStartElement()) {
- if (row_count < rows.size()) {
- EffectRow* row = rows.at(row_count);
- int field_count = 0;
+ while (!stream.atEnd() && !(stream.name() == tag && stream.isEndElement())) {
+ stream.readNext();
+ if (stream.name() == "row" && stream.isStartElement()) {
+ if (row_count < rows.size()) {
+ EffectRow* row = rows.at(row_count);
+ int field_count = 0;
- while (!stream.atEnd() && !(stream.name() == "row" && stream.isEndElement())) {
- stream.readNext();
+ while (!stream.atEnd() && !(stream.name() == "row" && stream.isEndElement())) {
+ stream.readNext();
- // read field
- if (stream.name() == "field" && stream.isStartElement()) {
- if (field_count < row->fieldCount()) {
- // match field using ID
- int field_number = field_count;
- for (int k=0;kfieldCount();l++) {
- if (row->field(l)->id == attr.value()) {
- field_number = l;
+ // read field
+ if (stream.name() == "field" && stream.isStartElement()) {
+ if (field_count < row->fieldCount()) {
+ // match field using ID
+ int field_number = field_count;
+ for (int k=0;kfieldCount();l++) {
+ if (row->field(l)->id == attr.value()) {
+ field_number = l;
// qInfo() << "Found field by ID";
- break;
- }
- }
- break;
- }
- }
+ break;
+ }
+ }
+ break;
+ }
+ }
- EffectField* field = row->field(field_number);
+ EffectField* field = row->field(field_number);
- // get current field value
- for (int k=0;kset_current_data(load_data_from_string(field->type, attr.value().toString()));
- break;
- }
- }
+ // get current field value
+ for (int k=0;kset_current_data(load_data_from_string(field->type, attr.value().toString()));
+ break;
+ }
+ }
- while (!stream.atEnd() && !(stream.name() == "field" && stream.isEndElement())) {
- stream.readNext();
+ while (!stream.atEnd() && !(stream.name() == "field" && stream.isEndElement())) {
+ stream.readNext();
- // read keyframes
- if (stream.name() == "key" && stream.isStartElement()) {
- row->setKeyframing(true);
+ // read keyframes
+ if (stream.name() == "key" && stream.isStartElement()) {
+ row->setKeyframing(true);
- EffectKeyframe key;
- for (int k=0;ktype, attr.value().toString());
- } else if (attr.name() == "frame") {
- key.time = attr.value().toLong();
- } else if (attr.name() == "type") {
- key.type = attr.value().toInt();
- } else if (attr.name() == "prehx") {
- key.pre_handle_x = attr.value().toDouble();
- } else if (attr.name() == "prehy") {
- key.pre_handle_y = attr.value().toDouble();
- } else if (attr.name() == "posthx") {
- key.post_handle_x = attr.value().toDouble();
- } else if (attr.name() == "posthy") {
- key.post_handle_y = attr.value().toDouble();
- }
- }
- field->keyframes.append(key);
- }
- }
- } else {
- qCritical() << "Too many fields for effect" << id << "row" << row_count << ". Project might be corrupt. (Got" << field_count << ", expected <" << row->fieldCount()-1 << ")";
- }
- field_count++;
- }
- }
+ EffectKeyframe key;
+ for (int k=0;ktype, attr.value().toString());
+ } else if (attr.name() == "frame") {
+ key.time = attr.value().toLong();
+ } else if (attr.name() == "type") {
+ key.type = attr.value().toInt();
+ } else if (attr.name() == "prehx") {
+ key.pre_handle_x = attr.value().toDouble();
+ } else if (attr.name() == "prehy") {
+ key.pre_handle_y = attr.value().toDouble();
+ } else if (attr.name() == "posthx") {
+ key.post_handle_x = attr.value().toDouble();
+ } else if (attr.name() == "posthy") {
+ key.post_handle_y = attr.value().toDouble();
+ }
+ }
+ field->keyframes.append(key);
+ }
+ }
+ } else {
+ qCritical() << "Too many fields for effect" << id << "row" << row_count << ". Project might be corrupt. (Got" << field_count << ", expected <" << row->fieldCount()-1 << ")";
+ }
+ field_count++;
+ }
+ }
- } else {
- qCritical() << "Too many rows for effect" << id << ". Project might be corrupt. (Got" << row_count << ", expected <" << rows.size()-1 << ")";
- }
- row_count++;
- } else if (stream.isStartElement()) {
- custom_load(stream);
- }
- }
+ } else {
+ qCritical() << "Too many rows for effect" << id << ". Project might be corrupt. (Got" << row_count << ", expected <" << rows.size()-1 << ")";
+ }
+ row_count++;
+ } else if (stream.isStartElement()) {
+ custom_load(stream);
+ }
+ }
}
void Effect::custom_load(QXmlStreamReader &) {}
void Effect::save(QXmlStreamWriter& stream) {
- stream.writeAttribute("name", meta->category + "/" + meta->name);
- stream.writeAttribute("enabled", QString::number(is_enabled()));
+ stream.writeAttribute("name", meta->category + "/" + meta->name);
+ stream.writeAttribute("enabled", QString::number(is_enabled()));
- for (int i=0;isavable) {
- stream.writeStartElement("row"); // row
- for (int j=0;jfieldCount();j++) {
- EffectField* field = row->field(j);
- stream.writeStartElement("field"); // field
- stream.writeAttribute("id", field->id);
- stream.writeAttribute("value", save_data_to_string(field->type, field->get_current_data()));
- for (int k=0;kkeyframes.size();k++) {
- const EffectKeyframe& key = field->keyframes.at(k);
- stream.writeStartElement("key");
- stream.writeAttribute("value", save_data_to_string(field->type, key.data));
- stream.writeAttribute("frame", QString::number(key.time));
- stream.writeAttribute("type", QString::number(key.type));
- stream.writeAttribute("prehx", QString::number(key.pre_handle_x));
- stream.writeAttribute("prehy", QString::number(key.pre_handle_y));
- stream.writeAttribute("posthx", QString::number(key.post_handle_x));
- stream.writeAttribute("posthy", QString::number(key.post_handle_y));
- stream.writeEndElement(); // key
- }
- stream.writeEndElement(); // field
- }
- stream.writeEndElement(); // row
- }
- }
+ for (int i=0;isavable) {
+ stream.writeStartElement("row"); // row
+ for (int j=0;jfieldCount();j++) {
+ EffectField* field = row->field(j);
+ stream.writeStartElement("field"); // field
+ stream.writeAttribute("id", field->id);
+ stream.writeAttribute("value", save_data_to_string(field->type, field->get_current_data()));
+ for (int k=0;kkeyframes.size();k++) {
+ const EffectKeyframe& key = field->keyframes.at(k);
+ stream.writeStartElement("key");
+ stream.writeAttribute("value", save_data_to_string(field->type, key.data));
+ stream.writeAttribute("frame", QString::number(key.time));
+ stream.writeAttribute("type", QString::number(key.type));
+ stream.writeAttribute("prehx", QString::number(key.pre_handle_x));
+ stream.writeAttribute("prehy", QString::number(key.pre_handle_y));
+ stream.writeAttribute("posthx", QString::number(key.post_handle_x));
+ stream.writeAttribute("posthy", QString::number(key.post_handle_y));
+ stream.writeEndElement(); // key
+ }
+ stream.writeEndElement(); // field
+ }
+ stream.writeEndElement(); // row
+ }
+ }
}
void Effect::load_from_string(const QByteArray &s) {
- // clear existing keyframe data
- for (int i=0;isetKeyframing(false);
- for (int j=0;jfieldCount();j++) {
- EffectField* field = row->field(j);
- field->keyframes.clear();
- }
- }
+ // clear existing keyframe data
+ for (int i=0;isetKeyframing(false);
+ for (int j=0;jfieldCount();j++) {
+ EffectField* field = row->field(j);
+ field->keyframes.clear();
+ }
+ }
- // write settings with xml writer
- QXmlStreamReader stream(s);
+ // write settings with xml writer
+ QXmlStreamReader stream(s);
- while (!stream.atEnd()) {
- stream.readNext();
+ while (!stream.atEnd()) {
+ stream.readNext();
- // find the effect opening tag
- if (stream.name() == "effect" && stream.isStartElement()) {
+ // find the effect opening tag
+ if (stream.name() == "effect" && stream.isStartElement()) {
- // check the name to see if it matches this effect
- const QXmlStreamAttributes& attributes = stream.attributes();
- for (int i=0;ipath.isEmpty() || (vertPath.isEmpty() && fragPath.isEmpty())) return;
- QList effects_paths = get_effects_paths();
- const QString& test_fn = vertPath.isEmpty() ? fragPath : vertPath;
- for (int i=0;ipath.isEmpty() || (vertPath.isEmpty() && fragPath.isEmpty())) return;
+ QList effects_paths = get_effects_paths();
+ const QString& test_fn = vertPath.isEmpty() ? fragPath : vertPath;
+ for (int i=0;iaddShaderFromSourceFile(QOpenGLShader::Vertex, meta->path + "/" + vertPath)) {
- qInfo() << "Vertex shader added successfully";
- } else {
- glsl_compiled = false;
- qWarning() << "Vertex shader could not be added";
- }
- }
- if (!fragPath.isEmpty()) {
- if (glslProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, meta->path + "/" + fragPath)) {
- qInfo() << "Fragment shader added successfully";
- } else {
- glsl_compiled = false;
- qWarning() << "Fragment shader could not be added";
- }
- }
- if (glsl_compiled) {
- if (glslProgram->link()) {
- qInfo() << "Shader program linked successfully";
- } else {
- qWarning() << "Shader program failed to link";
- }
- }
- isOpen = true;
- }
- } else {
- isOpen = true;
- }
+ if (isOpen) {
+ qWarning() << "Tried to open an effect that was already open";
+ close();
+ }
+ if (olive::CurrentRuntimeConfig.shaders_are_enabled && enable_shader) {
+ if (QOpenGLContext::currentContext() == nullptr) {
+ qWarning() << "No current context to create a shader program for - will retry next repaint";
+ } else {
+ glslProgram = new QOpenGLShaderProgram();
+ validate_meta_path();
+ bool glsl_compiled = true;
+ if (!vertPath.isEmpty()) {
+ if (glslProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, meta->path + "/" + vertPath)) {
+ qInfo() << "Vertex shader added successfully";
+ } else {
+ glsl_compiled = false;
+ qWarning() << "Vertex shader could not be added";
+ }
+ }
+ if (!fragPath.isEmpty()) {
+ if (glslProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, meta->path + "/" + fragPath)) {
+ qInfo() << "Fragment shader added successfully";
+ } else {
+ glsl_compiled = false;
+ qWarning() << "Fragment shader could not be added";
+ }
+ }
+ if (glsl_compiled) {
+ if (glslProgram->link()) {
+ qInfo() << "Shader program linked successfully";
+ } else {
+ qWarning() << "Shader program failed to link";
+ }
+ }
+ isOpen = true;
+ }
+ } else {
+ isOpen = true;
+ }
}
void Effect::close() {
- if (!isOpen) {
- qWarning() << "Tried to close an effect that was already closed";
- }
- delete_texture();
- if (glslProgram != nullptr) {
- delete glslProgram;
- glslProgram = nullptr;
- }
- isOpen = false;
+ if (!isOpen) {
+ qWarning() << "Tried to close an effect that was already closed";
+ }
+ delete_texture();
+ if (glslProgram != nullptr) {
+ delete glslProgram;
+ glslProgram = nullptr;
+ }
+ isOpen = false;
}
bool Effect::is_glsl_linked() {
- return glslProgram != nullptr && glslProgram->isLinked();
+ return glslProgram != nullptr && glslProgram->isLinked();
}
void Effect::startEffect() {
- if (!isOpen) {
- open();
- qWarning() << "Tried to start a closed effect - opening";
- }
- if (olive::CurrentRuntimeConfig.shaders_are_enabled
- && enable_shader
- && glslProgram->isLinked()) {
- bound = glslProgram->bind();
- }
+ if (!isOpen) {
+ open();
+ qWarning() << "Tried to start a closed effect - opening";
+ }
+ if (olive::CurrentRuntimeConfig.shaders_are_enabled
+ && enable_shader
+ && glslProgram->isLinked()) {
+ bound = glslProgram->bind();
+ }
}
void Effect::endEffect() {
- if (bound) glslProgram->release();
- bound = false;
+ if (bound) glslProgram->release();
+ bound = false;
}
int Effect::getIterations() {
- return iterations;
+ return iterations;
}
void Effect::setIterations(int i) {
- iterations = i;
+ iterations = i;
}
void Effect::process_image(double, uint8_t *, uint8_t *, int){}
EffectPtr Effect::copy(Clip *c) {
EffectPtr copy = Effect::Create(c, meta);
- copy->set_enabled(is_enabled());
- copy_field_keyframes(copy);
- return copy;
+ copy->set_enabled(is_enabled());
+ copy_field_keyframes(copy);
+ return copy;
}
void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
glslProgram->setUniformValue("resolution", parent_clip->media_width(), parent_clip->media_height());
- glslProgram->setUniformValue("time", GLfloat(timecode));
- glslProgram->setUniformValue("iteration", iteration);
+ glslProgram->setUniformValue("time", GLfloat(timecode));
+ glslProgram->setUniformValue("iteration", iteration);
- for (int i=0;ifieldCount();j++) {
- EffectField* field = row->field(j);
- if (!field->id.isEmpty()) {
- switch (field->type) {
- case EFFECT_FIELD_DOUBLE:
- glslProgram->setUniformValue(field->id.toUtf8().constData(), GLfloat(field->get_double_value(timecode)));
- break;
- case EFFECT_FIELD_COLOR:
- glslProgram->setUniformValue(
- field->id.toUtf8().constData(),
- GLfloat(field->get_color_value(timecode).redF()),
- GLfloat(field->get_color_value(timecode).greenF()),
- GLfloat(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:
- glslProgram->setUniformValue(field->id.toUtf8().constData(), field->get_bool_value(timecode));
- break;
- case EFFECT_FIELD_COMBO:
- glslProgram->setUniformValue(field->id.toUtf8().constData(), field->get_combo_index(timecode));
- break;
- case EFFECT_FIELD_FONT: break; // can you even send a string to a uniform value?
- case EFFECT_FIELD_FILE: break; // can you even send a string to a uniform value?
- }
- }
- }
- }
+ for (int i=0;ifieldCount();j++) {
+ EffectField* field = row->field(j);
+ if (!field->id.isEmpty()) {
+ switch (field->type) {
+ case EFFECT_FIELD_DOUBLE:
+ glslProgram->setUniformValue(field->id.toUtf8().constData(), GLfloat(field->get_double_value(timecode)));
+ break;
+ case EFFECT_FIELD_COLOR:
+ glslProgram->setUniformValue(
+ field->id.toUtf8().constData(),
+ GLfloat(field->get_color_value(timecode).redF()),
+ GLfloat(field->get_color_value(timecode).greenF()),
+ GLfloat(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:
+ glslProgram->setUniformValue(field->id.toUtf8().constData(), field->get_bool_value(timecode));
+ break;
+ case EFFECT_FIELD_COMBO:
+ glslProgram->setUniformValue(field->id.toUtf8().constData(), field->get_combo_index(timecode));
+ break;
+ case EFFECT_FIELD_FONT: break; // can you even send a string to a uniform value?
+ case EFFECT_FIELD_FILE: break; // can you even send a string to a uniform value?
+ }
+ }
+ }
+ }
}
void Effect::process_coords(double, GLTextureCoords&, int) {}
GLuint Effect::process_superimpose(double timecode) {
- bool dimensions_changed = false;
- bool redrew_image = false;
+ bool dimensions_changed = false;
+ bool redrew_image = false;
int width = parent_clip->media_width();
int height = parent_clip->media_height();
- if (width != img.width() || height != img.height()) {
- img = QImage(width, height, QImage::Format_RGBA8888_Premultiplied);
- dimensions_changed = true;
- }
+ if (width != img.width() || height != img.height()) {
+ img = QImage(width, height, QImage::Format_RGBA8888_Premultiplied);
+ dimensions_changed = true;
+ }
- if (valueHasChanged(timecode) || dimensions_changed || enable_always_update) {
- redraw(timecode);
- redrew_image = true;
- }
+ if (valueHasChanged(timecode) || dimensions_changed || enable_always_update) {
+ redraw(timecode);
+ redrew_image = true;
+ }
- if (texture == nullptr || texture->width() != img.width() || texture->height() != img.height()) {
- delete_texture();
+ if (texture == nullptr || texture->width() != img.width() || texture->height() != img.height()) {
+ delete_texture();
- texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
- texture->setSize(img.width(), img.height());
- texture->setFormat(QOpenGLTexture::RGBA8_UNorm);
- texture->setMipLevels(texture->maximumMipLevels());
- texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
- texture->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
+ texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
+ texture->setSize(img.width(), img.height());
+ texture->setFormat(QOpenGLTexture::RGBA8_UNorm);
+ texture->setMipLevels(texture->maximumMipLevels());
+ texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
+ texture->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
- redrew_image = true;
- }
+ redrew_image = true;
+ }
- if (redrew_image) {
- texture->setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, img.constBits());
- }
+ if (redrew_image) {
+ texture->setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, img.constBits());
+ }
- return texture->textureId();
+ return texture->textureId();
}
void Effect::process_audio(double, double, quint8*, int, int) {}
@@ -942,158 +943,158 @@ void Effect::process_audio(double, double, quint8*, int, int) {}
void Effect::gizmo_draw(double, GLTextureCoords &) {}
void Effect::gizmo_move(EffectGizmo* gizmo, int x_movement, int y_movement, double timecode, bool done) {
- for (int i=0;ix_field1 != nullptr) {
- gizmo->x_field1->set_double_value(gizmo->x_field1->get_double_value(timecode) + x_movement*gizmo->x_field_multi1);
- gizmo->x_field1->make_key_from_change(ca);
- }
- if (gizmo->y_field1 != nullptr) {
- gizmo->y_field1->set_double_value(gizmo->y_field1->get_double_value(timecode) + y_movement*gizmo->y_field_multi1);
- gizmo->y_field1->make_key_from_change(ca);
- }
- if (gizmo->x_field2 != nullptr) {
- gizmo->x_field2->set_double_value(gizmo->x_field2->get_double_value(timecode) + x_movement*gizmo->x_field_multi2);
- gizmo->x_field2->make_key_from_change(ca);
- }
- if (gizmo->y_field2 != nullptr) {
- gizmo->y_field2->set_double_value(gizmo->y_field2->get_double_value(timecode) + y_movement*gizmo->y_field_multi2);
- gizmo->y_field2->make_key_from_change(ca);
- }
- if (done) olive::UndoStack.push(ca);
- break;
- }
- }
+ for (int i=0;ix_field1 != nullptr) {
+ gizmo->x_field1->set_double_value(gizmo->x_field1->get_double_value(timecode) + x_movement*gizmo->x_field_multi1);
+ gizmo->x_field1->make_key_from_change(ca);
+ }
+ if (gizmo->y_field1 != nullptr) {
+ gizmo->y_field1->set_double_value(gizmo->y_field1->get_double_value(timecode) + y_movement*gizmo->y_field_multi1);
+ gizmo->y_field1->make_key_from_change(ca);
+ }
+ if (gizmo->x_field2 != nullptr) {
+ gizmo->x_field2->set_double_value(gizmo->x_field2->get_double_value(timecode) + x_movement*gizmo->x_field_multi2);
+ gizmo->x_field2->make_key_from_change(ca);
+ }
+ if (gizmo->y_field2 != nullptr) {
+ gizmo->y_field2->set_double_value(gizmo->y_field2->get_double_value(timecode) + y_movement*gizmo->y_field_multi2);
+ gizmo->y_field2->make_key_from_change(ca);
+ }
+ if (done) olive::UndoStack.push(ca);
+ break;
+ }
+ }
}
void Effect::gizmo_world_to_screen() {
- GLfloat view_val[16];
- GLfloat projection_val[16];
- glGetFloatv(GL_MODELVIEW_MATRIX, view_val);
- glGetFloatv(GL_PROJECTION_MATRIX, projection_val);
+ GLfloat view_val[16];
+ GLfloat projection_val[16];
+ glGetFloatv(GL_MODELVIEW_MATRIX, view_val);
+ glGetFloatv(GL_PROJECTION_MATRIX, projection_val);
- QMatrix4x4 view_matrix(view_val);
- QMatrix4x4 projection_matrix(projection_val);
+ QMatrix4x4 view_matrix(view_val);
+ QMatrix4x4 projection_matrix(projection_val);
- for (int i=0;iget_point_count();j++) {
- QVector4D screen_pos = QVector4D(g->world_pos[j].x(), g->world_pos[j].y(), 0, 1.0) * (view_matrix * projection_matrix);
+ for (int j=0;jget_point_count();j++) {
+ QVector4D screen_pos = QVector4D(g->world_pos[j].x(), g->world_pos[j].y(), 0, 1.0) * (view_matrix * projection_matrix);
- int adjusted_sx1 = qRound(((screen_pos.x()*0.5f)+0.5f)*parent_clip->sequence->width);
- int adjusted_sy1 = qRound((1.0f-((screen_pos.y()*0.5f)+0.5f))*parent_clip->sequence->height);
+ int adjusted_sx1 = qRound(((screen_pos.x()*0.5f)+0.5f)*parent_clip->sequence->width);
+ int adjusted_sy1 = qRound((1.0f-((screen_pos.y()*0.5f)+0.5f))*parent_clip->sequence->height);
- g->screen_pos[j] = QPoint(adjusted_sx1, adjusted_sy1);
- }
- }
+ g->screen_pos[j] = QPoint(adjusted_sx1, adjusted_sy1);
+ }
+ }
}
bool Effect::are_gizmos_enabled() {
- return (gizmos.size() > 0);
+ return (gizmos.size() > 0);
}
void Effect::redraw(double) {
- /*
- // run javascript
- QPainter p(&img);
- painter_wrapper.img = &img;
- painter_wrapper.painter = &p;
+ /*
+ // run javascript
+ QPainter p(&img);
+ painter_wrapper.img = &img;
+ painter_wrapper.painter = &p;
- jsEngine.globalObject().setProperty("painter", wrapper_obj);
+ jsEngine.globalObject().setProperty("painter", wrapper_obj);
jsEngine.globalObject().setProperty("width", parent_clip->media_width());
jsEngine.globalObject().setProperty("height", parent_clip->media_height());
- for (int i=0;ifieldCount();j++) {
- EffectField* field = row->field(j);
- if (!field->id.isEmpty()) {
- switch (field->type) {
- case EFFECT_FIELD_DOUBLE:
- jsEngine.globalObject().setProperty(field->id, field->get_double_value(timecode));
- break;
- case EFFECT_FIELD_COLOR:
- jsEngine.globalObject().setProperty(field->id, field->get_color_value(timecode).name());
- break;
- case EFFECT_FIELD_STRING:
- jsEngine.globalObject().setProperty(field->id, field->get_string_value(timecode));
- break;
- case EFFECT_FIELD_BOOL:
- jsEngine.globalObject().setProperty(field->id, field->get_bool_value(timecode));
- break;
- case EFFECT_FIELD_COMBO:
- jsEngine.globalObject().setProperty(field->id, field->get_combo_index(timecode));
- break;
- case EFFECT_FIELD_FONT:
- jsEngine.globalObject().setProperty(field->id, field->get_font_name(timecode));
- break;
- }
- }
- }
- }
+ for (int i=0;ifieldCount();j++) {
+ EffectField* field = row->field(j);
+ if (!field->id.isEmpty()) {
+ switch (field->type) {
+ case EFFECT_FIELD_DOUBLE:
+ jsEngine.globalObject().setProperty(field->id, field->get_double_value(timecode));
+ break;
+ case EFFECT_FIELD_COLOR:
+ jsEngine.globalObject().setProperty(field->id, field->get_color_value(timecode).name());
+ break;
+ case EFFECT_FIELD_STRING:
+ jsEngine.globalObject().setProperty(field->id, field->get_string_value(timecode));
+ break;
+ case EFFECT_FIELD_BOOL:
+ jsEngine.globalObject().setProperty(field->id, field->get_bool_value(timecode));
+ break;
+ case EFFECT_FIELD_COMBO:
+ jsEngine.globalObject().setProperty(field->id, field->get_combo_index(timecode));
+ break;
+ case EFFECT_FIELD_FONT:
+ jsEngine.globalObject().setProperty(field->id, field->get_font_name(timecode));
+ break;
+ }
+ }
+ }
+ }
- jsEngine.evaluate(script);
- */
+ jsEngine.evaluate(script);
+ */
}
bool Effect::valueHasChanged(double timecode) {
- if (cachedValues.size() == 0) {
- for (int i=0;ifieldCount();j++) {
- cachedValues.append(crow->field(j)->get_current_data());
- }
- }
- return true;
- } else {
- bool changed = false;
- int index = 0;
- for (int i=0;ifieldCount();j++) {
- EffectField* field = crow->field(j);
- field->validate_keyframe_data(timecode);
- if (cachedValues.at(index) != field->get_current_data()) {
- changed = true;
- }
- cachedValues[index] = field->get_current_data();
- index++;
- }
- }
- return changed;
- }
+ if (cachedValues.size() == 0) {
+ for (int i=0;ifieldCount();j++) {
+ cachedValues.append(crow->field(j)->get_current_data());
+ }
+ }
+ return true;
+ } else {
+ bool changed = false;
+ int index = 0;
+ for (int i=0;ifieldCount();j++) {
+ EffectField* field = crow->field(j);
+ field->validate_keyframe_data(timecode);
+ if (cachedValues.at(index) != field->get_current_data()) {
+ changed = true;
+ }
+ cachedValues[index] = field->get_current_data();
+ index++;
+ }
+ }
+ return changed;
+ }
}
void Effect::delete_texture() {
- if (texture != nullptr) {
- delete texture;
- texture = nullptr;
- }
+ if (texture != nullptr) {
+ delete texture;
+ texture = nullptr;
+ }
}
const EffectMeta* get_meta_from_name(const QString& input) {
- int split_index = input.indexOf('/');
- QString category;
- if (split_index > -1) {
- category = input.left(split_index);
- }
- QString name = input.mid(split_index + 1);
+ int split_index = input.indexOf('/');
+ QString category;
+ if (split_index > -1) {
+ category = input.left(split_index);
+ }
+ QString name = input.mid(split_index + 1);
- for (int j=0;j(a) + static_cast(b);
- mixed_sample = qMax(qMin(mixed_sample, static_cast(INT16_MAX)), static_cast(INT16_MIN));
- return static_cast(mixed_sample);
+ qint32 mixed_sample = static_cast(a) + static_cast(b);
+ mixed_sample = qMax(qMin(mixed_sample, static_cast(INT16_MAX)), static_cast(INT16_MIN));
+ return static_cast(mixed_sample);
}
diff --git a/project/effect.h b/project/effect.h
index 64224ec97..91600f1d3 100644
--- a/project/effect.h
+++ b/project/effect.h
@@ -58,7 +58,16 @@ struct EffectMeta {
int type;
int subtype;
};
-extern QVector effects;
+
+struct BlendMode {
+ QString name;
+ QString url;
+};
+
+namespace olive {
+ extern QVector effects;
+ extern QVector blend_modes;
+}
double log_volume(double linear);
@@ -94,36 +103,6 @@ enum EffectInternal {
EFFECT_INTERNAL_COUNT
};
-enum EffectBlendMode {
- BLEND_MODE_ADD,
- BLEND_MODE_AVERAGE,
- BLEND_MODE_COLORBURN,
- BLEND_MODE_COLORDODGE,
- BLEND_MODE_DARKEN,
- BLEND_MODE_DIFFERENCE,
- BLEND_MODE_EXCLUSION,
- BLEND_MODE_GLOW,
- BLEND_MODE_HARDLIGHT,
- BLEND_MODE_HARDMIX,
- BLEND_MODE_LIGHTEN,
- BLEND_MODE_LINEARBURN,
- BLEND_MODE_LINEARDODGE,
- BLEND_MODE_LINEARLIGHT,
- BLEND_MODE_MULTIPLY,
- BLEND_MODE_NEGATION,
- BLEND_MODE_NORMAL,
- BLEND_MODE_OVERLAY,
- BLEND_MODE_PHOENIX,
- BLEND_MODE_PINLIGHT,
- BLEND_MODE_REFLECT,
- BLEND_MODE_SCREEN,
- BLEND_MODE_SOFTLIGHT,
- BLEND_MODE_SUBSTRACT,
- BLEND_MODE_SUBTRACT,
- BLEND_MODE_VIVIDLIGHT,
- BLEND_MODE_COUNT
-};
-
struct GLTextureCoords {
int grid_size;
diff --git a/project/effectloaders.cpp b/project/effectloaders.cpp
index 443caec1e..4162a2a6b 100644
--- a/project/effectloaders.cpp
+++ b/project/effectloaders.cpp
@@ -39,233 +39,233 @@ typedef void (*f0rGetPluginInfo)(f0r_plugin_info_t* info);
#endif
void load_internal_effects() {
- if (!olive::CurrentRuntimeConfig.shaders_are_enabled) qWarning() << "Shaders are disabled, some effects may be nonfunctional";
+ if (!olive::CurrentRuntimeConfig.shaders_are_enabled) qWarning() << "Shaders are disabled, some effects may be nonfunctional";
- EffectMeta em;
+ EffectMeta em;
- // load internal effects
- em.path = ":/internalshaders";
+ // load internal effects
+ em.path = ":/internalshaders";
- em.type = EFFECT_TYPE_EFFECT;
- em.subtype = EFFECT_TYPE_AUDIO;
+ em.type = EFFECT_TYPE_EFFECT;
+ em.subtype = EFFECT_TYPE_AUDIO;
- em.name = "Volume";
- em.internal = EFFECT_INTERNAL_VOLUME;
- effects.append(em);
+ em.name = "Volume";
+ em.internal = EFFECT_INTERNAL_VOLUME;
+ olive::effects.append(em);
- em.name = "Pan";
- em.internal = EFFECT_INTERNAL_PAN;
- effects.append(em);
+ em.name = "Pan";
+ em.internal = EFFECT_INTERNAL_PAN;
+ olive::effects.append(em);
#ifndef NOVST
- em.name = "VST Plugin 2.x";
- em.internal = EFFECT_INTERNAL_VST;
- effects.append(em);
+ em.name = "VST Plugin 2.x";
+ em.internal = EFFECT_INTERNAL_VST;
+ olive::effects.append(em);
#endif
- em.name = "Tone";
- em.internal = EFFECT_INTERNAL_TONE;
- effects.append(em);
+ em.name = "Tone";
+ em.internal = EFFECT_INTERNAL_TONE;
+ olive::effects.append(em);
- em.name = "Noise";
- em.internal = EFFECT_INTERNAL_NOISE;
- effects.append(em);
+ em.name = "Noise";
+ em.internal = EFFECT_INTERNAL_NOISE;
+ olive::effects.append(em);
- em.name = "Fill Left/Right";
- em.internal = EFFECT_INTERNAL_FILLLEFTRIGHT;
- effects.append(em);
+ em.name = "Fill Left/Right";
+ em.internal = EFFECT_INTERNAL_FILLLEFTRIGHT;
+ olive::effects.append(em);
- em.subtype = EFFECT_TYPE_VIDEO;
+ em.subtype = EFFECT_TYPE_VIDEO;
- em.name = "Transform";
- em.category = "Distort";
- em.internal = EFFECT_INTERNAL_TRANSFORM;
- effects.append(em);
+ em.name = "Transform";
+ em.category = "Distort";
+ em.internal = EFFECT_INTERNAL_TRANSFORM;
+ olive::effects.append(em);
- em.name = "Corner Pin";
- em.internal = EFFECT_INTERNAL_CORNERPIN;
- effects.append(em);
+ em.name = "Corner Pin";
+ em.internal = EFFECT_INTERNAL_CORNERPIN;
+ olive::effects.append(em);
- /*em.name = "Mask";
- em.internal = EFFECT_INTERNAL_MASK;
- effects.append(em);*/
+ /*em.name = "Mask";
+ em.internal = EFFECT_INTERNAL_MASK;
+ olive::effects.append(em);*/
- em.name = "Shake";
- em.internal = EFFECT_INTERNAL_SHAKE;
- effects.append(em);
+ em.name = "Shake";
+ em.internal = EFFECT_INTERNAL_SHAKE;
+ olive::effects.append(em);
- em.name = "Text";
- em.category = "Render";
- em.internal = EFFECT_INTERNAL_TEXT;
- effects.append(em);
+ em.name = "Text";
+ em.category = "Render";
+ em.internal = EFFECT_INTERNAL_TEXT;
+ olive::effects.append(em);
- em.name = "Timecode";
- em.internal = EFFECT_INTERNAL_TIMECODE;
- effects.append(em);
+ em.name = "Timecode";
+ em.internal = EFFECT_INTERNAL_TIMECODE;
+ olive::effects.append(em);
- em.name = "Solid";
- em.internal = EFFECT_INTERNAL_SOLID;
- effects.append(em);
+ em.name = "Solid";
+ em.internal = EFFECT_INTERNAL_SOLID;
+ olive::effects.append(em);
- // internal transitions
- em.type = EFFECT_TYPE_TRANSITION;
- em.category = "";
+ // internal transitions
+ em.type = EFFECT_TYPE_TRANSITION;
+ em.category = "";
- em.name = "Cross Dissolve";
- em.internal = TRANSITION_INTERNAL_CROSSDISSOLVE;
- effects.append(em);
+ em.name = "Cross Dissolve";
+ em.internal = TRANSITION_INTERNAL_CROSSDISSOLVE;
+ olive::effects.append(em);
- em.subtype = EFFECT_TYPE_AUDIO;
+ em.subtype = EFFECT_TYPE_AUDIO;
- em.name = "Linear Fade";
- em.internal = TRANSITION_INTERNAL_LINEARFADE;
- effects.append(em);
+ em.name = "Linear Fade";
+ em.internal = TRANSITION_INTERNAL_LINEARFADE;
+ olive::effects.append(em);
- em.name = "Exponential Fade";
- em.internal = TRANSITION_INTERNAL_EXPONENTIALFADE;
- effects.append(em);
+ em.name = "Exponential Fade";
+ em.internal = TRANSITION_INTERNAL_EXPONENTIALFADE;
+ olive::effects.append(em);
- em.name = "Logarithmic Fade";
- em.internal = TRANSITION_INTERNAL_LOGARITHMICFADE;
- effects.append(em);
+ em.name = "Logarithmic Fade";
+ em.internal = TRANSITION_INTERNAL_LOGARITHMICFADE;
+ olive::effects.append(em);
}
void load_shader_effects() {
- QList effects_paths = get_effects_paths();
+ QList effects_paths = get_effects_paths();
- for (int h=0;h entries = effects_dir.entryList(QStringList("*.xml"), QDir::Files);
- for (int i=0;i entries = effects_dir.entryList(QStringList("*.xml"), QDir::Files);
+ for (int i=0;istart();
+ EffectInit* init_thread = new EffectInit();
+ QObject::connect(init_thread, SIGNAL(finished()), init_thread, SLOT(deleteLater()));
+ init_thread->start();
}
#ifndef NOFREI0R
void load_frei0r_effects_worker(const QString& dir, EffectMeta& em, QVector& loaded_names) {
- QDir search_dir(dir);
- if (search_dir.exists()) {
- QList entry_list = search_dir.entryList(LibFilter(), QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
- for (int j=0;j(LibAddress(effect, "f0r_get_plugin_info"));
- if (get_info_func != nullptr) {
- f0r_plugin_info_t info;
- get_info_func(&info);
+ QDir search_dir(dir);
+ if (search_dir.exists()) {
+ QList entry_list = search_dir.entryList(LibFilter(), QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
+ for (int j=0;j(LibAddress(effect, "f0r_get_plugin_info"));
+ if (get_info_func != nullptr) {
+ f0r_plugin_info_t info;
+ get_info_func(&info);
- if (!loaded_names.contains(info.name)
- && info.plugin_type == F0R_PLUGIN_TYPE_FILTER
- && info.color_model == F0R_COLOR_MODEL_RGBA8888) {
- em.name = info.name;
- em.path = dir;
- em.filename = entry_list.at(j);
- em.tooltip = QString("%1\n%2\n%3\n%4").arg(em.name, info.author, info.explanation, em.filename);
+ if (!loaded_names.contains(info.name)
+ && info.plugin_type == F0R_PLUGIN_TYPE_FILTER
+ && info.color_model == F0R_COLOR_MODEL_RGBA8888) {
+ em.name = info.name;
+ em.path = dir;
+ em.filename = entry_list.at(j);
+ em.tooltip = QString("%1\n%2\n%3\n%4").arg(em.name, info.author, info.explanation, em.filename);
- loaded_names.append(em.name);
+ loaded_names.append(em.name);
- effects.append(em);
- }
+ olive::effects.append(em);
+ }
// qDebug() << "Found:" << info.name << "by" << info.author;
- }
- LibClose(effect);
- }
+ }
+ LibClose(effect);
+ }
// qDebug() << search_dir.filePath(entry_list.at(j));
- }
- }
- }
+ }
+ }
+ }
}
void load_frei0r_effects() {
- QList effect_dirs = get_effects_paths();
+ QList effect_dirs = get_effects_paths();
- // add defined paths for frei0r plugins on unix
+ // add defined paths for frei0r plugins on unix
#if defined(__APPLE__) || defined(__linux__) || defined(__HAIKU__)
- effect_dirs.prepend("/usr/lib/frei0r-1");
- effect_dirs.prepend("/usr/local/lib/frei0r-1");
- effect_dirs.prepend(QDir::homePath() + "/.frei0r-1/lib");
+ effect_dirs.prepend("/usr/lib/frei0r-1");
+ effect_dirs.prepend("/usr/local/lib/frei0r-1");
+ effect_dirs.prepend(QDir::homePath() + "/.frei0r-1/lib");
#endif
- QString env_path(qgetenv("FREI0R_PATH"));
- if (!env_path.isEmpty()) effect_dirs.append(env_path);
+ QString env_path(qgetenv("FREI0R_PATH"));
+ if (!env_path.isEmpty()) effect_dirs.append(env_path);
- QVector loaded_names;
+ QVector loaded_names;
- // search for paths
- EffectMeta em;
- em.category = "Frei0r";
- em.type = EFFECT_TYPE_EFFECT;
- em.subtype = EFFECT_TYPE_VIDEO;
- em.internal = EFFECT_INTERNAL_FREI0R;
+ // search for paths
+ EffectMeta em;
+ em.category = "Frei0r";
+ em.type = EFFECT_TYPE_EFFECT;
+ em.subtype = EFFECT_TYPE_VIDEO;
+ em.internal = EFFECT_INTERNAL_FREI0R;
- for (int i=0;ieffects_loaded.lock();
+ panel_effect_controls->effects_loaded.lock();
}
void EffectInit::run() {
- qInfo() << "Initializing effects...";
- load_internal_effects();
- load_shader_effects();
+ qInfo() << "Initializing effects...";
+ load_internal_effects();
+ load_shader_effects();
#ifndef NOFREI0R
- load_frei0r_effects();
+ load_frei0r_effects();
#endif
- panel_effect_controls->effects_loaded.unlock();
- qInfo() << "Finished initializing effects";
+ panel_effect_controls->effects_loaded.unlock();
+ qInfo() << "Finished initializing effects";
}
diff --git a/rendering/renderfunctions.cpp b/rendering/renderfunctions.cpp
index 4f6a08990..681897895 100644
--- a/rendering/renderfunctions.cpp
+++ b/rendering/renderfunctions.cpp
@@ -399,7 +399,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) {
coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0.0;
coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0;
coords.textureTopLeftQ = coords.textureTopRightQ = coords.textureTopLeftQ = coords.textureBottomLeftQ = 1;
- coords.blendmode = BLEND_MODE_NORMAL;
+ coords.blendmode = -1;
coords.opacity = 1.0;
// if auto-scale is enabled, auto-scale the clip
@@ -514,8 +514,8 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) {
- // copy front buffer to back buffer (only if we're using blending modes - which we usually will be)
- if (!olive::CurrentRuntimeConfig.disable_blending) {
+ // copy front buffer to back buffer (only if we're using a blending mode)
+ if (coords.blendmode >= 0) {
if (params.nests.size() > 0) {
draw_clip(params.ctx, params.nests.last()->fbo[2]->handle(), params.nests.last()->fbo[0]->texture(), true);
} else {
@@ -533,8 +533,8 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) {
// bind front buffer as draw buffer
params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, final_fbo);
- if (olive::CurrentRuntimeConfig.disable_blending) {
- // some GPUs don't like the blending shader, so we provide a pure GL fallback here
+ // Check if we're using a blend mode (< 0 means no blend mode)
+ if (coords.blendmode < 0) {
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_1);
@@ -543,7 +543,9 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) {
full_blit();
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
+
} else {
+
// load background texture into texture unit 0
params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_2);
@@ -572,6 +574,7 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) {
// unbind texture from texture unit 0
params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
+
}
// unbind framebuffer