diff --git a/dialogs/speeddialog.cpp b/dialogs/speeddialog.cpp index 8f85f4594..6713bad1b 100644 --- a/dialogs/speeddialog.cpp +++ b/dialogs/speeddialog.cpp @@ -314,7 +314,7 @@ void set_speed(ComboAction* ca, Clip* c, double speed, bool ripple, long& ep, lo } ep = qMin(ep, c->timeline_out); lr = qMax(lr, proposed_out - c->timeline_out); - ca->append(new MoveClipAction(c, c->timeline_in, proposed_out, c->clip_in * multiplier, c->track)); + move_clip(ca, c, c->timeline_in, proposed_out, c->clip_in * multiplier, c->track); c->refactor_frame_rate(ca, multiplier, false); @@ -346,7 +346,7 @@ void SpeedDialog::accept() { if (reverse->checkState() != Qt::PartiallyChecked && c->reverse != reverse->isChecked()) { long new_clip_in = (c->getMaximumLength() - (c->getLength() + c->clip_in)); - ca->append(new MoveClipAction(c, c->timeline_in, c->timeline_out, new_clip_in, c->track)); + move_clip(ca, c, c->timeline_in, c->timeline_out, new_clip_in, c->track); c->clip_in = new_clip_in; ca->append(new SetBool(&c->reverse, reverse->isChecked())); } diff --git a/effects/internal/audionoiseeffect.cpp b/effects/internal/audionoiseeffect.cpp index 5a65763df..c86c5f38d 100644 --- a/effects/internal/audionoiseeffect.cpp +++ b/effects/internal/audionoiseeffect.cpp @@ -4,14 +4,12 @@ #include AudioNoiseEffect::AudioNoiseEffect(Clip* c, const EffectMeta *em) : Effect(c, em) { - amount_val = add_row("Amount:")->add_field(EFFECT_FIELD_DOUBLE); + amount_val = add_row("Amount:")->add_field(EFFECT_FIELD_DOUBLE, "amount"); amount_val->set_double_minimum_value(0); amount_val->set_double_maximum_value(100); - amount_val->set_double_default_value(20); - amount_val->id = "amount"; + amount_val->set_double_default_value(20); - mix_val = add_row("Mix:")->add_field(EFFECT_FIELD_BOOL); - mix_val->id = "mix"; + mix_val = add_row("Mix:")->add_field(EFFECT_FIELD_BOOL, "mix"); mix_val->set_bool_value(true); srand(QDateTime::currentMSecsSinceEpoch()); diff --git a/effects/internal/cornerpineffect.cpp b/effects/internal/cornerpineffect.cpp index 8e621f880..994d5bb6b 100644 --- a/effects/internal/cornerpineffect.cpp +++ b/effects/internal/cornerpineffect.cpp @@ -9,30 +9,22 @@ CornerPinEffect::CornerPinEffect(Clip *c, const EffectMeta *em) : Effect(c, em) enable_shader = true; EffectRow* top_left = add_row("Top Left:"); - top_left_x = top_left->add_field(EFFECT_FIELD_DOUBLE); - top_left_x->id = "topleftx"; - top_left_y = top_left->add_field(EFFECT_FIELD_DOUBLE); - top_left_y->id = "toplefty"; + top_left_x = top_left->add_field(EFFECT_FIELD_DOUBLE, "topleftx"); + top_left_y = top_left->add_field(EFFECT_FIELD_DOUBLE, "toplefty"); EffectRow* top_right = add_row("Top Right:"); - top_right_x = top_right->add_field(EFFECT_FIELD_DOUBLE); - top_right_x->id = "toprightx"; - top_right_y = top_right->add_field(EFFECT_FIELD_DOUBLE); - top_right_y->id = "toprighty"; + top_right_x = top_right->add_field(EFFECT_FIELD_DOUBLE, "toprightx"); + top_right_y = top_right->add_field(EFFECT_FIELD_DOUBLE, "toprighty"); EffectRow* bottom_left = add_row("Bottom Left:"); - bottom_left_x = bottom_left->add_field(EFFECT_FIELD_DOUBLE); - bottom_left_x->id = "bottomleftx"; - bottom_left_y = bottom_left->add_field(EFFECT_FIELD_DOUBLE); - bottom_left_y->id = "bottomlefty"; + bottom_left_x = bottom_left->add_field(EFFECT_FIELD_DOUBLE, "bottomleftx"); + bottom_left_y = bottom_left->add_field(EFFECT_FIELD_DOUBLE, "bottomlefty"); EffectRow* bottom_right = add_row("Bottom Right:"); - bottom_right_x = bottom_right->add_field(EFFECT_FIELD_DOUBLE); - bottom_right_x->id = "bottomrightx"; - bottom_right_y = bottom_right->add_field(EFFECT_FIELD_DOUBLE); - bottom_right_y->id = "bottomrighty"; + bottom_right_x = bottom_right->add_field(EFFECT_FIELD_DOUBLE, "bottomrightx"); + bottom_right_y = bottom_right->add_field(EFFECT_FIELD_DOUBLE, "bottomrighty"); - perspective = add_row("Perspective:")->add_field(EFFECT_FIELD_BOOL); + perspective = add_row("Perspective:")->add_field(EFFECT_FIELD_BOOL, "perspective"); perspective->set_bool_value(true); connect(top_left_x, SIGNAL(changed()), this, SLOT(field_changed())); diff --git a/effects/internal/cubetransition.cpp b/effects/internal/cubetransition.cpp index ae44537dc..e97cf0c66 100644 --- a/effects/internal/cubetransition.cpp +++ b/effects/internal/cubetransition.cpp @@ -6,6 +6,8 @@ CubeTransition::CubeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transit enable_coords = true; } -void CubeTransition::process_coords(double progress, GLTextureCoords&, int data) { - glTranslatef(-progress, 0, -progress); +void CubeTransition::process_coords(double progress, GLTextureCoords& coords, int data) { + + coords.vertexTopLeftZ = 1; + coords.vertexBottomLeftZ = 1; } diff --git a/effects/internal/paneffect.cpp b/effects/internal/paneffect.cpp index 159cc7136..a9fff136a 100644 --- a/effects/internal/paneffect.cpp +++ b/effects/internal/paneffect.cpp @@ -9,11 +9,10 @@ #include "ui/collapsiblewidget.h" PanEffect::PanEffect(Clip* c, const EffectMeta *em) : Effect(c, em) { - EffectRow* pan_row = add_row("Pan:"); - pan_val = pan_row->add_field(EFFECT_FIELD_DOUBLE); + EffectRow* pan_row = add_row("Pan:"); + pan_val = pan_row->add_field(EFFECT_FIELD_DOUBLE, "pan"); pan_val->set_double_minimum_value(-100); - pan_val->set_double_maximum_value(100); - pan_val->id = "pan"; + pan_val->set_double_maximum_value(100); // set defaults pan_val->set_double_default_value(0); diff --git a/effects/internal/shakeeffect.cpp b/effects/internal/shakeeffect.cpp index 7568bae6b..7460658e4 100644 --- a/effects/internal/shakeeffect.cpp +++ b/effects/internal/shakeeffect.cpp @@ -17,18 +17,15 @@ ShakeEffect::ShakeEffect(Clip *c, const EffectMeta *em) : Effect(c, em) { enable_coords = true; EffectRow* intensity_row = add_row("Intensity:"); - intensity_val = intensity_row->add_field(EFFECT_FIELD_DOUBLE); - intensity_val->id = "intensity"; + intensity_val = intensity_row->add_field(EFFECT_FIELD_DOUBLE, "intensity"); intensity_val->set_double_minimum_value(0); EffectRow* rotation_row = add_row("Rotation:"); - rotation_val = rotation_row->add_field(EFFECT_FIELD_DOUBLE); - rotation_val->id = "rotation"; + rotation_val = rotation_row->add_field(EFFECT_FIELD_DOUBLE, "rotation"); rotation_val->set_double_minimum_value(0); EffectRow* frequency_row = add_row("Frequency:"); - frequency_val = frequency_row->add_field(EFFECT_FIELD_DOUBLE); - frequency_val->id = "frequency"; + frequency_val = frequency_row->add_field(EFFECT_FIELD_DOUBLE, "frequency"); frequency_val->set_double_minimum_value(0); // set defaults diff --git a/effects/internal/solideffect.cpp b/effects/internal/solideffect.cpp index 42006253d..413722569 100644 --- a/effects/internal/solideffect.cpp +++ b/effects/internal/solideffect.cpp @@ -21,26 +21,22 @@ SolidEffect::SolidEffect(Clip* c, const EffectMeta* em) : Effect(c, em) { enable_superimpose = true; - solid_type = add_row("Type:")->add_field(EFFECT_FIELD_COMBO); + solid_type = add_row("Type:")->add_field(EFFECT_FIELD_COMBO, "type"); solid_type->add_combo_item("Solid Color", SOLID_TYPE_COLOR); solid_type->add_combo_item("SMPTE Bars", SOLID_TYPE_BARS); solid_type->add_combo_item("Checkerboard", SOLID_TYPE_CHECKERBOARD); - solid_type->id = "type"; - opacity_field = add_row("Opacity:")->add_field(EFFECT_FIELD_DOUBLE); + opacity_field = add_row("Opacity:")->add_field(EFFECT_FIELD_DOUBLE, "opacity"); opacity_field->set_double_minimum_value(0); opacity_field->set_double_maximum_value(100); opacity_field->set_double_default_value(100); - opacity_field->id = "opacity"; - solid_color_field = add_row("Color:")->add_field(EFFECT_FIELD_COLOR); - solid_color_field->set_color_value(Qt::red); - solid_color_field->id = "color"; + solid_color_field = add_row("Color:")->add_field(EFFECT_FIELD_COLOR, "color"); + solid_color_field->set_color_value(Qt::red); - checkerboard_size_field = add_row("Checkerboard Size:")->add_field(EFFECT_FIELD_DOUBLE); + checkerboard_size_field = add_row("Checkerboard Size:")->add_field(EFFECT_FIELD_DOUBLE, "checker_size"); checkerboard_size_field->set_double_minimum_value(1); checkerboard_size_field->set_double_default_value(10); - checkerboard_size_field->id = "checker_size"; connect(solid_type, SIGNAL(changed()), this, SLOT(field_changed())); connect(solid_color_field, SIGNAL(changed()), this, SLOT(field_changed())); diff --git a/effects/internal/texteffect.cpp b/effects/internal/texteffect.cpp index 2ec788964..e34f4c080 100644 --- a/effects/internal/texteffect.cpp +++ b/effects/internal/texteffect.cpp @@ -24,56 +24,41 @@ TextEffect::TextEffect(Clip *c, const EffectMeta* em) : { enable_superimpose = true; - text_val = add_row("Text:")->add_field(EFFECT_FIELD_STRING, 2); - text_val->id = "text"; + text_val = add_row("Text:")->add_field(EFFECT_FIELD_STRING, "text", 2); - set_font_combobox = add_row("Font:")->add_field(EFFECT_FIELD_FONT, 2); - set_font_combobox->id = "font"; + set_font_combobox = add_row("Font:")->add_field(EFFECT_FIELD_FONT, "font", 2); - size_val = add_row("Size:")->add_field(EFFECT_FIELD_DOUBLE, 2); - size_val->set_double_minimum_value(0); - size_val->id = "size"; + size_val = add_row("Size:")->add_field(EFFECT_FIELD_DOUBLE, "size", 2); + size_val->set_double_minimum_value(0); - set_color_button = add_row("Color:")->add_field(EFFECT_FIELD_COLOR, 2); - set_color_button->id = "color"; + set_color_button = add_row("Color:")->add_field(EFFECT_FIELD_COLOR, "color", 2); EffectRow* alignment_row = add_row("Alignment:"); - halign_field = alignment_row->add_field(EFFECT_FIELD_COMBO); + halign_field = alignment_row->add_field(EFFECT_FIELD_COMBO, "halign"); halign_field->add_combo_item("Left", Qt::AlignLeft); halign_field->add_combo_item("Center", Qt::AlignHCenter); halign_field->add_combo_item("Right", Qt::AlignRight); - halign_field->add_combo_item("Justify", Qt::AlignJustify); - halign_field->id = "halign"; + halign_field->add_combo_item("Justify", Qt::AlignJustify); - valign_field = alignment_row->add_field(EFFECT_FIELD_COMBO); + valign_field = alignment_row->add_field(EFFECT_FIELD_COMBO, "valign"); valign_field->add_combo_item("Top", Qt::AlignTop); valign_field->add_combo_item("Center", Qt::AlignVCenter); - valign_field->add_combo_item("Bottom", Qt::AlignBottom); - valign_field->id = "valign"; + valign_field->add_combo_item("Bottom", Qt::AlignBottom); - word_wrap_field = add_row("Word Wrap:")->add_field(EFFECT_FIELD_BOOL, 2); - word_wrap_field->id = "wordwrap"; + word_wrap_field = add_row("Word Wrap:")->add_field(EFFECT_FIELD_BOOL, "wordwrap", 2); - outline_bool = add_row("Outline:")->add_field(EFFECT_FIELD_BOOL, 2); - outline_bool->id = "outline"; - outline_color = add_row("Outline Color:")->add_field(EFFECT_FIELD_COLOR, 2); - outline_color->id = "outlinecolor"; - outline_width = add_row("Outline Width:")->add_field(EFFECT_FIELD_DOUBLE, 2); - outline_width->id = "outlinewidth"; + outline_bool = add_row("Outline:")->add_field(EFFECT_FIELD_BOOL, "outline", 2); + outline_color = add_row("Outline Color:")->add_field(EFFECT_FIELD_COLOR, "outlinecolor", 2); + outline_width = add_row("Outline Width:")->add_field(EFFECT_FIELD_DOUBLE, "outlinewidth", 2); outline_width->set_double_minimum_value(0); - shadow_bool = add_row("Shadow:")->add_field(EFFECT_FIELD_BOOL, 2); - shadow_bool->id = "shadow"; - shadow_color = add_row("Shadow Color:")->add_field(EFFECT_FIELD_COLOR, 2); - shadow_color->id = "shadowcolor"; - shadow_distance = add_row("Shadow Distance:")->add_field(EFFECT_FIELD_DOUBLE, 2); - shadow_distance->id = "shadowdistance"; + shadow_bool = add_row("Shadow:")->add_field(EFFECT_FIELD_BOOL, "shadow", 2); + shadow_color = add_row("Shadow Color:")->add_field(EFFECT_FIELD_COLOR, "shadowcolor", 2); + shadow_distance = add_row("Shadow Distance:")->add_field(EFFECT_FIELD_DOUBLE, "shadowdistance", 2); shadow_distance->set_double_minimum_value(0); - shadow_softness = add_row("Shadow Softness:")->add_field(EFFECT_FIELD_DOUBLE, 2); - shadow_softness->id = "shadowsoftness"; + shadow_softness = add_row("Shadow Softness:")->add_field(EFFECT_FIELD_DOUBLE, "shadowsoftness", 2); shadow_softness->set_double_minimum_value(0); - shadow_opacity = add_row("Shadow Opacity:")->add_field(EFFECT_FIELD_DOUBLE, 2); - shadow_opacity->id = "shadowopacity"; + shadow_opacity = add_row("Shadow Opacity:")->add_field(EFFECT_FIELD_DOUBLE, "shadowopacity", 2); shadow_opacity->set_double_minimum_value(0); shadow_opacity->set_double_maximum_value(100); diff --git a/effects/internal/toneeffect.cpp b/effects/internal/toneeffect.cpp index 66e24ab17..873a70817 100644 --- a/effects/internal/toneeffect.cpp +++ b/effects/internal/toneeffect.cpp @@ -9,24 +9,20 @@ #include "debug.h" ToneEffect::ToneEffect(Clip* c, const EffectMeta *em) : Effect(c, em), sinX(INT_MIN) { - type_val = add_row("Type:")->add_field(EFFECT_FIELD_COMBO); - type_val->id = "type"; + type_val = add_row("Type:")->add_field(EFFECT_FIELD_COMBO, "type"); type_val->add_combo_item("Sine", TONE_TYPE_SINE); - freq_val = add_row("Frequency:")->add_field(EFFECT_FIELD_DOUBLE); - freq_val->id = "frequency"; + freq_val = add_row("Frequency:")->add_field(EFFECT_FIELD_DOUBLE, "frequency"); freq_val->set_double_minimum_value(20); freq_val->set_double_maximum_value(20000); freq_val->set_double_default_value(1000); - amount_val = add_row("Amount:")->add_field(EFFECT_FIELD_DOUBLE); - amount_val->id = "amount"; + amount_val = add_row("Amount:")->add_field(EFFECT_FIELD_DOUBLE, "amount"); amount_val->set_double_minimum_value(0); amount_val->set_double_maximum_value(100); amount_val->set_double_default_value(25); - mix_val = add_row("Mix:")->add_field(EFFECT_FIELD_BOOL); - mix_val->id = "mix"; + mix_val = add_row("Mix:")->add_field(EFFECT_FIELD_BOOL, "mix"); mix_val->set_bool_value(true); connect(freq_val, SIGNAL(changed()), this, SLOT(field_changed())); diff --git a/effects/internal/transformeffect.cpp b/effects/internal/transformeffect.cpp index 1884d818c..894b291e2 100644 --- a/effects/internal/transformeffect.cpp +++ b/effects/internal/transformeffect.cpp @@ -26,44 +26,34 @@ TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em) enable_coords = true; EffectRow* position_row = add_row("Position:"); - position_x = position_row->add_field(EFFECT_FIELD_DOUBLE); // position X - position_x->id = "posx"; - position_y = position_row->add_field(EFFECT_FIELD_DOUBLE); // position Y - position_y->id = "posy"; + 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("Scale:"); - scale_x = scale_row->add_field(EFFECT_FIELD_DOUBLE); // scale X (and Y is uniform scale is selected) - scale_x->id = "scalex"; + 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); // scale Y (disabled if uniform scale is selected) - scale_y->id = "scaley"; + 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("Uniform Scale:"); - uniform_scale_field = uniform_scale_row->add_field(EFFECT_FIELD_BOOL); // uniform scale option - uniform_scale_field->id = "uniformscale"; + uniform_scale_field = uniform_scale_row->add_field(EFFECT_FIELD_BOOL, "uniformscale"); // uniform scale option EffectRow* rotation_row = add_row("Rotation:"); - rotation = rotation_row->add_field(EFFECT_FIELD_DOUBLE); - rotation->id = "rotation"; + rotation = rotation_row->add_field(EFFECT_FIELD_DOUBLE, "rotation"); EffectRow* anchor_point_row = add_row("Anchor Point:"); - anchor_x_box = anchor_point_row->add_field(EFFECT_FIELD_DOUBLE); // anchor point X - anchor_x_box->id = "anchorx"; - anchor_y_box = anchor_point_row->add_field(EFFECT_FIELD_DOUBLE); // anchor point Y - anchor_y_box->id = "anchory"; + 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("Opacity:"); - opacity = opacity_row->add_field(EFFECT_FIELD_DOUBLE); // opacity - opacity->id = "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("Blend Mode:"); - blend_mode_box = blend_mode_row->add_field(EFFECT_FIELD_COMBO); // blend mode - blend_mode_box->id = "blendmode"; + blend_mode_box = blend_mode_row->add_field(EFFECT_FIELD_COMBO, "blendmode"); // blend mode blend_mode_box->add_combo_item("Normal", BLEND_MODE_NORMAL); blend_mode_box->add_combo_item("Overlay", BLEND_MODE_OVERLAY); blend_mode_box->add_combo_item("Screen", BLEND_MODE_SCREEN); @@ -131,7 +121,7 @@ void TransformEffect::process_coords(double timecode, GLTextureCoords& coords, i coords.vertexBottomRightY -= anchor_y_offset; // rotation - glRotatef(rotation->get_double_value(timecode), 0, 0, 1); + glRotatef(rotation->get_double_value(timecode), 0, 0, 1); // scale float sx = scale_x->get_double_value(timecode)*0.01; diff --git a/effects/internal/volumeeffect.cpp b/effects/internal/volumeeffect.cpp index 8ea84e473..a876e810d 100644 --- a/effects/internal/volumeeffect.cpp +++ b/effects/internal/volumeeffect.cpp @@ -9,9 +9,8 @@ #include "ui/collapsiblewidget.h" VolumeEffect::VolumeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) { - EffectRow* volume_row = add_row("Volume:"); - volume_val = volume_row->add_field(EFFECT_FIELD_DOUBLE); - volume_val->id = "volume"; + EffectRow* volume_row = add_row("Volume:"); + volume_val = volume_row->add_field(EFFECT_FIELD_DOUBLE, "volume"); volume_val->set_double_minimum_value(0); // set defaults diff --git a/io/config.h b/io/config.h index fe3b68ce6..5259971a5 100644 --- a/io/config.h +++ b/io/config.h @@ -3,8 +3,8 @@ #include -#define SAVE_VERSION 181114 // YYMMDD -#define MIN_SAVE_VERSION 180820 // lowest compatible project version +#define SAVE_VERSION 181124 // YYMMDD +#define MIN_SAVE_VERSION 181114 // lowest compatible project version #define TIMECODE_DROP 0 #define TIMECODE_NONDROP 1 diff --git a/io/math.cpp b/io/math.cpp index 32a12db6e..c26bb5cad 100644 --- a/io/math.cpp +++ b/io/math.cpp @@ -6,6 +6,10 @@ int lerp(int a, int b, double t) { return qRound(((1.0 - t) * a) + (t * b)); } +float float_lerp(float a, float b, float t) { + return ((1.0F - t) * a) + (t * b); +} + double double_lerp(double a, double b, double t) { return ((1.0 - t) * a) + (t * b); } diff --git a/io/math.h b/io/math.h index 68264cff7..927e988ac 100644 --- a/io/math.h +++ b/io/math.h @@ -2,6 +2,7 @@ #define MATH_H int lerp(int a, int b, double t); +float float_lerp(float a, float b, float t); double double_lerp(double a, double b, double t); #endif // MATH_H diff --git a/olive.pro b/olive.pro index 4e45e4ea8..f81d7e964 100644 --- a/olive.pro +++ b/olive.pro @@ -1,189 +1,189 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2018-05-11T10:31:59 -# -#------------------------------------------------- - -QT += core gui multimedia opengl - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = Olive -TEMPLATE = app - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - - -SOURCES += \ - main.cpp \ - mainwindow.cpp \ - panels/project.cpp \ - panels/effectcontrols.cpp \ - panels/viewer.cpp \ - panels/timeline.cpp \ - ui/sourcetable.cpp \ - dialogs/aboutdialog.cpp \ - ui/timelinewidget.cpp \ - io/media.cpp \ - project/sequence.cpp \ - project/clip.cpp \ - playback/playback.cpp \ - playback/audio.cpp \ - io/config.cpp \ - dialogs/newsequencedialog.cpp \ - ui/viewerwidget.cpp \ - ui/viewercontainer.cpp \ - dialogs/exportdialog.cpp \ - ui/collapsiblewidget.cpp \ - panels/panels.cpp \ - playback/cacher.cpp \ - io/exportthread.cpp \ - ui/timelineheader.cpp \ - io/previewgenerator.cpp \ - ui/labelslider.cpp \ - dialogs/preferencesdialog.cpp \ - ui/audiomonitor.cpp \ - project/undo.cpp \ - ui/scrollarea.cpp \ - ui/comboboxex.cpp \ - ui/colorbutton.cpp \ - dialogs/replaceclipmediadialog.cpp \ - ui/fontcombobox.cpp \ - ui/checkboxex.cpp \ - ui/keyframeview.cpp \ - ui/texteditex.cpp \ - dialogs/demonotice.cpp \ - project/marker.cpp \ - dialogs/speeddialog.cpp \ - dialogs/mediapropertiesdialog.cpp \ - io/crc32.cpp \ - dialogs/loaddialog.cpp \ - debug.cpp \ - io/path.cpp \ - effects/internal/linearfadetransition.cpp \ - effects/internal/transformeffect.cpp \ - effects/internal/solideffect.cpp \ - effects/internal/texteffect.cpp \ - effects/internal/audionoiseeffect.cpp \ - effects/internal/paneffect.cpp \ - effects/internal/toneeffect.cpp \ - effects/internal/volumeeffect.cpp \ - effects/internal/crossdissolvetransition.cpp \ - effects/internal/shakeeffect.cpp \ - effects/internal/exponentialfadetransition.cpp \ - effects/internal/logarithmicfadetransition.cpp \ - effects/internal/cornerpineffect.cpp \ - io/math.cpp \ - io/qpainterwrapper.cpp \ - project/effect.cpp \ - project/transition.cpp \ - project/effectrow.cpp \ - project/effectfield.cpp \ - effects/internal/cubetransition.cpp - -HEADERS += \ - mainwindow.h \ - panels/project.h \ - panels/effectcontrols.h \ - panels/viewer.h \ - panels/timeline.h \ - ui/sourcetable.h \ - dialogs/aboutdialog.h \ - ui/timelinewidget.h \ - io/media.h \ - project/sequence.h \ - project/clip.h \ - playback/playback.h \ - playback/audio.h \ - io/config.h \ - dialogs/newsequencedialog.h \ - ui/viewerwidget.h \ - ui/viewercontainer.h \ - dialogs/exportdialog.h \ - ui/collapsiblewidget.h \ - panels/panels.h \ - playback/cacher.h \ - io/exportthread.h \ - ui/timelinetools.h \ - ui/timelineheader.h \ - io/previewgenerator.h \ - ui/labelslider.h \ - dialogs/preferencesdialog.h \ - ui/audiomonitor.h \ - project/undo.h \ - ui/scrollarea.h \ - ui/comboboxex.h \ - ui/colorbutton.h \ - dialogs/replaceclipmediadialog.h \ - ui/fontcombobox.h \ - ui/checkboxex.h \ - ui/keyframeview.h \ - ui/texteditex.h \ - dialogs/demonotice.h \ - project/marker.h \ - project/selection.h \ - dialogs/speeddialog.h \ - dialogs/mediapropertiesdialog.h \ - io/crc32.h \ - dialogs/loaddialog.h \ - debug.h \ - io/path.h \ - effects/internal/transformeffect.h \ - effects/internal/solideffect.h \ - effects/internal/texteffect.h \ - effects/internal/audionoiseeffect.h \ - effects/internal/paneffect.h \ - effects/internal/toneeffect.h \ - effects/internal/volumeeffect.h \ - effects/internal/shakeeffect.h \ - effects/internal/linearfadetransition.h \ - effects/internal/crossdissolvetransition.h \ - effects/internal/exponentialfadetransition.h \ - effects/internal/logarithmicfadetransition.h \ - effects/internal/cornerpineffect.h \ - io/math.h \ - io/qpainterwrapper.h \ - project/effect.h \ - project/transition.h \ - project/effectrow.h \ - project/effectfield.h \ - effects/internal/cubetransition.h - -FORMS += \ - mainwindow.ui \ - panels/project.ui \ - panels/effectcontrols.ui \ - panels/viewer.ui \ - panels/timeline.ui \ - dialogs/aboutdialog.ui \ - dialogs/newsequencedialog.ui \ - dialogs/exportdialog.ui \ - dialogs/preferencesdialog.ui \ - dialogs/demonotice.ui - -win32 { - RC_FILE = icons/resources.rc - LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -lopengl32 -} - -mac { - LIBS += -L/usr/local/lib -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample - ICON = icons/olive.icns - INCLUDEPATH = /usr/local/include -} - -linux { - LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -} - -RESOURCES += \ - icons/icons.qrc +#------------------------------------------------- +# +# Project created by QtCreator 2018-05-11T10:31:59 +# +#------------------------------------------------- + +QT += core gui multimedia opengl + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = Olive +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + panels/project.cpp \ + panels/effectcontrols.cpp \ + panels/viewer.cpp \ + panels/timeline.cpp \ + ui/sourcetable.cpp \ + dialogs/aboutdialog.cpp \ + ui/timelinewidget.cpp \ + io/media.cpp \ + project/sequence.cpp \ + project/clip.cpp \ + playback/playback.cpp \ + playback/audio.cpp \ + io/config.cpp \ + dialogs/newsequencedialog.cpp \ + ui/viewerwidget.cpp \ + ui/viewercontainer.cpp \ + dialogs/exportdialog.cpp \ + ui/collapsiblewidget.cpp \ + panels/panels.cpp \ + playback/cacher.cpp \ + io/exportthread.cpp \ + ui/timelineheader.cpp \ + io/previewgenerator.cpp \ + ui/labelslider.cpp \ + dialogs/preferencesdialog.cpp \ + ui/audiomonitor.cpp \ + project/undo.cpp \ + ui/scrollarea.cpp \ + ui/comboboxex.cpp \ + ui/colorbutton.cpp \ + dialogs/replaceclipmediadialog.cpp \ + ui/fontcombobox.cpp \ + ui/checkboxex.cpp \ + ui/keyframeview.cpp \ + ui/texteditex.cpp \ + dialogs/demonotice.cpp \ + project/marker.cpp \ + dialogs/speeddialog.cpp \ + dialogs/mediapropertiesdialog.cpp \ + io/crc32.cpp \ + dialogs/loaddialog.cpp \ + debug.cpp \ + io/path.cpp \ + effects/internal/linearfadetransition.cpp \ + effects/internal/transformeffect.cpp \ + effects/internal/solideffect.cpp \ + effects/internal/texteffect.cpp \ + effects/internal/audionoiseeffect.cpp \ + effects/internal/paneffect.cpp \ + effects/internal/toneeffect.cpp \ + effects/internal/volumeeffect.cpp \ + effects/internal/crossdissolvetransition.cpp \ + effects/internal/shakeeffect.cpp \ + effects/internal/exponentialfadetransition.cpp \ + effects/internal/logarithmicfadetransition.cpp \ + effects/internal/cornerpineffect.cpp \ + io/math.cpp \ + io/qpainterwrapper.cpp \ + project/effect.cpp \ + project/transition.cpp \ + project/effectrow.cpp \ + project/effectfield.cpp \ + effects/internal/cubetransition.cpp + +HEADERS += \ + mainwindow.h \ + panels/project.h \ + panels/effectcontrols.h \ + panels/viewer.h \ + panels/timeline.h \ + ui/sourcetable.h \ + dialogs/aboutdialog.h \ + ui/timelinewidget.h \ + io/media.h \ + project/sequence.h \ + project/clip.h \ + playback/playback.h \ + playback/audio.h \ + io/config.h \ + dialogs/newsequencedialog.h \ + ui/viewerwidget.h \ + ui/viewercontainer.h \ + dialogs/exportdialog.h \ + ui/collapsiblewidget.h \ + panels/panels.h \ + playback/cacher.h \ + io/exportthread.h \ + ui/timelinetools.h \ + ui/timelineheader.h \ + io/previewgenerator.h \ + ui/labelslider.h \ + dialogs/preferencesdialog.h \ + ui/audiomonitor.h \ + project/undo.h \ + ui/scrollarea.h \ + ui/comboboxex.h \ + ui/colorbutton.h \ + dialogs/replaceclipmediadialog.h \ + ui/fontcombobox.h \ + ui/checkboxex.h \ + ui/keyframeview.h \ + ui/texteditex.h \ + dialogs/demonotice.h \ + project/marker.h \ + project/selection.h \ + dialogs/speeddialog.h \ + dialogs/mediapropertiesdialog.h \ + io/crc32.h \ + dialogs/loaddialog.h \ + debug.h \ + io/path.h \ + effects/internal/transformeffect.h \ + effects/internal/solideffect.h \ + effects/internal/texteffect.h \ + effects/internal/audionoiseeffect.h \ + effects/internal/paneffect.h \ + effects/internal/toneeffect.h \ + effects/internal/volumeeffect.h \ + effects/internal/shakeeffect.h \ + effects/internal/linearfadetransition.h \ + effects/internal/crossdissolvetransition.h \ + effects/internal/exponentialfadetransition.h \ + effects/internal/logarithmicfadetransition.h \ + effects/internal/cornerpineffect.h \ + io/math.h \ + io/qpainterwrapper.h \ + project/effect.h \ + project/transition.h \ + project/effectrow.h \ + project/effectfield.h \ + effects/internal/cubetransition.h + +FORMS += \ + mainwindow.ui \ + panels/project.ui \ + panels/effectcontrols.ui \ + panels/viewer.ui \ + panels/timeline.ui \ + dialogs/aboutdialog.ui \ + dialogs/newsequencedialog.ui \ + dialogs/exportdialog.ui \ + dialogs/preferencesdialog.ui \ + dialogs/demonotice.ui + +win32 { + RC_FILE = icons/resources.rc + LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -lopengl32 +} + +mac { + LIBS += -L/usr/local/lib -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample + ICON = icons/olive.icns + INCLUDEPATH = /usr/local/include +} + +linux { + LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample +} + +RESOURCES += \ + icons/icons.qrc diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 095c25e06..727fa3bf5 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -68,10 +68,10 @@ void EffectControls::menu_select(QAction* q) { const EffectMeta* meta = reinterpret_cast(q->data().value()); if (transition_menu) { if (c->get_opening_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, meta, TA_OPENING_TRANSITION, 30)); + ca->append(new AddTransitionCommand(c, NULL, NULL, meta, TA_OPENING_TRANSITION, 30)); } if (c->get_closing_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, meta, TA_CLOSING_TRANSITION, 30)); + ca->append(new AddTransitionCommand(c, NULL, NULL, meta, TA_CLOSING_TRANSITION, 30)); } } else { ca->append(new AddEffectCommand(c, meta)); diff --git a/panels/project.cpp b/panels/project.cpp index 1794edcf7..74228c232 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -808,6 +808,102 @@ QTreeWidgetItem* Project::find_loaded_folder_by_id(int id) { return NULL; } +const EffectMeta* get_meta_from_name(const QString& name, int type) { + QVector& effect_list = (type == EFFECT_TYPE_VIDEO) ? video_effects : audio_effects; + for (int j=0;jtrack < 0) ? "Transform" : "Volume"; break; + case 1: effect_name = (c->track < 0) ? "Shake" : "Pan"; break; + case 2: effect_name = (c->track < 0) ? "Text" : "Noise"; break; + case 3: effect_name = (c->track < 0) ? "Solid" : "Tone"; break; + case 4: effect_name = "Invert"; break; + case 5: effect_name = "Chroma Key"; break; + case 6: effect_name = "Gaussian Blur"; break; + case 7: effect_name = "Crop"; break; + case 8: effect_name = "Flip"; break; + case 9: effect_name = "Box Blur"; break; + case 10: effect_name = "Wave"; break; + case 11: effect_name = "Temperature"; break; + } + } + + // wait for effects to be loaded + effects_loaded.lock(); + + const EffectMeta* meta = NULL; + + // find effect with this name + if (!effect_name.isEmpty()) { + meta = get_meta_from_name(effect_name, (c->track < 0) ? EFFECT_TYPE_VIDEO : EFFECT_TYPE_AUDIO); + } + + effects_loaded.unlock(); + + if (meta == NULL) { + dout << "[WARNING] An effect used by this project is missing. It was not loaded."; + } else { + QString tag = stream.name().toString(); + + if (tag == "opening" || tag == "closing") { + // TODO replace NULL/s with something else + + int transition_index = create_transition(c, NULL, meta); + Transition* t = c->sequence->transitions.at(transition_index); + if (effect_length > -1) t->length = effect_length; + t->set_enabled(effect_enabled); + t->load(stream); + + if (tag == "opening") { + c->opening_transition = transition_index; + } else { + c->closing_transition = transition_index; + } + } else { + Effect* e = create_effect(c, meta); + e->set_enabled(effect_enabled); + e->load(stream); + + c->effects.append(e); + } + } +} + +struct TransitionData { + int id; + QString name; + long length; + Clip* otc; + Clip* ctc; +}; + bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) { f.seek(0); stream.setDevice(stream.device()); @@ -968,6 +1064,8 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) { } } + QVector transition_data; + // load all clips and clip information while (!(stream.name() == child_search && stream.isEndElement()) && !stream.atEnd()) { stream.readNextStartElement(); @@ -982,7 +1080,22 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) { } } s->markers.append(m); - } else if (stream.name() == "clip" && stream.isStartElement()) { + } else if (stream.name() == "transition" && stream.isStartElement()) { + TransitionData td; + td.otc = NULL; + td.ctc = NULL; + for (int j=0;jmaintain_audio_pitch = (attr.value() == "1"); } else if (attr.name() == "reverse") { c->reverse = (attr.value() == "1"); + } else if (attr.name() == "opening") { + c->opening_transition = attr.value().toInt(); + } else if (attr.name() == "closing") { + c->closing_transition = attr.value().toInt(); } else if (attr.name() == "sequence") { c->media_type = MEDIA_TYPE_SEQUENCE; @@ -1072,87 +1189,9 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) { } } } - } else if (stream.isStartElement() && (stream.name() == "effect" || stream.name() == "opening" || stream.name() == "closing")) { - int effect_id = -1; - QString effect_name; - bool effect_enabled = true; - long effect_length = -1; - for (int j=0;jtrack < 0) ? "Transform" : "Volume"; break; - case 1: effect_name = (c->track < 0) ? "Shake" : "Pan"; break; - case 2: effect_name = (c->track < 0) ? "Text" : "Noise"; break; - case 3: effect_name = (c->track < 0) ? "Solid" : "Tone"; break; - case 4: effect_name = "Invert"; break; - case 5: effect_name = "Chroma Key"; break; - case 6: effect_name = "Gaussian Blur"; break; - case 7: effect_name = "Crop"; break; - case 8: effect_name = "Flip"; break; - case 9: effect_name = "Box Blur"; break; - case 10: effect_name = "Wave"; break; - case 11: effect_name = "Temperature"; break; - } - } - - // wait for effects to be loaded - effects_loaded.lock(); - - const EffectMeta* meta = NULL; - - // find effect with this name - if (!effect_name.isEmpty()) { - QVector& effect_list = (c->track < 0) ? video_effects : audio_effects; - for (int j=0;jsequence->transitions.at(transition_index); - if (effect_length > -1) t->length = effect_length; - t->set_enabled(effect_enabled); - t->load(stream); - - if (tag == "opening") { - c->opening_transition = transition_index; - } else { - c->closing_transition = transition_index; - } - } else { - Effect* e = create_effect(c, meta); - e->set_enabled(effect_enabled); - e->load(stream); - - c->effects.append(e); - } - } + } else if (stream.isStartElement() && (stream.name() == "effect" || stream.name() == "opening" || stream.name() == "closing")) { + // "opening" and "closing" are backwards compatibility code + load_effect(stream, c); } } } @@ -1161,8 +1200,8 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) { } } - // correct links and clip IDs - for (int i=0;iclips.size();i++) { + // correct links, clip IDs, transitions + for (int i=0;iclips.size();i++) { // correct links Clip* correct_clip = s->clips.at(i); for (int j=0;jlinked.size();j++) { @@ -1183,6 +1222,44 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) { } } } + + // re-link clips to transitions + if (correct_clip->opening_transition > -1) { + for (int j=0;jopening_transition) { + transition_data[j].otc = correct_clip; + } + } + } + if (correct_clip->closing_transition > -1) { + for (int j=0;jclosing_transition) { + transition_data[j].ctc = correct_clip; + } + } + } + } + + // create transitions + for (int i=0;itrack < 0) ? EFFECT_TYPE_VIDEO : EFFECT_TYPE_AUDIO); + if (meta == NULL) { + dout << "[WARNING] Failed to link transition with name:" << td.name; + if (td.otc != NULL) td.otc->opening_transition = -1; + if (td.ctc != NULL) td.ctc->closing_transition = -1; + } else { + int transition_index = create_transition(primary, secondary, meta); + primary->sequence->transitions.at(transition_index)->length = td.length; + if (td.otc != NULL) td.otc->opening_transition = transition_index; + if (td.ctc != NULL) td.ctc->closing_transition = transition_index; + } } new_sequence(NULL, s, false, parent); @@ -1414,6 +1491,17 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int stream.writeAttribute("workarea", QString::number(s->using_workarea)); stream.writeAttribute("workareaIn", QString::number(s->workarea_in)); stream.writeAttribute("workareaOut", QString::number(s->workarea_out)); + + for (int j=0;jtransitions.size();j++) { + Transition* t = s->transitions.at(j); + if (t != NULL) { + stream.writeStartElement("transition"); + stream.writeAttribute("id", QString::number(j)); + t->save(stream); + stream.writeEndElement(); // transition + } + } + for (int j=0;jclips.size();j++) { Clip* c = s->clips.at(j); if (c != NULL) { @@ -1425,6 +1513,8 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int stream.writeAttribute("in", QString::number(c->timeline_in)); stream.writeAttribute("out", QString::number(c->timeline_out)); stream.writeAttribute("track", QString::number(c->track)); + stream.writeAttribute("opening", QString::number(c->opening_transition)); + stream.writeAttribute("closing", QString::number(c->closing_transition)); stream.writeAttribute("r", QString::number(c->color_r)); stream.writeAttribute("g", QString::number(c->color_g)); @@ -1458,19 +1548,7 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int stream.writeStartElement("effect"); // effect c->effects.at(k)->save(stream); stream.writeEndElement(); // effect - } - - if (c->get_opening_transition() != NULL) { - stream.writeStartElement("opening"); - c->get_opening_transition()->save(stream); - stream.writeEndElement(); // opening - } - - if (c->get_closing_transition() != NULL) { - stream.writeStartElement("closing"); // closing - c->get_closing_transition()->save(stream); - stream.writeEndElement(); // closing - } + } stream.writeEndElement(); // clip } diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 9d041f484..4d9ce5b6e 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -355,11 +355,11 @@ void Timeline::add_transition() { Clip* c = sequence->clips.at(i); if (c != NULL && is_clip_selected(c, true)) { if (c->get_opening_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE), TA_OPENING_TRANSITION, 30)); + ca->append(new AddTransitionCommand(c, NULL, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE), TA_OPENING_TRANSITION, 30)); adding = true; } if (c->get_closing_transition() == NULL) { - ca->append(new AddTransitionCommand(c, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE), TA_OPENING_TRANSITION, 30)); + ca->append(new AddTransitionCommand(c, NULL, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE), TA_OPENING_TRANSITION, 30)); adding = true; } } @@ -634,7 +634,7 @@ Clip* Timeline::split_clip(ComboAction* ca, int p, long frame, long post_in) { post->timeline_in = post_in; post->clip_in = pre->clip_in + (post->timeline_in - pre->timeline_in); - ca->append(new MoveClipAction(pre, pre->timeline_in, frame, pre->clip_in, pre->track)); + move_clip(ca, pre, pre->timeline_in, frame, pre->clip_in, pre->track); if (pre->get_opening_transition() != NULL) { /*if (frame < pre->timeline_in + pre->get_opening_transition()->length && pre->get_opening_transition()->secondary_clip != NULL) { @@ -792,7 +792,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area post_clips.append(post); } else if (c->timeline_in < s.in && c->timeline_out > s.in) { // only out point is in deletion area - ca->append(new MoveClipAction(c, c->timeline_in, s.in, c->clip_in, c->track)); + move_clip(ca, c, c->timeline_in, s.in, c->clip_in, c->track); if (c->get_closing_transition() != NULL) { if (s.in < c->timeline_out - c->get_closing_transition()->length) { @@ -803,7 +803,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector& area } } else if (c->timeline_in < s.out && c->timeline_out > s.out) { // only in point is in deletion area - ca->append(new MoveClipAction(c, s.out, c->timeline_out, c->clip_in + (s.out - c->timeline_in), c->track)); + move_clip(ca, c, s.out, c->timeline_out, c->clip_in + (s.out - c->timeline_in), c->track); if (c->get_opening_transition() != NULL) { if (s.out > c->timeline_in + c->get_opening_transition()->length) { @@ -1075,7 +1075,7 @@ bool Timeline::split_selection(ComboAction* ca) { split_A->sequence->hard_delete_transition(split_A, TA_CLOSING_TRANSITION); } - ca->append(new MoveClipAction(clip, clip->timeline_in, s.in, clip->clip_in, clip->track)); + move_clip(ca, clip, clip->timeline_in, s.in, clip->clip_in, clip->track); split = true; } else { Clip* post_a = split_clip(ca, j, s.in); @@ -1489,3 +1489,21 @@ void Timeline::transition_menu_select(QAction* a) { tool = TIMELINE_TOOL_TRANSITION; ui->toolTransitionButton->setChecked(true); } + +void move_clip(ComboAction* ca, Clip *c, long iin, long iout, long iclip_in, int itrack, bool verify_transitions) { + ca->append(new MoveClipAction(c, iin, iout, iclip_in, itrack)); + + if (verify_transitions) { + if (c->get_opening_transition() != NULL && c->get_opening_transition()->secondary_clip != NULL && c->get_opening_transition()->secondary_clip->timeline_out != iin) { + // separate transition + ca->append(new SetPointer((void**) &c->get_opening_transition()->secondary_clip, NULL)); + ca->append(new AddTransitionCommand(c->get_opening_transition()->secondary_clip, NULL, c->get_opening_transition(), NULL, TA_CLOSING_TRANSITION, 0)); + } + + if (c->get_closing_transition() != NULL && c->get_closing_transition()->secondary_clip != NULL && c->get_closing_transition()->parent_clip->timeline_in != iout) { + // separate transition + ca->append(new SetPointer((void**) &c->get_closing_transition()->secondary_clip, NULL)); + ca->append(new AddTransitionCommand(c, NULL, c->get_closing_transition(), NULL, TA_CLOSING_TRANSITION, 0)); + } + } +} diff --git a/panels/timeline.h b/panels/timeline.h index 96c2f97be..a218ae2cd 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -34,6 +34,7 @@ int getScreenPointFromFrame(double zoom, long frame); long getFrameFromScreenPoint(double zoom, int x); void draw_selection_rectangle(QPainter& painter, const QRect& rect); bool selection_contains_transition(const Selection& s, Clip* c, int type); +void move_clip(ComboAction *ca, Clip *c, long iin, long iout, long iclip_in, int itrack, bool verify_transitions = true); struct Ghost { int clip; diff --git a/project/clip.cpp b/project/clip.cpp index 1cfcb71c6..d136f666c 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -293,11 +293,11 @@ int Clip::getHeight() { void Clip::refactor_frame_rate(ComboAction* ca, double multiplier, bool change_timeline_points) { if (change_timeline_points) { - ca->append(new MoveClipAction(this, - qRound((double) timeline_in * multiplier), - qRound((double) timeline_out * multiplier), - qRound((double) clip_in * multiplier), - track)); + move_clip(ca, this, + qRound((double) timeline_in * multiplier), + qRound((double) timeline_out * multiplier), + qRound((double) clip_in * multiplier), + track); } for (int i=0;ifilename << "- ID cannot be empty."; } else if (type > -1) { - EffectField* field = row->add_field(type); - field->id = id; + EffectField* field = row->add_field(type, id); connect(field, SIGNAL(changed()), this, SLOT(field_changed())); switch (type) { case EFFECT_FIELD_DOUBLE: diff --git a/project/effect.h b/project/effect.h index d91a1d24e..0caf160ce 100644 --- a/project/effect.h +++ b/project/effect.h @@ -63,7 +63,6 @@ extern QMutex effects_loaded; - #define EFFECT_INTERNAL_CORNERPIN 12 #define EFFECT_INTERNAL_COUNT 13 @@ -76,21 +75,29 @@ struct GLTextureCoords { int vertexTopLeftX; int vertexTopLeftY; + int vertexTopLeftZ; int vertexTopRightX; int vertexTopRightY; + int vertexTopRightZ; int vertexBottomLeftX; int vertexBottomLeftY; + int vertexBottomLeftZ; int vertexBottomRightX; int vertexBottomRightY; + int vertexBottomRightZ; - double textureTopLeftX; - double textureTopLeftY; - double textureTopRightX; - double textureTopRightY; - double textureBottomRightX; - double textureBottomRightY; - double textureBottomLeftX; - double textureBottomLeftY; + float textureTopLeftX; + float textureTopLeftY; + float textureTopLeftQ; + float textureTopRightX; + float textureTopRightY; + float textureTopRightQ; + float textureBottomRightX; + float textureBottomRightY; + float textureBottomRightQ; + float textureBottomLeftX; + float textureBottomLeftY; + float textureBottomLeftQ; }; qint16 mix_audio_sample(qint16 a, qint16 b); diff --git a/project/effectfield.cpp b/project/effectfield.cpp index 51f8331c5..f2893f97f 100644 --- a/project/effectfield.cpp +++ b/project/effectfield.cpp @@ -17,7 +17,7 @@ #include "io/math.h" #include -EffectField::EffectField(EffectRow *parent, int t) : parent_row(parent), type(t) { +EffectField::EffectField(EffectRow *parent, int t, const QString &i) : parent_row(parent), type(t), id(i) { switch (t) { case EFFECT_FIELD_DOUBLE: { diff --git a/project/effectfield.h b/project/effectfield.h index 7c61ee967..c94d6a3fb 100644 --- a/project/effectfield.h +++ b/project/effectfield.h @@ -17,7 +17,7 @@ class EffectRow; class EffectField : public QObject { Q_OBJECT public: - EffectField(EffectRow* parent, int t); + EffectField(EffectRow* parent, int t, const QString& i); EffectRow* parent_row; int type; QString id; diff --git a/project/effectrow.cpp b/project/effectrow.cpp index c4fd58f11..0772162f0 100644 --- a/project/effectrow.cpp +++ b/project/effectrow.cpp @@ -144,8 +144,8 @@ void EffectRow::goto_next_key() { if (key != LONG_MAX) panel_sequence_viewer->seek(key); } -EffectField* EffectRow::add_field(int type, int colspan) { - EffectField* field = new EffectField(this, type); +EffectField* EffectRow::add_field(int type, const QString& id, int colspan) { + EffectField* field = new EffectField(this, type, id); fields.append(field); QWidget* element = field->get_ui_element(); ui->addWidget(element, ui_row, fields.size(), 1, colspan); diff --git a/project/effectrow.h b/project/effectrow.h index f74940326..5a6305a09 100644 --- a/project/effectrow.h +++ b/project/effectrow.h @@ -16,7 +16,7 @@ class EffectRow : public QObject { public: EffectRow(Effect* parent, QGridLayout* uilayout, const QString& n, int row); ~EffectRow(); - EffectField* add_field(int type, int colspan = 1); + EffectField* add_field(int type, const QString &id, int colspan = 1); EffectField* field(int i); int fieldCount(); void set_keyframe_now(bool undoable); diff --git a/project/transition.cpp b/project/transition.cpp index 23d12fa6d..51467c14e 100644 --- a/project/transition.cpp +++ b/project/transition.cpp @@ -14,7 +14,7 @@ #include Transition::Transition(Clip* c, Clip* s, const EffectMeta* em) : Effect(c, em), secondary_clip(s) { - add_row("Length:")->add_field(EFFECT_FIELD_DOUBLE); + //add_row("Length:")->add_field(EFFECT_FIELD_DOUBLE); } int Transition::copy(Clip *c, Clip* s) { diff --git a/project/undo.cpp b/project/undo.cpp index 0b514d4cb..22c1f8a0b 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -224,9 +224,10 @@ void AddEffectCommand::redo() { mainWindow->setWindowModified(true); } -AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, const EffectMeta *itransition, int itype, int ilength) : +AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, Transition* copy, const EffectMeta *itransition, int itype, int ilength) : clip(c), secondary(s), + transition_to_copy(copy), transition(itransition), type(itype), length(ilength), @@ -236,19 +237,36 @@ AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, const EffectMeta *i void AddTransitionCommand::undo() { clip->sequence->hard_delete_transition(clip, type); if (secondary != NULL) secondary->sequence->hard_delete_transition(secondary, (type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION); + + if (type == TA_OPENING_TRANSITION) { + clip->opening_transition = old_ptransition; + if (secondary != NULL) secondary->closing_transition = old_stransition; + } else { + clip->closing_transition = old_ptransition; + if (secondary != NULL) secondary->opening_transition = old_stransition; + } + mainWindow->setWindowModified(old_project_changed); } void AddTransitionCommand::redo() { if (type == TA_OPENING_TRANSITION) { - clip->opening_transition = create_transition(clip, secondary, transition); - if (secondary != NULL) secondary->closing_transition = clip->opening_transition; + old_ptransition = clip->opening_transition; + clip->opening_transition = (transition_to_copy == NULL) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, NULL); + if (secondary != NULL) { + old_stransition = secondary->closing_transition; + secondary->closing_transition = clip->opening_transition; + } if (length > 0) { clip->get_opening_transition()->length = length; } } else { - clip->closing_transition = create_transition(clip, secondary, transition); - if (secondary != NULL) secondary->opening_transition = clip->closing_transition; + old_ptransition = clip->closing_transition; + clip->closing_transition = (transition_to_copy == NULL) ? create_transition(clip, secondary, transition) : transition_to_copy->copy(clip, NULL); + if (secondary != NULL) { + old_stransition = secondary->opening_transition; + secondary->opening_transition = clip->closing_transition; + } if (length > 0) { clip->get_closing_transition()->length = length; } diff --git a/project/undo.h b/project/undo.h index bd8d1cf2e..e69c466ab 100644 --- a/project/undo.h +++ b/project/undo.h @@ -101,16 +101,19 @@ private: class AddTransitionCommand : public QUndoCommand { public: - AddTransitionCommand(Clip* c, Clip* s, const EffectMeta* itransition, int itype, int ilength); + AddTransitionCommand(Clip* c, Clip* s, Transition *copy, const EffectMeta* itransition, int itype, int ilength); void undo(); void redo(); private: Clip* clip; Clip* secondary; + Transition* transition_to_copy; const EffectMeta* transition; int type; int length; bool old_project_changed; + int old_ptransition; + int old_stransition; }; class ModifyTransitionCommand : public QUndoCommand { diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index da72080a6..0a56b83b4 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -934,7 +934,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { // step 3 - move clips Clip* c = sequence->clips.at(g.clip); if (g.transition == NULL) { - ca->append(new MoveClipAction(c, c->timeline_in + (g.in - g.old_in), c->timeline_out + (g.out - g.old_out), c->clip_in + (g.clip_in - g.old_clip_in), c->track + (g.track - g.old_track))); + move_clip(ca, c, c->timeline_in + (g.in - g.old_in), c->timeline_out + (g.out - g.old_out), c->clip_in + (g.clip_in - g.old_clip_in), c->track + (g.track - g.old_track)); // adjust transitions if we need to long new_clip_length = (g.out - g.in); @@ -971,13 +971,13 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { if (g.transition->secondary_clip != NULL) { if (g.in != g.old_in && !g.trimming) { long movement = g.in - g.old_in; - ca->append(new MoveClipAction(g.transition->parent_clip, g.transition->parent_clip->timeline_in + movement, g.transition->parent_clip->timeline_out, g.transition->parent_clip->clip_in + movement, g.transition->parent_clip->track)); - ca->append(new MoveClipAction(g.transition->secondary_clip, g.transition->secondary_clip->timeline_in, g.transition->secondary_clip->timeline_out + movement, g.transition->secondary_clip->clip_in, g.transition->secondary_clip->track)); + move_clip(ca, g.transition->parent_clip, g.transition->parent_clip->timeline_in + movement, g.transition->parent_clip->timeline_out, g.transition->parent_clip->clip_in + movement, g.transition->parent_clip->track, false); + move_clip(ca, g.transition->secondary_clip, g.transition->secondary_clip->timeline_in, g.transition->secondary_clip->timeline_out + movement, g.transition->secondary_clip->clip_in, g.transition->secondary_clip->track, false); } } else if (is_opening_transition) { if (g.in != g.old_in) { // if transition is going to make the clip bigger, make the clip bigger - ca->append(new MoveClipAction(c, c->timeline_in + (g.in - g.old_in), c->timeline_out, c->clip_in + (g.clip_in - g.old_clip_in), c->track)); + move_clip(ca, c, c->timeline_in + (g.in - g.old_in), c->timeline_out, c->clip_in + (g.clip_in - g.old_clip_in), c->track); clip_length -= (g.in - g.old_in); } @@ -985,7 +985,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { } else { if (g.out != g.old_out) { // if transition is going to make the clip bigger, make the clip bigger - ca->append(new MoveClipAction(c, c->timeline_in, c->timeline_out + (g.out - g.old_out), c->clip_in, c->track)); + move_clip(ca, c, c->timeline_in, c->timeline_out + (g.out - g.old_out), c->clip_in, c->track); clip_length += (g.out - g.old_out); } @@ -1053,14 +1053,14 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) { panel_timeline->delete_areas_and_relink(ca, areas); - if (move_post) ca->append(new MoveClipAction(post, qMin(transition_start, post->timeline_in), post->timeline_out, post->clip_in - (post->timeline_in - transition_start), post->track)); - if (move_pre) ca->append(new MoveClipAction(pre, pre->timeline_in, qMax(transition_end, pre->timeline_out), pre->clip_in, pre->track)); + if (move_post) move_clip(ca, post, qMin(transition_start, post->timeline_in), post->timeline_out, post->clip_in - (post->timeline_in - transition_start), post->track); + if (move_pre) move_clip(ca, pre, pre->timeline_in, qMax(transition_end, pre->timeline_out), pre->clip_in, pre->track); } if (panel_timeline->transition_tool_post_clip > -1) { - ca->append(new AddTransitionCommand(pre, post, panel_timeline->transition_tool_meta, TA_OPENING_TRANSITION, transition_end - pre->timeline_in)); + ca->append(new AddTransitionCommand(pre, post, NULL, panel_timeline->transition_tool_meta, TA_OPENING_TRANSITION, transition_end - pre->timeline_in)); } else { - ca->append(new AddTransitionCommand(pre, NULL, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - transition_start)); + ca->append(new AddTransitionCommand(pre, NULL, NULL, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - transition_start)); } push_undo = true; @@ -1124,9 +1124,14 @@ void TimelineWidget::init_ghosts() { Clip* c = sequence->clips.at(g.clip); g.track = g.old_track = c->track; - g.clip_in = g.old_clip_in = panel_timeline->tool == TIMELINE_TOOL_SLIP ? c->get_clip_in_with_transition() : c->clip_in; + g.clip_in = g.old_clip_in = c->clip_in; - if (g.transition == NULL) { + if (panel_timeline->tool == TIMELINE_TOOL_SLIP) { + g.clip_in = g.old_clip_in = c->get_clip_in_with_transition(); + g.in = g.old_in = c->get_timeline_in_with_transition(); + g.out = g.old_out = c->get_timeline_out_with_transition(); + g.ghost_length = g.old_out - g.old_in; + } else if (g.transition == NULL) { // this ghost is for a clip g.in = g.old_in = c->timeline_in; g.out = g.old_out = c->timeline_out; @@ -1153,6 +1158,42 @@ void TimelineWidget::init_ghosts() { } } +void validate_transitions(Clip* otc, Clip* ctc, long length, long& frame_diff) { + long validator; + if (otc != NULL) { + validator = otc->timeline_in + frame_diff; + if (validator < 0) frame_diff -= validator; // prevent from going below 0 on the timeline + + if (panel_timeline->transition_tool_post_clip > -1) { + validator = otc->clip_in + length - frame_diff; + if (validator < 0) frame_diff += validator; // prevent from going below 0 for the media + + validator = otc->clip_in + length + frame_diff - otc->getMaximumLength(); + if (validator > 0) frame_diff -= validator; // prevent transition from exceeding media length + } else { + validator = otc->clip_in + length + frame_diff; + if (validator < 0) frame_diff -= validator; // prevent from going below 0 for the media + if (validator > otc->getMaximumLength()) frame_diff -= (validator - otc->getMaximumLength()); // prevent transition from exceeding media length + } + } + + if (ctc != NULL) { + // prevent transition from exceeding media length + validator = ctc->clip_in + length + ctc->getLength() + frame_diff; + if (validator > ctc->getMaximumLength()) frame_diff -= (validator - ctc->getMaximumLength()); + + // prevent from going below 0 for the media + if (panel_timeline->transition_tool_post_clip > -1) { + validator = ctc->clip_in + length - ctc->getLength() + frame_diff; + if (validator > 0) frame_diff -= validator; + } + + // prevent from going below 0 on the timeline + validator = ctc->timeline_out + length + frame_diff; + if (validator < 0) frame_diff -= validator; + } +} + void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { int mouse_track = getTrackFromScreenPoint(mouse_pos.y()); long frame_diff = (lock_frame) ? 0 : panel_timeline->getTimelineFrameFromScreenPoint(mouse_pos.x()) - panel_timeline->drag_frame_start; @@ -1246,14 +1287,12 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { frame_diff = -frame_diff; } - validator = g.transition->parent_clip->get_clip_in_with_transition() - frame_diff; - if (validator < 0) frame_diff += validator; + // TESTING CODE + Clip* otc = g.transition->parent_clip; + Clip* ctc = g.transition->secondary_clip; - validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff - g.transition->secondary_clip->getMaximumLength(); - if (validator > 0) frame_diff -= validator; - - validator = g.transition->length + frame_diff - 1; - if (validator < 0) frame_diff -= validator; + validate_transitions(otc, ctc, g.transition->length, frame_diff); + // TESTING CODE END if (g.trim_in) { frame_diff = -frame_diff; @@ -1294,9 +1333,16 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { if (g.transition != NULL) { if (g.transition->secondary_clip != NULL) { // prevent dual transitions from going below 0 on the primary or above media length on the secondary + validator = g.transition->parent_clip->get_clip_in_with_transition() + frame_diff; if (validator < 0) frame_diff -= validator; + validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() - g.transition->get_length() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff; + if (validator < 0) frame_diff -= validator; + + validator = g.transition->parent_clip->clip_in + frame_diff - g.transition->parent_clip->getMaximumLength() + g.transition->length; + if (validator > 0) frame_diff -= validator; + validator = g.transition->secondary_clip->get_timeline_out_with_transition() - g.transition->secondary_clip->get_timeline_in_with_transition() + g.transition->secondary_clip->get_clip_in_with_transition() + frame_diff - g.transition->secondary_clip->getMaximumLength(); if (validator > 0) frame_diff -= validator; } else { @@ -1344,38 +1390,7 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) { ctc = temp; } - if (otc != NULL) { - validator = otc->timeline_in + frame_diff; - if (validator < 0) frame_diff -= validator; // prevent from going below 0 on the timeline - - if (panel_timeline->transition_tool_post_clip > -1) { - validator = otc->clip_in - frame_diff; - if (validator < 0) frame_diff += validator; // prevent from going below 0 for the media - - validator = otc->clip_in + frame_diff - otc->getMaximumLength(); - if (validator > 0) frame_diff -= validator; // prevent transition from exceeding media length - } else { - validator = otc->clip_in + frame_diff; - if (validator < 0) frame_diff -= validator; // prevent from going below 0 for the media - if (validator > otc->getMaximumLength()) frame_diff -= (validator - otc->getMaximumLength()); // prevent transition from exceeding media length - } - } - - if (ctc != NULL) { - validator = ctc->clip_in + ctc->getLength() + frame_diff; // prevent transition from exceeding media length - if (validator > ctc->getMaximumLength()) { - frame_diff -= (validator - ctc->getMaximumLength()); - } - - if (validator < 0) { // prevent from going below 0 for the media - frame_diff -= validator; - } - - validator = ctc->timeline_out + frame_diff; // prevent from going below 0 on the timeline - if (validator < 0) { - frame_diff -= validator; - } - } + validate_transitions(otc, ctc, 0, frame_diff); if (flipped) { frame_diff = -frame_diff; @@ -1614,7 +1629,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) { bool add = panel_timeline->is_clip_selected(c, true); // if a whole clip is not selected, maybe just a transition is - if (!add && panel_timeline->tool == TIMELINE_TOOL_POINTER && (c->get_opening_transition() != NULL || c->get_closing_transition() != NULL)) { + if (panel_timeline->tool == TIMELINE_TOOL_POINTER && (c->get_opening_transition() != NULL || c->get_closing_transition() != NULL)) { // check if any selections contain the whole clip or transition for (int j=0;jselections.size();j++) { const Selection& s = sequence->selections.at(j); @@ -2129,6 +2144,8 @@ void draw_transition(QPainter& p, Clip* c, const QRect& clip_rect, QRect& text_r p.fillRect(transition_rect, transition_color); QRect transition_text_rect(transition_rect.x() + CLIP_TEXT_PADDING, transition_rect.y() + CLIP_TEXT_PADDING, transition_rect.width() - CLIP_TEXT_PADDING, transition_rect.height() - CLIP_TEXT_PADDING); if (transition_text_rect.width() > MAX_TEXT_WIDTH) { + bool draw_text = true; + p.setPen(QColor(0, 0, 0, 96)); if (t->secondary_clip == NULL) { if (transition_type == TA_OPENING_TRANSITION) { @@ -2136,18 +2153,21 @@ void draw_transition(QPainter& p, Clip* c, const QRect& clip_rect, QRect& text_r } else { p.drawLine(transition_rect.topLeft(), transition_rect.bottomRight()); } - } else{ + } else { if (transition_type == TA_OPENING_TRANSITION) { p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.topRight()); p.drawLine(QPoint(transition_rect.left(), transition_rect.center().y()), transition_rect.bottomRight()); + draw_text = false; } else { p.drawLine(QPoint(transition_rect.right(), transition_rect.center().y()), transition_rect.topLeft()); p.drawLine(QPoint(transition_rect.right(), transition_rect.center().y()), transition_rect.bottomLeft()); } } - p.setPen(Qt::white); - p.drawText(transition_text_rect, 0, t->name, &transition_text_rect); + if (draw_text) { + p.setPen(Qt::white); + p.drawText(transition_text_rect, 0, t->meta->name, &transition_text_rect); + } } p.setPen(Qt::black); p.drawRect(transition_rect); diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index f1b1dbbd3..e105c0447 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -441,9 +441,11 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2; coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2; coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2; - coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; - coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0; + coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2; + coords.vertexBottomLeftZ = coords.vertexBottomRightZ = coords.vertexTopLeftZ = coords.vertexTopRightZ = 1; + 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; if (c->autoscale && (video_width != s->width && video_height != s->height)) { float width_multiplier = (float) s->width / (float) video_width; @@ -496,43 +498,45 @@ GLuint ViewerWidget::compose_sequence(QVector& nests, bool render_audio) glBegin(GL_QUADS); if (coords.grid_size <= 1) { - glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left - glVertex2f(coords.vertexTopLeftX, coords.vertexTopLeftY); // top left - glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right - glVertex2f(coords.vertexTopRightX, coords.vertexTopRightY); // top right - glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right - glVertex2f(coords.vertexBottomRightX, coords.vertexBottomRightY); // bottom right - glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left - glVertex2f(coords.vertexBottomLeftX, coords.vertexBottomLeftY); // bottom left + float z = 0.5f; + + glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left + glVertex3f(coords.vertexTopLeftX, coords.vertexTopLeftY, z); // top left + glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right + glVertex3f(coords.vertexTopRightX, coords.vertexTopRightY, z); // top right + glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right + glVertex3f(coords.vertexBottomRightX, coords.vertexBottomRightY, z); // bottom right + glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left + glVertex3f(coords.vertexBottomLeftX, coords.vertexBottomLeftY, z); // bottom left } else { - double rows = coords.grid_size; - double cols = coords.grid_size; + float rows = coords.grid_size; + float cols = coords.grid_size; - for (double i=0;i