merged effects into node structure
This commit is contained in:
@@ -127,7 +127,7 @@ void AutoCutSilenceDialog::cut_silence() {
|
||||
Clip* clip = clips_.at(j);
|
||||
|
||||
// Check if this clip is an audio footage clip
|
||||
if (clip->type() == Track::kTypeAudio
|
||||
if (clip->type() == olive::kTypeAudio
|
||||
&& clip->media() != nullptr
|
||||
&& clip->media_stream()->preview_done) { // TODO provide warning for preview not being done
|
||||
|
||||
|
||||
+10
-10
@@ -33,7 +33,7 @@
|
||||
#include "panels/timeline.h"
|
||||
#include "undo/undo.h"
|
||||
#include "undo/undostack.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "project/media.h"
|
||||
|
||||
SpeedDialog::SpeedDialog(QWidget *parent, QVector<Clip*> clips) : QDialog(parent) {
|
||||
@@ -103,7 +103,7 @@ int SpeedDialog::exec() {
|
||||
|
||||
// get default frame rate/percentage
|
||||
clip_percent = c->speed().value;
|
||||
if (c->type() == Track::kTypeVideo) {
|
||||
if (c->type() == olive::kTypeVideo) {
|
||||
bool process_video = true;
|
||||
if (c->media() != nullptr && c->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
|
||||
FootageStream* ms = c->media_stream();
|
||||
@@ -131,7 +131,7 @@ int SpeedDialog::exec() {
|
||||
|
||||
enable_frame_rate = true;
|
||||
}
|
||||
} else if (c->type() == Track::kTypeAudio) {
|
||||
} else if (c->type() == olive::kTypeAudio) {
|
||||
maintain_pitch->setEnabled(true);
|
||||
|
||||
if (!multiple_audio) {
|
||||
@@ -192,7 +192,7 @@ void SpeedDialog::percent_update() {
|
||||
Clip* c = clips_.at(i);
|
||||
|
||||
// get frame rate
|
||||
if (frame_rate->isEnabled() && c->type() == Track::kTypeVideo) {
|
||||
if (frame_rate->isEnabled() && c->type() == olive::kTypeVideo) {
|
||||
double clip_fr = c->media_frame_rate() * percent->value();
|
||||
if (got_fr) {
|
||||
if (!qIsNaN(fr_val) && !qFuzzyCompare(fr_val, clip_fr)) {
|
||||
@@ -236,7 +236,7 @@ void SpeedDialog::duration_update() {
|
||||
}
|
||||
|
||||
// get frame rate
|
||||
if (frame_rate->isEnabled() && c->type() == Track::kTypeVideo) {
|
||||
if (frame_rate->isEnabled() && c->type() == olive::kTypeVideo) {
|
||||
double clip_fr = c->media_frame_rate() * clip_pc;
|
||||
if (got_fr) {
|
||||
if (!qIsNaN(fr_val) && !qFuzzyCompare(fr_val, clip_fr)) {
|
||||
@@ -276,7 +276,7 @@ void SpeedDialog::frame_rate_update() {
|
||||
old_pc_val = qSNaN();
|
||||
}
|
||||
|
||||
if (c->type() == Track::kTypeVideo) {
|
||||
if (c->type() == olive::kTypeVideo) {
|
||||
// what would the new speed be based on this frame rate
|
||||
double new_clip_speed = frame_rate->value() / c->media_frame_rate();
|
||||
if (!got_pc_val) {
|
||||
@@ -301,7 +301,7 @@ void SpeedDialog::frame_rate_update() {
|
||||
for (int i=0;i<clips_.size();i++) {
|
||||
Clip* c = clips_.at(i);
|
||||
|
||||
if (c->type() == Track::kTypeAudio) {
|
||||
if (c->type() == olive::kTypeAudio) {
|
||||
|
||||
long new_clip_len = (qIsNaN(old_pc_val) || qIsNaN(pc_val)) ?
|
||||
c->length() : qRound((c->length() * c->speed().value) / pc_val);
|
||||
@@ -376,7 +376,7 @@ void SpeedDialog::accept() {
|
||||
}
|
||||
|
||||
// set maintain audio pitch if the user made a selection
|
||||
if (c->type() == Track::kTypeAudio
|
||||
if (c->type() == olive::kTypeAudio
|
||||
&& maintain_pitch->checkState() != Qt::PartiallyChecked
|
||||
&& c->speed().maintain_audio_pitch != maintain_pitch->isChecked()) {
|
||||
audio_pitch_action->AddSetting(c, maintain_pitch->isChecked());
|
||||
@@ -418,7 +418,7 @@ void SpeedDialog::accept() {
|
||||
if (i > 0 && !qFuzzyCompare(cached_speed, c->speed().value)) {
|
||||
can_change_all = false;
|
||||
}
|
||||
if (c->type() == Track::kTypeVideo) {
|
||||
if (c->type() == olive::kTypeVideo) {
|
||||
if (qIsNaN(cached_fr)) {
|
||||
cached_fr = c->media_frame_rate();
|
||||
} else if (!qFuzzyCompare(cached_fr, c->media_frame_rate())) {
|
||||
@@ -431,7 +431,7 @@ void SpeedDialog::accept() {
|
||||
// make changes
|
||||
for (int i=0;i<clips_.size();i++) {
|
||||
Clip* c = clips_.at(i);
|
||||
if (c->type() == Track::kTypeVideo) {
|
||||
if (c->type() == olive::kTypeVideo) {
|
||||
set_speed(ca, c, frame_rate->value() / c->media_frame_rate(), ripple->isChecked(), earliest_point, longest_ripple);
|
||||
} else if (can_change_all) {
|
||||
set_speed(ca, c, frame_rate->value() / cached_fr, ripple->isChecked(), earliest_point, longest_ripple);
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "global/config.h"
|
||||
#include "global/timing.h"
|
||||
#include "effects/effectrow.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "undo/undo.h"
|
||||
#include "timeline/clip.h"
|
||||
#include "timeline/sequence.h"
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <QVector>
|
||||
|
||||
#include "effects/keyframe.h"
|
||||
#include "undo/undo.h"
|
||||
#include "undo/undostack.h"
|
||||
#include "nodes/nodedatatypes.h"
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
#include "ui/labelslider.h"
|
||||
#include "effects/fields/doublefield.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
EffectGizmo::EffectGizmo(Effect *parent, int type) :
|
||||
EffectGizmo::EffectGizmo(Node *parent, int type) :
|
||||
QObject(parent),
|
||||
x_field1(nullptr),
|
||||
x_field_multi1(1.0),
|
||||
|
||||
@@ -39,12 +39,12 @@ enum GizmoType {
|
||||
#include <QColor>
|
||||
|
||||
class DoubleField;
|
||||
class Effect;
|
||||
class Node;
|
||||
|
||||
class EffectGizmo : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
EffectGizmo(Effect* parent, int type);
|
||||
EffectGizmo(Node* parent, int type);
|
||||
|
||||
QVector<QVector3D> world_pos;
|
||||
QVector<QPoint> screen_pos;
|
||||
|
||||
+82
-143
@@ -24,13 +24,36 @@
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDebug>
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "effects/transition.h"
|
||||
#include "global/path.h"
|
||||
#include "panels/panels.h"
|
||||
#include "panels/effectcontrols.h"
|
||||
#include "global/config.h"
|
||||
|
||||
#include "effects/internal/transformeffect.h"
|
||||
#include "effects/internal/texteffect.h"
|
||||
#include "effects/internal/timecodeeffect.h"
|
||||
#include "effects/internal/solideffect.h"
|
||||
#include "effects/internal/audionoiseeffect.h"
|
||||
#include "effects/internal/toneeffect.h"
|
||||
#include "effects/internal/volumeeffect.h"
|
||||
#include "effects/internal/paneffect.h"
|
||||
#include "effects/internal/shakeeffect.h"
|
||||
#include "effects/internal/cornerpineffect.h"
|
||||
#include "effects/internal/vsthost.h"
|
||||
#include "effects/internal/fillleftrighteffect.h"
|
||||
#include "effects/internal/richtexteffect.h"
|
||||
|
||||
#include "effects/internal/crossdissolvetransition.h"
|
||||
#include "effects/internal/linearfadetransition.h"
|
||||
#include "effects/internal/logarithmicfadetransition.h"
|
||||
#include "effects/internal/exponentialfadetransition.h"
|
||||
|
||||
#include "nodes/nodes/nodemedia.h"
|
||||
#include "nodes/nodes/nodeimageoutput.h"
|
||||
#include "nodes/nodes/nodeshader.h"
|
||||
|
||||
QMutex olive::effects_loaded;
|
||||
|
||||
void load_internal_effects() {
|
||||
@@ -38,103 +61,35 @@ void load_internal_effects() {
|
||||
qWarning() << "Shaders are disabled, some effects may be nonfunctional";
|
||||
}
|
||||
|
||||
EffectMeta em;
|
||||
olive::node_library.resize(kInvalidNode);
|
||||
olive::node_library.fill(nullptr);
|
||||
|
||||
// load internal effects
|
||||
em.path = ":/internalshaders";
|
||||
|
||||
em.type = EFFECT_TYPE_EFFECT;
|
||||
em.subtype = Track::kTypeAudio;
|
||||
|
||||
em.name = "Volume";
|
||||
em.internal = EFFECT_INTERNAL_VOLUME;
|
||||
olive::effects.append(em);
|
||||
|
||||
em.name = "Pan";
|
||||
em.internal = EFFECT_INTERNAL_PAN;
|
||||
olive::effects.append(em);
|
||||
|
||||
em.name = "VST Plugin 2.x";
|
||||
em.internal = EFFECT_INTERNAL_VST;
|
||||
olive::effects.append(em);
|
||||
|
||||
em.name = "Tone";
|
||||
em.internal = EFFECT_INTERNAL_TONE;
|
||||
olive::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;
|
||||
olive::effects.append(em);
|
||||
|
||||
em.subtype = Track::kTypeVideo;
|
||||
|
||||
em.name = "Transform";
|
||||
em.category = "Distort";
|
||||
em.internal = EFFECT_INTERNAL_TRANSFORM;
|
||||
olive::effects.append(em);
|
||||
|
||||
em.name = "Corner Pin";
|
||||
em.internal = EFFECT_INTERNAL_CORNERPIN;
|
||||
olive::effects.append(em);
|
||||
|
||||
/*em.name = "Mask";
|
||||
em.internal = EFFECT_INTERNAL_MASK;
|
||||
olive::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;
|
||||
olive::effects.append(em);
|
||||
|
||||
em.name = "Rich Text";
|
||||
em.category = "Render";
|
||||
em.internal = EFFECT_INTERNAL_RICHTEXT;
|
||||
olive::effects.append(em);
|
||||
|
||||
em.name = "Timecode";
|
||||
em.internal = EFFECT_INTERNAL_TIMECODE;
|
||||
olive::effects.append(em);
|
||||
|
||||
em.name = "Solid";
|
||||
em.internal = EFFECT_INTERNAL_SOLID;
|
||||
olive::effects.append(em);
|
||||
|
||||
// internal transitions
|
||||
em.type = EFFECT_TYPE_TRANSITION;
|
||||
em.category = "";
|
||||
|
||||
em.name = "Cross Dissolve";
|
||||
em.internal = TRANSITION_INTERNAL_CROSSDISSOLVE;
|
||||
olive::effects.append(em);
|
||||
|
||||
em.subtype = Track::kTypeAudio;
|
||||
|
||||
em.name = "Linear Fade";
|
||||
em.internal = TRANSITION_INTERNAL_LINEARFADE;
|
||||
olive::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;
|
||||
olive::effects.append(em);
|
||||
olive::node_library[kTransformEffect] = std::make_shared<TransformEffect>(nullptr);
|
||||
olive::node_library[kTextInput] = std::make_shared<TextEffect>(nullptr);
|
||||
olive::node_library[kSolidInput] = std::make_shared<SolidEffect>(nullptr);
|
||||
olive::node_library[kNoiseInput] = std::make_shared<AudioNoiseEffect>(nullptr);
|
||||
olive::node_library[kVolumeEffect] = std::make_shared<VolumeEffect>(nullptr);
|
||||
olive::node_library[kPanEffect] = std::make_shared<PanEffect>(nullptr);
|
||||
olive::node_library[kToneInput] = std::make_shared<ToneEffect>(nullptr);
|
||||
olive::node_library[kShakeEffect] = std::make_shared<ShakeEffect>(nullptr);
|
||||
olive::node_library[kTimecodeEffect] = std::make_shared<TimecodeEffect>(nullptr);
|
||||
olive::node_library[kFillLeftRightEffect] = std::make_shared<FillLeftRightEffect>(nullptr);
|
||||
olive::node_library[kVstEffect] = std::make_shared<VSTHost>(nullptr);
|
||||
olive::node_library[kCornerPinEffect] = std::make_shared<CornerPinEffect>(nullptr);
|
||||
olive::node_library[kRichTextInput] = std::make_shared<RichTextEffect>(nullptr);
|
||||
olive::node_library[kMediaInput] = std::make_shared<NodeMedia>(nullptr);
|
||||
olive::node_library[kImageOutput] = std::make_shared<NodeImageOutput>(nullptr);
|
||||
olive::node_library[kCrossDissolveTransition] = std::make_shared<CrossDissolveTransition>(nullptr);
|
||||
olive::node_library[kLinearFadeTransition] = std::make_shared<LinearFadeTransition>(nullptr);
|
||||
olive::node_library[kExponentialFadeTransition] = std::make_shared<ExponentialFadeTransition>(nullptr);
|
||||
olive::node_library[kLogarithmicFadeTransition] = std::make_shared<LogarithmicFadeTransition>(nullptr);
|
||||
}
|
||||
|
||||
void load_shader_effects_worker(const QString& effects_path) {
|
||||
QDir effects_dir(effects_path);
|
||||
if (effects_dir.exists()) {
|
||||
|
||||
QList<QString> entries = effects_dir.entryList({"*.xml", "*.blend"},
|
||||
QList<QString> entries = effects_dir.entryList({"*.xml"},
|
||||
QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||
|
||||
for (int i=0;i<entries.size();i++) {
|
||||
@@ -144,60 +99,44 @@ void load_shader_effects_worker(const QString& effects_path) {
|
||||
} else {
|
||||
QString file_url = QDir(effects_path).filePath(entries.at(i));
|
||||
|
||||
if (file_url.endsWith(".blend", Qt::CaseInsensitive)) {
|
||||
QFile file(file_url);
|
||||
|
||||
// Load blending mode shaders from file
|
||||
QList<QString> blend_mode_entries = effects_dir.entryList(QStringList("*.blend"), QDir::Files);
|
||||
for (int i=0;i<blend_mode_entries.size();i++) {
|
||||
BlendMode b;
|
||||
b.loaded = false;
|
||||
b.url = effects_dir.filePath(blend_mode_entries.at(i));
|
||||
b.name = QFileInfo(b.url).baseName();
|
||||
olive::blend_modes.append(b);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
QFile file(file_url);
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qCritical() << "Could not open" << entries.at(i);
|
||||
return;
|
||||
}
|
||||
|
||||
QXmlStreamReader reader(&file);
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.name() == "effect") {
|
||||
QString effect_name = "";
|
||||
QString effect_cat = "";
|
||||
const QXmlStreamAttributes attr = reader.attributes();
|
||||
for (int j=0;j<attr.size();j++) {
|
||||
if (attr.at(j).name() == "name") {
|
||||
effect_name = attr.at(j).value().toString();
|
||||
} else if (attr.at(j).name() == "category") {
|
||||
effect_cat = attr.at(j).value().toString();
|
||||
}
|
||||
}
|
||||
if (!effect_name.isEmpty()) {
|
||||
EffectMeta em;
|
||||
em.type = EFFECT_TYPE_EFFECT;
|
||||
em.subtype = Track::kTypeVideo;
|
||||
em.name = effect_name;
|
||||
em.category = effect_cat;
|
||||
em.filename = file.fileName();
|
||||
em.path = effects_path;
|
||||
em.internal = -1;
|
||||
olive::effects.append(em);
|
||||
} else {
|
||||
qCritical() << "Invalid effect found in" << entries.at(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
|
||||
file.close();
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qCritical() << "Could not open" << entries.at(i);
|
||||
return;
|
||||
}
|
||||
|
||||
QXmlStreamReader reader(&file);
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.name() == "effect") {
|
||||
QString effect_name;
|
||||
QString effect_cat;
|
||||
QString effect_id;
|
||||
const QXmlStreamAttributes attr = reader.attributes();
|
||||
for (int j=0;j<attr.size();j++) {
|
||||
if (attr.at(j).name() == "name") {
|
||||
effect_name = attr.at(j).value().toString();
|
||||
} else if (attr.at(j).name() == "category") {
|
||||
effect_cat = attr.at(j).value().toString();
|
||||
} else if (attr.at(j).name() == "id") {
|
||||
effect_id = attr.at(j).value().toString();
|
||||
}
|
||||
}
|
||||
if (!effect_name.isEmpty() && !effect_id.isEmpty()) {
|
||||
olive::node_library.append(std::make_shared<NodeShader>(nullptr,
|
||||
effect_name,
|
||||
effect_id,
|
||||
effect_cat,
|
||||
file_url));
|
||||
} else {
|
||||
qCritical() << "Invalid effect found in" << entries.at(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@
|
||||
#include "panels/effectcontrols.h"
|
||||
#include "panels/viewer.h"
|
||||
#include "panels/grapheditor.h"
|
||||
#include "effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "ui/viewerwidget.h"
|
||||
#include "ui/keyframenavigator.h"
|
||||
#include "ui/clickablelabel.h"
|
||||
|
||||
EffectRow::EffectRow(Effect *parent,
|
||||
EffectRow::EffectRow(Node *parent,
|
||||
const QString &id,
|
||||
const QString &name,
|
||||
bool savable,
|
||||
@@ -77,7 +77,7 @@ bool EffectRow::IsKeyframing() {
|
||||
}
|
||||
|
||||
void EffectRow::SetKeyframingInternal(bool b) {
|
||||
if (GetParentEffect()->meta->type != EFFECT_TYPE_TRANSITION) {
|
||||
if (GetParentEffect()->type() != EFFECT_TYPE_TRANSITION) {
|
||||
keyframing_ = b;
|
||||
emit KeyframingSetChanged(keyframing_);
|
||||
}
|
||||
@@ -315,9 +315,9 @@ void EffectRow::SetKeyframeOnAllFields(ComboAction* ca) {
|
||||
panel_effect_controls->update_keyframes();
|
||||
}
|
||||
|
||||
Effect *EffectRow::GetParentEffect()
|
||||
Node *EffectRow::GetParentEffect()
|
||||
{
|
||||
return static_cast<Effect*>(parent());
|
||||
return static_cast<Node*>(parent());
|
||||
}
|
||||
|
||||
const QString &EffectRow::name() {
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
class Effect;
|
||||
class Node;
|
||||
class QGridLayout;
|
||||
class EffectField;
|
||||
class QLabel;
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
* Whether keyframing can be enabled on this row or not. This is true by default. Some values you may want to prevent
|
||||
* the user from keyframing (e.g. the filename of a VST plugin), which can be done by setting this to false.
|
||||
*/
|
||||
EffectRow(Effect* parent,
|
||||
EffectRow(Node* parent,
|
||||
const QString& id,
|
||||
const QString& name,
|
||||
bool savable = true,
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
*
|
||||
* @return The parent Effect object that this row is attached to.
|
||||
*/
|
||||
Effect* GetParentEffect();
|
||||
Node* GetParentEffect();
|
||||
|
||||
/**
|
||||
* @brief Return the row's name
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
#include <QCheckBox>
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "undo/undo.h"
|
||||
|
||||
BoolField::BoolField(EffectRow *parent) :
|
||||
EffectField(parent, EffectField::EFFECT_FIELD_BOOL)
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
#include <QColor>
|
||||
|
||||
#include "ui/colorbutton.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "undo/undo.h"
|
||||
|
||||
ColorField::ColorField(EffectRow* parent) :
|
||||
EffectField(parent, EffectField::EFFECT_FIELD_COLOR)
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "ui/comboboxex.h"
|
||||
#include "undo/undo.h"
|
||||
|
||||
ComboField::ComboField(EffectRow* parent) :
|
||||
EffectField(parent, EffectField::EFFECT_FIELD_COMBO)
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
|
||||
#include "doublefield.h"
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "undo/undo.h"
|
||||
|
||||
DoubleField::DoubleField(EffectRow* parent) :
|
||||
EffectField(parent, EffectField::EFFECT_FIELD_DOUBLE),
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "../effectfield.h"
|
||||
#include "ui/labelslider.h"
|
||||
|
||||
class KeyframeDataChange;
|
||||
|
||||
/**
|
||||
* @brief The DoubleField class
|
||||
*
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "ui/embeddedfilechooser.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "undo/undo.h"
|
||||
|
||||
FileField::FileField(EffectRow* parent) :
|
||||
EffectField(parent, EffectField::EFFECT_FIELD_FILE)
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "ui/comboboxex.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "undo/undo.h"
|
||||
|
||||
// NOTE/TODO: This shares a lot of similarity with ComboInput, and could probably be a derived class of it
|
||||
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
#include <QtMath>
|
||||
#include <QDebug>
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "ui/texteditex.h"
|
||||
#include "global/config.h"
|
||||
#include "undo/undo.h"
|
||||
|
||||
StringField::StringField(EffectRow* parent, bool rich_text) :
|
||||
EffectField(parent, EffectField::EFFECT_FIELD_STRING),
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <QDateTime>
|
||||
#include <QtMath>
|
||||
|
||||
AudioNoiseEffect::AudioNoiseEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
|
||||
AudioNoiseEffect::AudioNoiseEffect(Clip* c) : Node(c) {
|
||||
amount_val = new DoubleInput(this, "amount", tr("Amount"));
|
||||
amount_val->SetMinimum(0);
|
||||
amount_val->SetDefault(20);
|
||||
@@ -33,6 +33,36 @@ AudioNoiseEffect::AudioNoiseEffect(Clip* c, const EffectMeta *em) : Effect(c, em
|
||||
mix_val->SetValueAt(0, true);
|
||||
}
|
||||
|
||||
QString AudioNoiseEffect::name()
|
||||
{
|
||||
return tr("Noise");
|
||||
}
|
||||
|
||||
QString AudioNoiseEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.noise";
|
||||
}
|
||||
|
||||
QString AudioNoiseEffect::description()
|
||||
{
|
||||
return tr("Generate audio noise that can be mixed with this clip.");
|
||||
}
|
||||
|
||||
EffectType AudioNoiseEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType AudioNoiseEffect::subtype()
|
||||
{
|
||||
return olive::kTypeAudio;
|
||||
}
|
||||
|
||||
NodePtr AudioNoiseEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<AudioNoiseEffect>(c);
|
||||
}
|
||||
|
||||
void AudioNoiseEffect::process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -21,12 +21,20 @@
|
||||
#ifndef AUDIONOISEEFFECT_H
|
||||
#define AUDIONOISEEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class AudioNoiseEffect : public Effect {
|
||||
class AudioNoiseEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioNoiseEffect(Clip* c, const EffectMeta* em);
|
||||
AudioNoiseEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#include "timeline/clip.h"
|
||||
#include "global/debug.h"
|
||||
|
||||
CornerPinEffect::CornerPinEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
|
||||
SetFlags(Effect::CoordsFlag | Effect::ShaderFlag);
|
||||
CornerPinEffect::CornerPinEffect(Clip* c) : Node(c) {
|
||||
SetFlags(Node::CoordsFlag | Node::ShaderFlag);
|
||||
|
||||
top_left = new Vec2Input(this, "topleft", tr("Top Left"));
|
||||
|
||||
@@ -58,6 +58,41 @@ CornerPinEffect::CornerPinEffect(Clip* c, const EffectMeta *em) : Effect(c, em)
|
||||
shader_frag_path_ = "cornerpin.frag";
|
||||
}
|
||||
|
||||
QString CornerPinEffect::name()
|
||||
{
|
||||
return tr("Corner Pin");
|
||||
}
|
||||
|
||||
QString CornerPinEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.cornerpin";
|
||||
}
|
||||
|
||||
QString CornerPinEffect::category()
|
||||
{
|
||||
return tr("Distort");
|
||||
}
|
||||
|
||||
QString CornerPinEffect::description()
|
||||
{
|
||||
return tr("Distort/warp this clip by pinning each of its four corners.");
|
||||
}
|
||||
|
||||
EffectType CornerPinEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType CornerPinEffect::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
NodePtr CornerPinEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<CornerPinEffect>(c);
|
||||
}
|
||||
|
||||
void CornerPinEffect::process_coords(double timecode, GLTextureCoords &coords, int) {
|
||||
coords.vertex_top_left += top_left->GetVector2DAt(timecode);
|
||||
coords.vertex_top_right += top_right->GetVector2DAt(timecode);
|
||||
|
||||
@@ -21,12 +21,21 @@
|
||||
#ifndef CORNERPINEFFECT_H
|
||||
#define CORNERPINEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class CornerPinEffect : public Effect {
|
||||
class CornerPinEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CornerPinEffect(Clip* c, const EffectMeta* em);
|
||||
CornerPinEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
void process_coords(double timecode, GLTextureCoords& coords, int data);
|
||||
void process_shader(double timecode, GLTextureCoords& coords, int iterations);
|
||||
void gizmo_draw(double timecode, GLTextureCoords& coords);
|
||||
|
||||
@@ -22,8 +22,43 @@
|
||||
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
CrossDissolveTransition::CrossDissolveTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {
|
||||
SetFlags(Effect::CoordsFlag);
|
||||
CrossDissolveTransition::CrossDissolveTransition(Clip* c) : Transition(c) {
|
||||
SetFlags(Node::CoordsFlag);
|
||||
}
|
||||
|
||||
QString CrossDissolveTransition::name()
|
||||
{
|
||||
return tr("Cross Dissolve");
|
||||
}
|
||||
|
||||
QString CrossDissolveTransition::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.crossdissolve";
|
||||
}
|
||||
|
||||
QString CrossDissolveTransition::category()
|
||||
{
|
||||
return tr("Dissolves");
|
||||
}
|
||||
|
||||
QString CrossDissolveTransition::description()
|
||||
{
|
||||
return tr("Dissolve clips evenly.");
|
||||
}
|
||||
|
||||
EffectType CrossDissolveTransition::type()
|
||||
{
|
||||
return EFFECT_TYPE_TRANSITION;
|
||||
}
|
||||
|
||||
olive::TrackType CrossDissolveTransition::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
NodePtr CrossDissolveTransition::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<CrossDissolveTransition>(c);
|
||||
}
|
||||
|
||||
void CrossDissolveTransition::process_coords(double progress, GLTextureCoords& coords, int data) {
|
||||
|
||||
@@ -25,8 +25,17 @@
|
||||
|
||||
class CrossDissolveTransition : public Transition {
|
||||
public:
|
||||
CrossDissolveTransition(Clip *c, Clip *s, const EffectMeta* em);
|
||||
void process_coords(double timecode, GLTextureCoords &, int data);
|
||||
CrossDissolveTransition(Clip *c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void process_coords(double timecode, GLTextureCoords &, int data) override;
|
||||
};
|
||||
|
||||
#endif // CROSSDISSOLVETRANSITION_H
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
class CubeTransition : public Transition {
|
||||
public:
|
||||
CubeTransition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
CubeTransition(Clip* c, Clip* s);
|
||||
void process_coords(double timecode, GLTextureCoords &, int data);
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,40 @@
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
ExponentialFadeTransition::ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {}
|
||||
ExponentialFadeTransition::ExponentialFadeTransition(Clip* c) :
|
||||
Transition(c)
|
||||
{
|
||||
}
|
||||
|
||||
QString ExponentialFadeTransition::name()
|
||||
{
|
||||
return tr("Exponential Fade");
|
||||
}
|
||||
|
||||
QString ExponentialFadeTransition::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.exponentialfade";
|
||||
}
|
||||
|
||||
QString ExponentialFadeTransition::description()
|
||||
{
|
||||
return tr("An exponential audio fade that starts slow and ends fast.");
|
||||
}
|
||||
|
||||
EffectType ExponentialFadeTransition::type()
|
||||
{
|
||||
return EFFECT_TYPE_TRANSITION;
|
||||
}
|
||||
|
||||
olive::TrackType ExponentialFadeTransition::subtype()
|
||||
{
|
||||
return olive::kTypeAudio;
|
||||
}
|
||||
|
||||
NodePtr ExponentialFadeTransition::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<ExponentialFadeTransition>(c);
|
||||
}
|
||||
|
||||
void ExponentialFadeTransition::process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
|
||||
@@ -25,7 +25,15 @@
|
||||
|
||||
class ExponentialFadeTransition : public Transition {
|
||||
public:
|
||||
ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
ExponentialFadeTransition(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -25,12 +25,42 @@ enum FillType {
|
||||
FILL_TYPE_RIGHT
|
||||
};
|
||||
|
||||
FillLeftRightEffect::FillLeftRightEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
|
||||
FillLeftRightEffect::FillLeftRightEffect(Clip* c) : Node(c) {
|
||||
fill_type = new ComboInput(this, "type", tr("Type"));
|
||||
fill_type->AddItem(tr("Fill Left with Right"), FILL_TYPE_LEFT);
|
||||
fill_type->AddItem(tr("Fill Right with Left"), FILL_TYPE_RIGHT);
|
||||
}
|
||||
|
||||
QString FillLeftRightEffect::name()
|
||||
{
|
||||
return tr("Fill Left/Right");
|
||||
}
|
||||
|
||||
QString FillLeftRightEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.fillleftright";
|
||||
}
|
||||
|
||||
QString FillLeftRightEffect::description()
|
||||
{
|
||||
return tr("Replaces either the left or right channel with the other");
|
||||
}
|
||||
|
||||
EffectType FillLeftRightEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType FillLeftRightEffect::subtype()
|
||||
{
|
||||
return olive::kTypeAudio;
|
||||
}
|
||||
|
||||
NodePtr FillLeftRightEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<FillLeftRightEffect>(c);
|
||||
}
|
||||
|
||||
void FillLeftRightEffect::process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -21,12 +21,20 @@
|
||||
#ifndef FILLLEFTRIGHTEFFECT_H
|
||||
#define FILLLEFTRIGHTEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class FillLeftRightEffect : public Effect {
|
||||
class FillLeftRightEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FillLeftRightEffect(Clip* c, const EffectMeta* em);
|
||||
FillLeftRightEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -20,7 +20,37 @@
|
||||
|
||||
#include "linearfadetransition.h"
|
||||
|
||||
LinearFadeTransition::LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {}
|
||||
LinearFadeTransition::LinearFadeTransition(Clip* c) : Transition(c) {}
|
||||
|
||||
QString LinearFadeTransition::name()
|
||||
{
|
||||
return tr("Linear Fade");
|
||||
}
|
||||
|
||||
QString LinearFadeTransition::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.linearfade";
|
||||
}
|
||||
|
||||
QString LinearFadeTransition::description()
|
||||
{
|
||||
return tr("An linear audio fade that fades evenly at a constant rate.");
|
||||
}
|
||||
|
||||
EffectType LinearFadeTransition::type()
|
||||
{
|
||||
return EFFECT_TYPE_TRANSITION;
|
||||
}
|
||||
|
||||
olive::TrackType LinearFadeTransition::subtype()
|
||||
{
|
||||
return olive::kTypeAudio;
|
||||
}
|
||||
|
||||
NodePtr LinearFadeTransition::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<LinearFadeTransition>(c);
|
||||
}
|
||||
|
||||
void LinearFadeTransition::process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
|
||||
@@ -25,7 +25,15 @@
|
||||
|
||||
class LinearFadeTransition : public Transition {
|
||||
public:
|
||||
LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
LinearFadeTransition(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -22,7 +22,40 @@
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
LogarithmicFadeTransition::LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {}
|
||||
LogarithmicFadeTransition::LogarithmicFadeTransition(Clip* c) :
|
||||
Transition(c)
|
||||
{
|
||||
}
|
||||
|
||||
QString LogarithmicFadeTransition::name()
|
||||
{
|
||||
return tr("Logarithmic Fade");
|
||||
}
|
||||
|
||||
QString LogarithmicFadeTransition::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.logarithmicfade";
|
||||
}
|
||||
|
||||
QString LogarithmicFadeTransition::description()
|
||||
{
|
||||
return tr("An logarithmic audio fade that starts fast and ends slow.");
|
||||
}
|
||||
|
||||
EffectType LogarithmicFadeTransition::type()
|
||||
{
|
||||
return EFFECT_TYPE_TRANSITION;
|
||||
}
|
||||
|
||||
olive::TrackType LogarithmicFadeTransition::subtype()
|
||||
{
|
||||
return olive::kTypeAudio;
|
||||
}
|
||||
|
||||
NodePtr LogarithmicFadeTransition::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<LogarithmicFadeTransition>(c);
|
||||
}
|
||||
|
||||
void LogarithmicFadeTransition::process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
|
||||
@@ -25,7 +25,15 @@
|
||||
|
||||
class LogarithmicFadeTransition : public Transition {
|
||||
public:
|
||||
LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
LogarithmicFadeTransition(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip* c) override;
|
||||
|
||||
virtual void process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -28,13 +28,43 @@
|
||||
#include "ui/labelslider.h"
|
||||
#include "ui/collapsiblewidget.h"
|
||||
|
||||
PanEffect::PanEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
|
||||
PanEffect::PanEffect(Clip* c) : Node(c) {
|
||||
pan_val = new DoubleInput(this, "pan", tr("Pan"));
|
||||
pan_val->SetMinimum(-100);
|
||||
pan_val->SetDefault(0);
|
||||
pan_val->SetMaximum(100);
|
||||
}
|
||||
|
||||
QString PanEffect::name()
|
||||
{
|
||||
return tr("Pan");
|
||||
}
|
||||
|
||||
QString PanEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.pan";
|
||||
}
|
||||
|
||||
QString PanEffect::description()
|
||||
{
|
||||
return tr("Modifying the panning on a stereo audio clip.");
|
||||
}
|
||||
|
||||
EffectType PanEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType PanEffect::subtype()
|
||||
{
|
||||
return olive::kTypeAudio;
|
||||
}
|
||||
|
||||
NodePtr PanEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<PanEffect>(c);
|
||||
}
|
||||
|
||||
void PanEffect::process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -21,12 +21,20 @@
|
||||
#ifndef PANEFFECT_H
|
||||
#define PANEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class PanEffect : public Effect {
|
||||
class PanEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PanEffect(Clip* c, const EffectMeta* em);
|
||||
PanEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -34,10 +34,10 @@ enum AutoscrollDirection {
|
||||
SCROLL_RIGHT,
|
||||
};
|
||||
|
||||
RichTextEffect::RichTextEffect(Clip *c, const EffectMeta *em) :
|
||||
Effect(c, em)
|
||||
RichTextEffect::RichTextEffect(Clip *c) :
|
||||
Node(c)
|
||||
{
|
||||
SetFlags(Effect::SuperimposeFlag);
|
||||
SetFlags(Node::SuperimposeFlag);
|
||||
|
||||
text_val = new StringInput(this, "text", tr("Text"));
|
||||
|
||||
@@ -82,6 +82,41 @@ RichTextEffect::RichTextEffect(Clip *c, const EffectMeta *em) :
|
||||
"</html>");
|
||||
}
|
||||
|
||||
QString RichTextEffect::name()
|
||||
{
|
||||
return tr("Rich Text");
|
||||
}
|
||||
|
||||
QString RichTextEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.richtext";
|
||||
}
|
||||
|
||||
QString RichTextEffect::category()
|
||||
{
|
||||
return tr("Render");
|
||||
}
|
||||
|
||||
QString RichTextEffect::description()
|
||||
{
|
||||
return tr("Render formatted rich text over a clip.");
|
||||
}
|
||||
|
||||
EffectType RichTextEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType RichTextEffect::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
NodePtr RichTextEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<RichTextEffect>(c);
|
||||
}
|
||||
|
||||
void RichTextEffect::redraw(double timecode)
|
||||
{
|
||||
QPainter p(&img);
|
||||
|
||||
@@ -21,13 +21,23 @@
|
||||
#ifndef RICHTEXTEFFECT_H
|
||||
#define RICHTEXTEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class RichTextEffect : public Effect {
|
||||
class RichTextEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RichTextEffect(Clip* c, const EffectMeta *em);
|
||||
RichTextEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void redraw(double timecode) override;
|
||||
|
||||
protected:
|
||||
virtual bool AlwaysUpdate() override;
|
||||
private:
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
#include "panels/timeline.h"
|
||||
#include "global/debug.h"
|
||||
|
||||
ShakeEffect::ShakeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
|
||||
SetFlags(Effect::CoordsFlag);
|
||||
ShakeEffect::ShakeEffect(Clip* c) : Node(c) {
|
||||
SetFlags(Node::CoordsFlag);
|
||||
|
||||
intensity_val = new DoubleInput(this, "intensity", tr("Intensity"));
|
||||
intensity_val->SetMinimum(0);
|
||||
@@ -79,3 +79,38 @@ void ShakeEffect::process_coords(double timecode, GLTextureCoords& coords, int)
|
||||
|
||||
coords.matrix.rotate(QQuaternion::fromEulerAngles(0.0f, 0.0f, rotoff));
|
||||
}
|
||||
|
||||
QString ShakeEffect::name()
|
||||
{
|
||||
return tr("Shake");
|
||||
}
|
||||
|
||||
QString ShakeEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.shake";
|
||||
}
|
||||
|
||||
QString ShakeEffect::category()
|
||||
{
|
||||
return tr("Distort");
|
||||
}
|
||||
|
||||
QString ShakeEffect::description()
|
||||
{
|
||||
return tr("Simulate a camera shake movement.");
|
||||
}
|
||||
|
||||
EffectType ShakeEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType ShakeEffect::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
NodePtr ShakeEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<ShakeEffect>(c);
|
||||
}
|
||||
|
||||
@@ -21,16 +21,24 @@
|
||||
#ifndef SHAKEEFFECT_H
|
||||
#define SHAKEEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
#define RANDOM_VAL_SIZE 30
|
||||
|
||||
class ShakeEffect : public Effect {
|
||||
class ShakeEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ShakeEffect(Clip* c, const EffectMeta* em);
|
||||
ShakeEffect(Clip* c);
|
||||
virtual void process_coords(double timecode, GLTextureCoords& coords, int data) override;
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
DoubleInput* intensity_val;
|
||||
DoubleInput* rotation_val;
|
||||
DoubleInput* frequency_val;
|
||||
|
||||
@@ -34,10 +34,10 @@ const int SMPTE_BARS = 7;
|
||||
const int SMPTE_STRIP_COUNT = 3;
|
||||
const int SMPTE_LOWER_BARS = 4;
|
||||
|
||||
SolidEffect::SolidEffect(Clip* c, const EffectMeta* em) :
|
||||
Effect(c, em)
|
||||
SolidEffect::SolidEffect(Clip* c) :
|
||||
Node(c)
|
||||
{
|
||||
SetFlags(Effect::SuperimposeFlag);
|
||||
SetFlags(Node::SuperimposeFlag);
|
||||
|
||||
// Field for solid type
|
||||
solid_type = new ComboInput(this, "type", tr("Type"));
|
||||
@@ -69,6 +69,41 @@ SolidEffect::SolidEffect(Clip* c, const EffectMeta* em) :
|
||||
fragPath = ":/shaders/solideffect.frag";*/
|
||||
}
|
||||
|
||||
QString SolidEffect::name()
|
||||
{
|
||||
return tr("Solid");
|
||||
}
|
||||
|
||||
QString SolidEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.solid";
|
||||
}
|
||||
|
||||
QString SolidEffect::category()
|
||||
{
|
||||
return tr("Render");
|
||||
}
|
||||
|
||||
QString SolidEffect::description()
|
||||
{
|
||||
return tr("Render a solid color over this clip.");
|
||||
}
|
||||
|
||||
EffectType SolidEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType SolidEffect::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
NodePtr SolidEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<SolidEffect>(c);
|
||||
}
|
||||
|
||||
void SolidEffect::redraw(double timecode) {
|
||||
int w = img.width();
|
||||
int h = img.height();
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
#ifndef SOLIDEFFECT_H
|
||||
#define SOLIDEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
#include <QImage>
|
||||
|
||||
class SolidEffect : public Effect {
|
||||
class SolidEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum SolidType {
|
||||
@@ -34,7 +34,16 @@ public:
|
||||
SOLID_TYPE_CHECKERBOARD
|
||||
};
|
||||
|
||||
SolidEffect(Clip* c, const EffectMeta *em);
|
||||
SolidEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void redraw(double timecode) override;
|
||||
|
||||
void SetType(SolidType type);
|
||||
|
||||
@@ -42,10 +42,10 @@
|
||||
#include "ui/blur.h"
|
||||
#include "global/config.h"
|
||||
|
||||
TextEffect::TextEffect(Clip* c, const EffectMeta* em) :
|
||||
Effect(c, em)
|
||||
TextEffect::TextEffect(Clip* c) :
|
||||
Node(c)
|
||||
{
|
||||
SetFlags(Effect::SuperimposeFlag);
|
||||
SetFlags(Node::SuperimposeFlag);
|
||||
|
||||
text_val = new StringInput(this, "text", tr("Text"), false);
|
||||
|
||||
@@ -121,6 +121,41 @@ TextEffect::TextEffect(Clip* c, const EffectMeta* em) :
|
||||
shader_frag_path_ = "dropshadow.frag";
|
||||
}
|
||||
|
||||
QString TextEffect::name()
|
||||
{
|
||||
return tr("Text");
|
||||
}
|
||||
|
||||
QString TextEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.text";
|
||||
}
|
||||
|
||||
QString TextEffect::category()
|
||||
{
|
||||
return tr("Render");
|
||||
}
|
||||
|
||||
QString TextEffect::description()
|
||||
{
|
||||
return tr("Generate simple text over this clip");
|
||||
}
|
||||
|
||||
EffectType TextEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType TextEffect::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
NodePtr TextEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<TextEffect>(c);
|
||||
}
|
||||
|
||||
void TextEffect::redraw(double timecode) {
|
||||
QColor bkg = set_color_button->GetColorAt(timecode);
|
||||
bkg.setAlpha(0);
|
||||
|
||||
@@ -21,15 +21,24 @@
|
||||
#ifndef TEXTEFFECT_H
|
||||
#define TEXTEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QImage>
|
||||
|
||||
class TextEffect : public Effect {
|
||||
class TextEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TextEffect(Clip* c, const EffectMeta *em);
|
||||
TextEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void redraw(double timecode) override;
|
||||
private slots:
|
||||
void outline_enable(bool);
|
||||
|
||||
@@ -42,10 +42,10 @@
|
||||
#include "ui/colorbutton.h"
|
||||
#include "global/config.h"
|
||||
|
||||
TimecodeEffect::TimecodeEffect(Clip* c, const EffectMeta* em) :
|
||||
Effect(c, em)
|
||||
TimecodeEffect::TimecodeEffect(Clip* c) :
|
||||
Node(c)
|
||||
{
|
||||
SetFlags(Effect::SuperimposeFlag);
|
||||
SetFlags(Node::SuperimposeFlag);
|
||||
|
||||
tc_select = new ComboInput(this, "tc_selector", tr("Timecode"));
|
||||
tc_select->AddItem(tr("Sequence"), true);
|
||||
@@ -74,6 +74,41 @@ TimecodeEffect::TimecodeEffect(Clip* c, const EffectMeta* em) :
|
||||
prepend_text = new StringInput(this, "prepend", tr("Prepend"), false);
|
||||
}
|
||||
|
||||
QString TimecodeEffect::name()
|
||||
{
|
||||
return tr("Timecode");
|
||||
}
|
||||
|
||||
QString TimecodeEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.timecode";
|
||||
}
|
||||
|
||||
QString TimecodeEffect::category()
|
||||
{
|
||||
return tr("Render");
|
||||
}
|
||||
|
||||
QString TimecodeEffect::description()
|
||||
{
|
||||
return tr("Render the media or sequence timecode on this clip.");
|
||||
}
|
||||
|
||||
EffectType TimecodeEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType TimecodeEffect::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
NodePtr TimecodeEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<TimecodeEffect>(c);
|
||||
}
|
||||
|
||||
|
||||
void TimecodeEffect::redraw(double timecode) {
|
||||
Sequence* sequence = parent_clip->track()->sequence();
|
||||
|
||||
@@ -21,15 +21,24 @@
|
||||
#ifndef TIMECODEEFFECT_H
|
||||
#define TIMECODEEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QImage>
|
||||
|
||||
class TimecodeEffect : public Effect {
|
||||
class TimecodeEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TimecodeEffect(Clip* c, const EffectMeta *em);
|
||||
TimecodeEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void redraw(double timecode) override;
|
||||
DoubleInput* scale_val;
|
||||
ColorInput* color_val;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "timeline/clip.h"
|
||||
#include "timeline/sequence.h"
|
||||
|
||||
ToneEffect::ToneEffect(Clip* c, const EffectMeta *em) : Effect(c, em), sinX(INT_MIN) {
|
||||
ToneEffect::ToneEffect(Clip* c) : Node(c), sinX(INT_MIN) {
|
||||
type_val = new ComboInput(this, "type", tr("Type"));
|
||||
type_val->AddItem(tr("Sine"), TONE_TYPE_SINE);
|
||||
|
||||
@@ -45,6 +45,36 @@ ToneEffect::ToneEffect(Clip* c, const EffectMeta *em) : Effect(c, em), sinX(INT_
|
||||
mix_val->SetValueAt(0, true);
|
||||
}
|
||||
|
||||
QString ToneEffect::name()
|
||||
{
|
||||
return tr("Tone");
|
||||
}
|
||||
|
||||
QString ToneEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.tone";
|
||||
}
|
||||
|
||||
QString ToneEffect::description()
|
||||
{
|
||||
return tr("Generate a sine wave tone to mix into this clip's audio.");
|
||||
}
|
||||
|
||||
EffectType ToneEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType ToneEffect::subtype()
|
||||
{
|
||||
return olive::kTypeAudio;
|
||||
}
|
||||
|
||||
NodePtr ToneEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<ToneEffect>(c);
|
||||
}
|
||||
|
||||
void ToneEffect::process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -21,12 +21,20 @@
|
||||
#ifndef TONEEFFECT_H
|
||||
#define TONEEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class ToneEffect : public Effect {
|
||||
class ToneEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ToneEffect(Clip* c, const EffectMeta* em);
|
||||
ToneEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
@@ -34,11 +42,12 @@ public:
|
||||
int channel_count,
|
||||
int type) override;
|
||||
|
||||
private:
|
||||
ComboInput* type_val;
|
||||
DoubleInput* freq_val;
|
||||
DoubleInput* amount_val;
|
||||
BoolInput* mix_val;
|
||||
private:
|
||||
|
||||
int sinX;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
#include "panels/viewer.h"
|
||||
#include "ui/viewerwidget.h"
|
||||
|
||||
TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em) {
|
||||
SetFlags(Effect::CoordsFlag);
|
||||
TransformEffect::TransformEffect(Clip* c) : Node(c) {
|
||||
SetFlags(Node::CoordsFlag);
|
||||
|
||||
position = new Vec2Input(this, "pos", tr("Position"));
|
||||
|
||||
@@ -125,6 +125,41 @@ TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em)
|
||||
refresh();
|
||||
}
|
||||
|
||||
QString TransformEffect::name()
|
||||
{
|
||||
return tr("Transform");
|
||||
}
|
||||
|
||||
QString TransformEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.transform";
|
||||
}
|
||||
|
||||
QString TransformEffect::category()
|
||||
{
|
||||
return tr("Distort");
|
||||
}
|
||||
|
||||
QString TransformEffect::description()
|
||||
{
|
||||
return tr("Transform the position, scale, and rotation of this clip.");
|
||||
}
|
||||
|
||||
EffectType TransformEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType TransformEffect::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
NodePtr TransformEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<TransformEffect>(c);
|
||||
}
|
||||
|
||||
void TransformEffect::refresh() {
|
||||
if (parent_clip != nullptr && parent_clip->track()->sequence() != nullptr) {
|
||||
|
||||
|
||||
@@ -21,12 +21,21 @@
|
||||
#ifndef TRANSFORMEFFECT_H
|
||||
#define TRANSFORMEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class TransformEffect : public Effect {
|
||||
class TransformEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TransformEffect(Clip* c, const EffectMeta* em);
|
||||
TransformEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void refresh() override;
|
||||
virtual void process_coords(double timecode, GLTextureCoords& coords, int data) override;
|
||||
|
||||
|
||||
@@ -27,24 +27,55 @@
|
||||
#include "ui/collapsiblewidget.h"
|
||||
#include "global/debug.h"
|
||||
|
||||
VoidEffect::VoidEffect(Clip* c, const QString& n) : Effect(c, nullptr) {
|
||||
QString display_name;
|
||||
if (n.isEmpty()) {
|
||||
display_name = tr("(unknown)");
|
||||
} else {
|
||||
display_name = n;
|
||||
VoidEffect::VoidEffect(Clip* c, const QString& n, const QString& id) :
|
||||
Node(c),
|
||||
display_name_(n),
|
||||
id_(id)
|
||||
{
|
||||
if (display_name_.isEmpty()) {
|
||||
display_name_ = tr("(unknown)");
|
||||
}
|
||||
|
||||
new LabelWidget(this, tr("Missing Effect"), display_name);
|
||||
|
||||
name = display_name;
|
||||
|
||||
void_meta.type = EFFECT_TYPE_EFFECT;
|
||||
meta = &void_meta;
|
||||
new LabelWidget(this, tr("Missing Effect"), display_name_);
|
||||
}
|
||||
|
||||
EffectPtr VoidEffect::copy(Clip* c) {
|
||||
EffectPtr copy = std::make_shared<VoidEffect>(c, name);
|
||||
QString VoidEffect::name()
|
||||
{
|
||||
return display_name_;
|
||||
}
|
||||
|
||||
QString VoidEffect::id()
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
QString VoidEffect::description()
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
EffectType VoidEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType VoidEffect::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
bool VoidEffect::IsCreatable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
NodePtr VoidEffect::Create(Clip *)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NodePtr VoidEffect::copy(Clip* c) {
|
||||
NodePtr copy = std::make_shared<VoidEffect>(c, display_name_, id_);
|
||||
copy->SetEnabled(IsEnabled());
|
||||
copy_field_keyframes(copy);
|
||||
return copy;
|
||||
@@ -53,7 +84,7 @@ EffectPtr VoidEffect::copy(Clip* c) {
|
||||
void VoidEffect::load(QXmlStreamReader &stream) {
|
||||
QString tag = stream.name().toString();
|
||||
|
||||
QXmlStreamWriter writer(&bytes);
|
||||
QXmlStreamWriter writer(&bytes_);
|
||||
|
||||
// copy XML from reader to writer
|
||||
while (!stream.atEnd() && !(stream.name() == tag && stream.isEndElement())) {
|
||||
@@ -75,18 +106,18 @@ void VoidEffect::load(QXmlStreamReader &stream) {
|
||||
}
|
||||
|
||||
void VoidEffect::save(QXmlStreamWriter &stream) {
|
||||
if (!name.isEmpty()) {
|
||||
stream.writeAttribute("name", name);
|
||||
if (!display_name_.isEmpty()) {
|
||||
stream.writeAttribute("name", display_name_);
|
||||
stream.writeAttribute("enabled", QString::number(IsEnabled()));
|
||||
|
||||
// force xml writer to expand <effect> tag, ignored when loading
|
||||
stream.writeStartElement("void");
|
||||
stream.writeEndElement();
|
||||
|
||||
if (!bytes.isEmpty()) {
|
||||
if (!bytes_.isEmpty()) {
|
||||
// write stored data
|
||||
QIODevice* device = stream.device();
|
||||
device->write(bytes);
|
||||
device->write(bytes_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,19 +27,28 @@
|
||||
* isn't lost if the user saves over the project.
|
||||
*/
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class VoidEffect : public Effect {
|
||||
class VoidEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VoidEffect(Clip* c, const QString& n);
|
||||
VoidEffect(Clip* c, const QString& n, const QString &id);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual bool IsCreatable() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
virtual NodePtr copy(Clip* c) override;
|
||||
|
||||
virtual EffectPtr copy(Clip* c) override;
|
||||
virtual void load(QXmlStreamReader &stream) override;
|
||||
virtual void save(QXmlStreamWriter &stream) override;
|
||||
private:
|
||||
QByteArray bytes;
|
||||
EffectMeta void_meta;
|
||||
QByteArray bytes_;
|
||||
QString display_name_;
|
||||
QString id_;
|
||||
};
|
||||
|
||||
#endif // VOIDEFFECT_H
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "ui/labelslider.h"
|
||||
#include "ui/collapsiblewidget.h"
|
||||
|
||||
VolumeEffect::VolumeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
|
||||
VolumeEffect::VolumeEffect(Clip* c) : Node(c) {
|
||||
volume_val = new DoubleInput(this, "volume", tr("Volume"));
|
||||
|
||||
// set defaults
|
||||
@@ -36,6 +36,36 @@ VolumeEffect::VolumeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
|
||||
volume_val->SetDisplayType(LabelSlider::Decibel);
|
||||
}
|
||||
|
||||
QString VolumeEffect::name()
|
||||
{
|
||||
return tr("Volume");
|
||||
}
|
||||
|
||||
QString VolumeEffect::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.volume";
|
||||
}
|
||||
|
||||
QString VolumeEffect::description()
|
||||
{
|
||||
return tr("Adjust the volume of this clip's audio");
|
||||
}
|
||||
|
||||
EffectType VolumeEffect::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType VolumeEffect::subtype()
|
||||
{
|
||||
return olive::kTypeAudio;
|
||||
}
|
||||
|
||||
NodePtr VolumeEffect::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<VolumeEffect>(c);
|
||||
}
|
||||
|
||||
void VolumeEffect::process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
@@ -21,12 +21,20 @@
|
||||
#ifndef VOLUMEEFFECT_H
|
||||
#define VOLUMEEFFECT_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class VolumeEffect : public Effect {
|
||||
class VolumeEffect : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VolumeEffect(Clip* c, const EffectMeta* em);
|
||||
VolumeEffect(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
@@ -34,6 +42,7 @@ public:
|
||||
int channel_count,
|
||||
int type) override;
|
||||
|
||||
private:
|
||||
DoubleInput* volume_val;
|
||||
};
|
||||
|
||||
|
||||
@@ -227,8 +227,8 @@ void VSTHost::send_data_cache_to_plugin()
|
||||
dispatcher(plugin, effSetChunk, 0, int32_t(data_cache.size()), static_cast<void*>(data_cache.data()), 0);
|
||||
}
|
||||
|
||||
VSTHost::VSTHost(Clip* c, const EffectMeta *em) :
|
||||
Effect(c, em),
|
||||
VSTHost::VSTHost(Clip* c) :
|
||||
Node(c),
|
||||
plugin(nullptr),
|
||||
dialog(nullptr),
|
||||
input_cache(BLOCK_SIZE),
|
||||
@@ -249,6 +249,36 @@ VSTHost::~VSTHost() {
|
||||
freePlugin();
|
||||
}
|
||||
|
||||
QString VSTHost::name()
|
||||
{
|
||||
return tr("VST Plugin 2.x");
|
||||
}
|
||||
|
||||
QString VSTHost::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.vst2x";
|
||||
}
|
||||
|
||||
QString VSTHost::description()
|
||||
{
|
||||
return tr("Use a VST 2.x plugin on this clip's audio.");
|
||||
}
|
||||
|
||||
EffectType VSTHost::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType VSTHost::subtype()
|
||||
{
|
||||
return olive::kTypeAudio;
|
||||
}
|
||||
|
||||
NodePtr VSTHost::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<VSTHost>(c);
|
||||
}
|
||||
|
||||
void VSTHost::process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
@@ -291,7 +321,7 @@ void VSTHost::custom_load(QXmlStreamReader &stream) {
|
||||
}
|
||||
|
||||
void VSTHost::save(QXmlStreamWriter &stream) {
|
||||
Effect::save(stream);
|
||||
Node::save(stream);
|
||||
if (plugin != nullptr) {
|
||||
char* p = nullptr;
|
||||
int32_t length = int32_t(dispatcher(plugin, effGetChunk, 0, 0, &p, 0));
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <QDialog>
|
||||
#include <QLibrary>
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "include/vestige.h"
|
||||
|
||||
// Plugin's dispatcher function
|
||||
@@ -46,11 +46,19 @@ private:
|
||||
void destroy();
|
||||
};
|
||||
|
||||
class VSTHost : public Effect {
|
||||
class VSTHost : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VSTHost(Clip* c, const EffectMeta* em);
|
||||
~VSTHost();
|
||||
VSTHost(Clip* c);
|
||||
virtual ~VSTHost() override;
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
virtual void process_audio(double timecode_start,
|
||||
double timecode_end,
|
||||
float **samples,
|
||||
|
||||
+22
-24
@@ -40,27 +40,34 @@
|
||||
#include <QMessageBox>
|
||||
#include <QCoreApplication>
|
||||
|
||||
Transition::Transition(Clip *c, Clip *s, const EffectMeta* em) :
|
||||
Effect(c, em),
|
||||
secondary_clip(s)
|
||||
Transition::Transition(Clip *c) :
|
||||
Node(c),
|
||||
secondary_clip(nullptr)
|
||||
{
|
||||
length_field = new DoubleInput(this, "length", tr("Length"), false, false);
|
||||
length_field->SetDefault(30);
|
||||
length_field->SetMinimum(1);
|
||||
length_field->SetDisplayType(LabelSlider::FrameNumber);
|
||||
length_field->SetFrameRate(parent_clip->track()->sequence() == nullptr ?
|
||||
parent_clip->cached_frame_rate() : parent_clip->track()->sequence()->frame_rate);
|
||||
|
||||
if (parent_clip != nullptr) {
|
||||
length_field->SetFrameRate(parent_clip->track()->sequence() == nullptr ?
|
||||
parent_clip->cached_frame_rate() : parent_clip->track()->sequence()->frame_rate);
|
||||
}
|
||||
|
||||
connect(length_field, SIGNAL(Changed()), this, SLOT(UpdateMaximumLength()));
|
||||
}
|
||||
|
||||
TransitionPtr Transition::copy(Clip *c, Clip *s) {
|
||||
return Transition::Create(c, s, meta, get_true_length());
|
||||
NodePtr Transition::copy(Clip *c) {
|
||||
NodePtr node = Node::copy(c);
|
||||
|
||||
static_cast<Transition*>(node.get())->set_length(get_true_length());
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void Transition::save(QXmlStreamWriter &stream) {
|
||||
stream.writeAttribute("length", QString::number(get_true_length()));
|
||||
Effect::save(stream);
|
||||
Node::save(stream);
|
||||
}
|
||||
|
||||
void Transition::set_length(int l) {
|
||||
@@ -96,17 +103,18 @@ Clip* Transition::get_closed_clip() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TransitionPtr Transition::CreateFromMeta(Clip* c, Clip* s, const EffectMeta* em) {
|
||||
/*
|
||||
TransitionPtr Transition::CreateFromMeta(Clip* c, Clip* s) {
|
||||
if (!em->filename.isEmpty()) {
|
||||
// load effect from file
|
||||
return TransitionPtr(new Transition(c, s, em));
|
||||
} else if (em->internal >= 0 && em->internal < TRANSITION_INTERNAL_COUNT) {
|
||||
// must be an internal effect
|
||||
switch (em->internal) {
|
||||
case TRANSITION_INTERNAL_CROSSDISSOLVE: return TransitionPtr(new CrossDissolveTransition(c, s, em));
|
||||
case TRANSITION_INTERNAL_LINEARFADE: return TransitionPtr(new LinearFadeTransition(c, s, em));
|
||||
case TRANSITION_INTERNAL_EXPONENTIALFADE: return TransitionPtr(new ExponentialFadeTransition(c, s, em));
|
||||
case TRANSITION_INTERNAL_LOGARITHMICFADE: return TransitionPtr(new LogarithmicFadeTransition(c, s, em));
|
||||
case kCrossDissolveTransition: return TransitionPtr(new CrossDissolveTransition(c, s, em));
|
||||
case kLinearFadeTransition: return TransitionPtr(new LinearFadeTransition(c, s, em));
|
||||
case kExponentialFadeTransition: return TransitionPtr(new ExponentialFadeTransition(c, s, em));
|
||||
case kLogarithmicFadeTransition: return TransitionPtr(new LogarithmicFadeTransition(c, s, em));
|
||||
//case TRANSITION_INTERNAL_CUBE: return TransitionPtr(new CubeTransition(c, s, em));
|
||||
}
|
||||
} else {
|
||||
@@ -118,6 +126,7 @@ TransitionPtr Transition::CreateFromMeta(Clip* c, Clip* s, const EffectMeta* em)
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
*/
|
||||
|
||||
void Transition::UpdateMaximumLength()
|
||||
{
|
||||
@@ -154,14 +163,3 @@ long Transition::GetMaximumEmptySpaceOnClip(Clip *c)
|
||||
|
||||
return maximum_transition_length;
|
||||
}
|
||||
|
||||
TransitionPtr Transition::Create(Clip* c, Clip* s, const EffectMeta* em, long length) {
|
||||
TransitionPtr t(CreateFromMeta(c, s, em));
|
||||
if (t != nullptr) {
|
||||
if (length > 0) {
|
||||
t->set_length(length);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+7
-15
@@ -21,7 +21,8 @@
|
||||
#ifndef TRANSITION_H
|
||||
#define TRANSITION_H
|
||||
|
||||
#include "effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "nodes/inputs.h"
|
||||
|
||||
enum TransitionType {
|
||||
kTransitionNone,
|
||||
@@ -29,23 +30,16 @@ enum TransitionType {
|
||||
kTransitionClosing
|
||||
};
|
||||
|
||||
enum TransitionInternal {
|
||||
TRANSITION_INTERNAL_CROSSDISSOLVE,
|
||||
TRANSITION_INTERNAL_LINEARFADE,
|
||||
TRANSITION_INTERNAL_EXPONENTIALFADE,
|
||||
TRANSITION_INTERNAL_LOGARITHMICFADE,
|
||||
//TRANSITION_INTERNAL_CUBE,
|
||||
TRANSITION_INTERNAL_COUNT
|
||||
};
|
||||
|
||||
class Transition;
|
||||
using TransitionPtr = std::shared_ptr<Transition>;
|
||||
|
||||
class Transition : public Effect {
|
||||
class Transition : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Transition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
virtual TransitionPtr copy(Clip* c, Clip* s);
|
||||
Transition(Clip* c);
|
||||
|
||||
virtual NodePtr copy(Clip* c) override;
|
||||
|
||||
Clip* secondary_clip;
|
||||
|
||||
virtual void save(QXmlStreamWriter& stream) override;
|
||||
@@ -57,8 +51,6 @@ public:
|
||||
Clip* get_opened_clip();
|
||||
Clip* get_closed_clip();
|
||||
|
||||
static TransitionPtr Create(Clip* c, Clip* s, const EffectMeta* em, long length = 0);
|
||||
static TransitionPtr CreateFromMeta(Clip *c, Clip *s, const EffectMeta* em);
|
||||
|
||||
private:
|
||||
DoubleInput* length_field;
|
||||
|
||||
@@ -21,8 +21,9 @@
|
||||
#include "clipboard.h"
|
||||
|
||||
#include "timeline/clip.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "effects/transition.h"
|
||||
#include "undo/undo.h"
|
||||
|
||||
Clipboard::Clipboard() :
|
||||
type_(CLIPBOARD_TYPE_CLIP)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <QVector>
|
||||
|
||||
#include "effects/transition.h"
|
||||
#include "project/media.h"
|
||||
|
||||
using VoidPtr = std::shared_ptr<void>;
|
||||
|
||||
|
||||
+6
-6
@@ -389,15 +389,15 @@ void OliveGlobal::PasteInternal(Sequence *s, bool insert)
|
||||
Clip* c = selected_clips.at(i);
|
||||
|
||||
for (int j=0;j<olive::clipboard.Count();j++) {
|
||||
EffectPtr e = std::static_pointer_cast<Effect>(olive::clipboard.Get(j));
|
||||
if (c->type() == e->meta->subtype) {
|
||||
NodePtr e = std::static_pointer_cast<Node>(olive::clipboard.Get(j));
|
||||
if (c->type() == e->subtype()) {
|
||||
int found = -1;
|
||||
if (ask_conflict) {
|
||||
replace = false;
|
||||
skip = false;
|
||||
}
|
||||
for (int k=0;k<c->effects.size();k++) {
|
||||
if (c->effects.at(k)->meta == e->meta) {
|
||||
if (c->effects.at(k)->id() == e->id()) {
|
||||
found = k;
|
||||
break;
|
||||
}
|
||||
@@ -407,7 +407,7 @@ void OliveGlobal::PasteInternal(Sequence *s, bool insert)
|
||||
box.setWindowTitle(tr("Effect already exists"));
|
||||
box.setText(tr("Clip '%1' already contains a '%2' effect. "
|
||||
"Would you like to replace it with the pasted one or add it as a separate effect?")
|
||||
.arg(c->name(), e->meta->name));
|
||||
.arg(c->name(), e->name()));
|
||||
box.setIcon(QMessageBox::Icon::Question);
|
||||
|
||||
box.addButton(tr("Add"), QMessageBox::YesRole);
|
||||
@@ -432,9 +432,9 @@ void OliveGlobal::PasteInternal(Sequence *s, bool insert)
|
||||
} else if (found >= 0 && replace) {
|
||||
ca->append(new EffectDeleteCommand(c->effects.at(found).get()));
|
||||
|
||||
ca->append(new AddEffectCommand(c, e->copy(c), nullptr, found));
|
||||
ca->append(new AddEffectCommand(c, e->copy(c), kInvalidNode, found));
|
||||
} else {
|
||||
ca->append(new AddEffectCommand(c, e->copy(c), nullptr));
|
||||
ca->append(new AddEffectCommand(c, e->copy(c), kInvalidNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "boolinput.h"
|
||||
|
||||
BoolInput::BoolInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
|
||||
BoolInput::BoolInput(Node* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
|
||||
EffectRow(parent, id, name, savable, keyframable)
|
||||
{
|
||||
BoolField* bool_field = new BoolField(this);
|
||||
|
||||
@@ -7,7 +7,7 @@ class BoolInput : public EffectRow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
BoolInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
BoolInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
|
||||
/**
|
||||
* @brief Get the boolean value at a given timecode
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "colorinput.h"
|
||||
|
||||
ColorInput::ColorInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
|
||||
ColorInput::ColorInput(Node* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
|
||||
EffectRow(parent, id, name, savable, keyframable)
|
||||
{
|
||||
AddField(new ColorField(this));
|
||||
@@ -10,5 +10,5 @@ ColorInput::ColorInput(Effect* parent, const QString& id, const QString& name, b
|
||||
|
||||
QColor ColorInput::GetColorAt(double timecode)
|
||||
{
|
||||
static_cast<ColorField*>(Field(0))->GetColorAt(timecode);
|
||||
return static_cast<ColorField*>(Field(0))->GetColorAt(timecode);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ class ColorInput : public EffectRow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ColorInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
ColorInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
|
||||
/**
|
||||
* @brief Get the color value at a given timecode
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "comboinput.h"
|
||||
|
||||
ComboInput::ComboInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
|
||||
ComboInput::ComboInput(Node* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
|
||||
EffectRow(parent, id, name, savable, keyframable)
|
||||
{
|
||||
ComboField* combo_field = new ComboField(this);
|
||||
|
||||
@@ -7,7 +7,7 @@ class ComboInput : public EffectRow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ComboInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
ComboInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
|
||||
/**
|
||||
* @brief Add an item to this ComboInput
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "fileinput.h"
|
||||
|
||||
FileInput::FileInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
|
||||
FileInput::FileInput(Node* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
|
||||
EffectRow(parent, id, name, savable, keyframable)
|
||||
{
|
||||
AddField(new FileField(this));
|
||||
|
||||
@@ -7,7 +7,7 @@ class FileInput : public EffectRow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FileInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
FileInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
|
||||
/**
|
||||
* @brief Get the filename at the given timecode
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "fontinput.h"
|
||||
|
||||
FontInput::FontInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
|
||||
FontInput::FontInput(Node* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
|
||||
EffectRow(parent, id, name, savable, keyframable)
|
||||
{
|
||||
AddField(new FontField(this));
|
||||
|
||||
@@ -7,7 +7,7 @@ class FontInput : public EffectRow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FontInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
FontInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
|
||||
/**
|
||||
* @brief Get the font family name at the given timecode
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "stringinput.h"
|
||||
|
||||
StringInput::StringInput(Effect* parent, const QString& id, const QString& name, bool rich_text, bool savable, bool keyframable) :
|
||||
StringInput::StringInput(Node* parent, const QString& id, const QString& name, bool rich_text, bool savable, bool keyframable) :
|
||||
EffectRow(parent, id, name, savable, keyframable)
|
||||
{
|
||||
AddField(new StringField(this, rich_text));
|
||||
|
||||
@@ -7,7 +7,7 @@ class StringInput : public EffectRow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
StringInput(Effect* parent,
|
||||
StringInput(Node* parent,
|
||||
const QString& id,
|
||||
const QString& name,
|
||||
bool rich_text = true,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <QVector4D>
|
||||
#include <QDebug>
|
||||
|
||||
VecInput::VecInput(Effect* parent, const QString& id, const QString& name, int values, bool savable, bool keyframable) :
|
||||
VecInput::VecInput(Node* parent, const QString& id, const QString& name, int values, bool savable, bool keyframable) :
|
||||
EffectRow(parent, id, name, savable, keyframable),
|
||||
single_value_mode_(false),
|
||||
values_(values)
|
||||
@@ -79,7 +79,7 @@ void VecInput::SetSingleValueMode(bool on)
|
||||
}
|
||||
}
|
||||
|
||||
DoubleInput::DoubleInput(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
|
||||
DoubleInput::DoubleInput(Node *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
|
||||
VecInput(parent, id, name, 1, savable, keyframable)
|
||||
{
|
||||
}
|
||||
@@ -89,7 +89,7 @@ double DoubleInput::GetDoubleAt(double timecode)
|
||||
return static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode);
|
||||
}
|
||||
|
||||
Vec2Input::Vec2Input(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
|
||||
Vec2Input::Vec2Input(Node *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
|
||||
VecInput(parent, id, name, 2, savable, keyframable)
|
||||
{
|
||||
}
|
||||
@@ -121,7 +121,7 @@ void Vec2Input::SetValueAt(double timecode, const QVariant &value)
|
||||
static_cast<DoubleField*>(Field(1))->SetValueAt(timecode, vec2.y());
|
||||
}
|
||||
|
||||
Vec3Input::Vec3Input(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
|
||||
Vec3Input::Vec3Input(Node *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
|
||||
VecInput(parent, id, name, 3, savable, keyframable)
|
||||
{
|
||||
}
|
||||
@@ -156,7 +156,7 @@ void Vec3Input::SetValueAt(double timecode, const QVariant &value)
|
||||
static_cast<DoubleField*>(Field(2))->SetValueAt(timecode, vec3.z());
|
||||
}
|
||||
|
||||
Vec4Input::Vec4Input(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
|
||||
Vec4Input::Vec4Input(Node *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
|
||||
VecInput(parent, id, name, 4, savable, keyframable)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ class VecInput : public EffectRow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VecInput(Effect* parent, const QString& id, const QString& name, int values, bool savable = true, bool keyframable = true);
|
||||
VecInput(Node* parent, const QString& id, const QString& name, int values, bool savable = true, bool keyframable = true);
|
||||
|
||||
void SetMinimum(double minimum);
|
||||
void SetMaximum(double maximum);
|
||||
@@ -43,14 +43,14 @@ private:
|
||||
class DoubleInput : public VecInput
|
||||
{
|
||||
public:
|
||||
DoubleInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
DoubleInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
|
||||
double GetDoubleAt(double timecode);
|
||||
};
|
||||
|
||||
class Vec2Input : public VecInput {
|
||||
public:
|
||||
Vec2Input(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
Vec2Input(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
|
||||
QVector2D GetVector2DAt(double timecode);
|
||||
virtual QVariant GetValueAt(double timecode) override;
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
|
||||
class Vec3Input : public VecInput {
|
||||
public:
|
||||
Vec3Input(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
Vec3Input(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
|
||||
QVector3D GetVector3DAt(double timecode);
|
||||
virtual QVariant GetValueAt(double timecode) override;
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
class Vec4Input : public VecInput {
|
||||
public:
|
||||
Vec4Input(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
Vec4Input(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
|
||||
|
||||
QVector4D GetVector4DAt(double timecode);
|
||||
virtual QVariant GetValueAt(double timecode) override;
|
||||
|
||||
+129
-142
@@ -18,7 +18,7 @@
|
||||
|
||||
***/
|
||||
|
||||
#include "effect.h"
|
||||
#include "node.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QGridLayout>
|
||||
@@ -50,61 +50,47 @@
|
||||
#include "global/math.h"
|
||||
#include "global/clipboard.h"
|
||||
#include "global/config.h"
|
||||
#include "transition.h"
|
||||
#include "effects/transition.h"
|
||||
#include "undo/undostack.h"
|
||||
#include "rendering/shadergenerators.h"
|
||||
#include "global/timing.h"
|
||||
#include "nodes/nodes.h"
|
||||
|
||||
#include "effects/internal/transformeffect.h"
|
||||
#include "effects/internal/texteffect.h"
|
||||
#include "effects/internal/timecodeeffect.h"
|
||||
#include "effects/internal/solideffect.h"
|
||||
#include "effects/internal/audionoiseeffect.h"
|
||||
#include "effects/internal/toneeffect.h"
|
||||
#include "effects/internal/volumeeffect.h"
|
||||
#include "effects/internal/paneffect.h"
|
||||
#include "effects/internal/shakeeffect.h"
|
||||
#include "effects/internal/cornerpineffect.h"
|
||||
#include "effects/internal/vsthost.h"
|
||||
#include "effects/internal/fillleftrighteffect.h"
|
||||
#include "effects/internal/richtexteffect.h"
|
||||
QVector<NodePtr> olive::node_library;
|
||||
|
||||
QVector<EffectMeta> olive::effects;
|
||||
QVector<BlendMode> olive::blend_modes;
|
||||
QString olive::generated_blending_shader;
|
||||
|
||||
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) {
|
||||
case EFFECT_INTERNAL_TRANSFORM: return std::make_shared<TransformEffect>(c, em);
|
||||
case EFFECT_INTERNAL_TEXT: return std::make_shared<TextEffect>(c, em);
|
||||
case EFFECT_INTERNAL_TIMECODE: return std::make_shared<TimecodeEffect>(c, em);
|
||||
case EFFECT_INTERNAL_SOLID: return std::make_shared<SolidEffect>(c, em);
|
||||
case EFFECT_INTERNAL_NOISE: return std::make_shared<AudioNoiseEffect>(c, em);
|
||||
case EFFECT_INTERNAL_VOLUME: return std::make_shared<VolumeEffect>(c, em);
|
||||
case EFFECT_INTERNAL_PAN: return std::make_shared<PanEffect>(c, em);
|
||||
case EFFECT_INTERNAL_TONE: return std::make_shared<ToneEffect>(c, em);
|
||||
case EFFECT_INTERNAL_SHAKE: return std::make_shared<ShakeEffect>(c, em);
|
||||
case EFFECT_INTERNAL_CORNERPIN: return std::make_shared<CornerPinEffect>(c, em);
|
||||
case EFFECT_INTERNAL_FILLLEFTRIGHT: return std::make_shared<FillLeftRightEffect>(c, em);
|
||||
case EFFECT_INTERNAL_VST: return std::make_shared<VSTHost>(c, em);
|
||||
case EFFECT_INTERNAL_RICHTEXT: return std::make_shared<RichTextEffect>(c, em);
|
||||
}
|
||||
} else if (!em->filename.isEmpty()) {
|
||||
// load effect from file
|
||||
return std::make_shared<NodeShader>(c, em);
|
||||
} else {
|
||||
/*
|
||||
NodePtr Node::Create(Clip* c) {
|
||||
// must be an internal effect
|
||||
switch (em->internal) {
|
||||
case kTransformEffect: return std::make_shared<TransformEffect>(c, em);
|
||||
case kTextInput: return std::make_shared<TextEffect>(c, em);
|
||||
case kTimecodeEffect: return std::make_shared<TimecodeEffect>(c, em);
|
||||
case kSolidInput: return std::make_shared<SolidEffect>(c, em);
|
||||
case kNoiseInput: return std::make_shared<AudioNoiseEffect>(c, em);
|
||||
case kVolumeEffect: return std::make_shared<VolumeEffect>(c, em);
|
||||
case kPanEffect: return std::make_shared<PanEffect>(c, em);
|
||||
case kToneInput: return std::make_shared<ToneEffect>(c, em);
|
||||
case kShakeEffect: return std::make_shared<ShakeEffect>(c, em);
|
||||
case kCornerPinEffect: return std::make_shared<CornerPinEffect>(c, em);
|
||||
case kFillLeftRightEffect: return std::make_shared<FillLeftRightEffect>(c, em);
|
||||
case kVstEffect: return std::make_shared<VSTHost>(c, em);
|
||||
case kRichTextInput: return std::make_shared<RichTextEffect>(c, em);
|
||||
case kMediaInput: return std::make_shared<NodeMedia>(c, em);
|
||||
case kShaderEffect: return std::make_shared<NodeShader>(c, em);
|
||||
case kImageOutput: return std::make_shared<NodeImageOutput>(c, em);
|
||||
default:
|
||||
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));
|
||||
QCoreApplication::translate("Effect", "No candidate for effect '%1'. This effect may be "
|
||||
"corrupt. Try reinstalling it or Olive.").arg(em->name));
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
*/
|
||||
|
||||
const EffectMeta* Effect::GetInternalMeta(int internal_id, int type) {
|
||||
/*
|
||||
const EffectMeta* Node::GetInternalMeta(int internal_id, int type) {
|
||||
for (int i=0;i<olive::effects.size();i++) {
|
||||
if (olive::effects.at(i).internal == internal_id && olive::effects.at(i).type == type) {
|
||||
return &olive::effects.at(i);
|
||||
@@ -112,10 +98,10 @@ const EffectMeta* Effect::GetInternalMeta(int internal_id, int type) {
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
*/
|
||||
|
||||
Effect::Effect(Clip* c, const EffectMeta *em) :
|
||||
Node::Node(Clip* c) :
|
||||
parent_clip(c),
|
||||
meta(em),
|
||||
flags_(0),
|
||||
shader_program_(nullptr),
|
||||
texture(0),
|
||||
@@ -127,14 +113,10 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
|
||||
enabled_(true),
|
||||
expanded_(true),
|
||||
texture_ctx(nullptr)
|
||||
{
|
||||
if (em != nullptr) {
|
||||
// set up UI from effect metadata
|
||||
name = em->name;
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
Effect::~Effect() {
|
||||
Node::~Node() {
|
||||
if (isOpen) {
|
||||
close();
|
||||
}
|
||||
@@ -150,13 +132,23 @@ Effect::~Effect() {
|
||||
}
|
||||
}
|
||||
|
||||
void Effect::AddRow(EffectRow *row)
|
||||
QString Node::category()
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool Node::IsCreatable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Node::AddRow(EffectRow *row)
|
||||
{
|
||||
row->setParent(this);
|
||||
rows.append(row);
|
||||
}
|
||||
|
||||
void Effect::copy_field_keyframes(EffectPtr e) {
|
||||
void Node::copy_field_keyframes(NodePtr e) {
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
EffectRow* row = rows.at(i);
|
||||
EffectRow* copy_row = e->rows.at(i);
|
||||
@@ -177,40 +169,43 @@ void Effect::copy_field_keyframes(EffectPtr e) {
|
||||
}
|
||||
}
|
||||
|
||||
EffectRow* Effect::row(int i) {
|
||||
EffectRow* Node::row(int i) {
|
||||
return rows.at(i);
|
||||
}
|
||||
|
||||
int Effect::row_count() {
|
||||
int Node::row_count() {
|
||||
return rows.size();
|
||||
}
|
||||
|
||||
EffectGizmo *Effect::add_gizmo(int type) {
|
||||
EffectGizmo *Node::add_gizmo(int type) {
|
||||
EffectGizmo* gizmo = new EffectGizmo(this, type);
|
||||
gizmos.append(gizmo);
|
||||
return gizmo;
|
||||
}
|
||||
|
||||
EffectGizmo *Effect::gizmo(int i) {
|
||||
EffectGizmo *Node::gizmo(int i) {
|
||||
return gizmos.at(i);
|
||||
}
|
||||
|
||||
int Effect::gizmo_count() {
|
||||
int Node::gizmo_count() {
|
||||
return gizmos.size();
|
||||
}
|
||||
|
||||
void Effect::refresh() {}
|
||||
void Node::refresh() {}
|
||||
|
||||
void Effect::FieldChanged() {
|
||||
update_ui(false);
|
||||
void Node::FieldChanged() {
|
||||
// Update the UI if a field has been modified, but don't both if this effect is inactive
|
||||
if (parent_clip != nullptr) {
|
||||
update_ui(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Effect::delete_self() {
|
||||
void Node::delete_self() {
|
||||
olive::undo_stack.push(new EffectDeleteCommand(this));
|
||||
update_ui(true);
|
||||
}
|
||||
|
||||
void Effect::move_up() {
|
||||
void Node::move_up() {
|
||||
int index_of_effect = parent_clip->IndexOfEffect(this);
|
||||
if (index_of_effect == 0) {
|
||||
return;
|
||||
@@ -225,7 +220,7 @@ void Effect::move_up() {
|
||||
panel_sequence_viewer->viewer_widget()->frame_update();
|
||||
}
|
||||
|
||||
void Effect::move_down() {
|
||||
void Node::move_down() {
|
||||
int index_of_effect = parent_clip->IndexOfEffect(this);
|
||||
if (index_of_effect == parent_clip->effects.size()-1) {
|
||||
return;
|
||||
@@ -240,7 +235,7 @@ void Effect::move_down() {
|
||||
panel_sequence_viewer->viewer_widget()->frame_update();
|
||||
}
|
||||
|
||||
void Effect::save_to_file() {
|
||||
void Node::save_to_file() {
|
||||
// save effect settings to file
|
||||
QString file = QFileDialog::getSaveFileName(olive::MainWindow,
|
||||
tr("Save Effect Settings"),
|
||||
@@ -270,7 +265,7 @@ void Effect::save_to_file() {
|
||||
}
|
||||
}
|
||||
|
||||
void Effect::load_from_file() {
|
||||
void Node::load_from_file() {
|
||||
// load effect settings from file
|
||||
QString file = QFileDialog::getOpenFileName(olive::MainWindow,
|
||||
tr("Load Effect Settings"),
|
||||
@@ -296,31 +291,31 @@ void Effect::load_from_file() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Effect::AlwaysUpdate()
|
||||
bool Node::AlwaysUpdate()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Effect::IsEnabled() {
|
||||
bool Node::IsEnabled() {
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
bool Effect::IsExpanded()
|
||||
bool Node::IsExpanded()
|
||||
{
|
||||
return expanded_;
|
||||
}
|
||||
|
||||
void Effect::SetExpanded(bool e)
|
||||
void Node::SetExpanded(bool e)
|
||||
{
|
||||
expanded_ = e;
|
||||
}
|
||||
|
||||
void Effect::SetEnabled(bool b) {
|
||||
void Node::SetEnabled(bool b) {
|
||||
enabled_ = b;
|
||||
emit EnabledChanged(b);
|
||||
}
|
||||
|
||||
void Effect::load(QXmlStreamReader& stream) {
|
||||
void Node::load(QXmlStreamReader& stream) {
|
||||
/*
|
||||
int row_count = 0;
|
||||
|
||||
@@ -412,9 +407,9 @@ void Effect::load(QXmlStreamReader& stream) {
|
||||
*/
|
||||
}
|
||||
|
||||
void Effect::custom_load(QXmlStreamReader &) {}
|
||||
void Node::custom_load(QXmlStreamReader &) {}
|
||||
|
||||
void Effect::save(QXmlStreamWriter& stream) {
|
||||
void Node::save(QXmlStreamWriter& stream) {
|
||||
/*
|
||||
stream.writeAttribute("name", meta->category + "/" + meta->name);
|
||||
stream.writeAttribute("enabled", QString::number(IsEnabled()));
|
||||
@@ -451,7 +446,7 @@ void Effect::save(QXmlStreamWriter& stream) {
|
||||
*/
|
||||
}
|
||||
|
||||
void Effect::load_from_string(const QByteArray &s) {
|
||||
void Node::load_from_string(const QByteArray &s) {
|
||||
// clear existing keyframe data
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
EffectRow* row = rows.at(i);
|
||||
@@ -465,6 +460,8 @@ void Effect::load_from_string(const QByteArray &s) {
|
||||
// write settings with xml writer
|
||||
QXmlStreamReader stream(s);
|
||||
|
||||
bool found_id = false;
|
||||
|
||||
while (!stream.atEnd()) {
|
||||
stream.readNext();
|
||||
|
||||
@@ -475,16 +472,9 @@ void Effect::load_from_string(const QByteArray &s) {
|
||||
const QXmlStreamAttributes& attributes = stream.attributes();
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "name") {
|
||||
if (Effect::GetMetaFromName(attr.value().toString()) == meta) {
|
||||
// pass off to standard loading function
|
||||
load(stream);
|
||||
} else {
|
||||
QMessageBox::critical(olive::MainWindow,
|
||||
tr("Load Settings Failed"),
|
||||
tr("This settings file doesn't match this effect."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
if (attr.name() == "id") {
|
||||
load(stream);
|
||||
found_id = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -493,9 +483,16 @@ void Effect::load_from_string(const QByteArray &s) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_id) {
|
||||
QMessageBox::critical(olive::MainWindow,
|
||||
tr("Load Settings Failed"),
|
||||
tr("This settings file doesn't match this effect."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray Effect::save_to_string() {
|
||||
QByteArray Node::save_to_string() {
|
||||
QByteArray save_data;
|
||||
|
||||
// write settings to string with xml writer
|
||||
@@ -515,11 +512,12 @@ QByteArray Effect::save_to_string() {
|
||||
return save_data;
|
||||
}
|
||||
|
||||
bool Effect::is_open() {
|
||||
bool Node::is_open() {
|
||||
return isOpen;
|
||||
}
|
||||
|
||||
void Effect::validate_meta_path() {
|
||||
void Node::validate_meta_path() {
|
||||
/*
|
||||
if (!meta->path.isEmpty() || (shader_vert_path_.isEmpty() && shader_frag_path_.isEmpty())) return;
|
||||
QList<QString> effects_paths = get_effects_paths();
|
||||
const QString& test_fn = shader_vert_path_.isEmpty() ? shader_frag_path_ : shader_vert_path_;
|
||||
@@ -534,9 +532,11 @@ void Effect::validate_meta_path() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void Effect::open() {
|
||||
void Node::open() {
|
||||
/*
|
||||
if (isOpen) {
|
||||
qWarning() << "Tried to open an effect that was already open";
|
||||
close();
|
||||
@@ -548,7 +548,7 @@ void Effect::open() {
|
||||
validate_meta_path();
|
||||
|
||||
QString frag_shader_str;
|
||||
QString frag_file_url = QDir(meta->path).filePath(shader_frag_path_);
|
||||
QString frag_file_url = QDir(file).filePath(shader_frag_path_);
|
||||
QFile frag_file(frag_file_url);
|
||||
if (frag_file.open(QFile::ReadOnly)) {
|
||||
frag_shader_str = frag_file.readAll();
|
||||
@@ -570,41 +570,16 @@ void Effect::open() {
|
||||
shader_program_ = olive::shader::GetPipeline(shader_func, frag_shader_str);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
bool shader_compiled = true;
|
||||
if (!shader_vert_path_.isEmpty()) {
|
||||
if (shader_program_->addShaderFromSourceFile(QOpenGLShader::Vertex, meta->path + "/" + shader_vert_path_)) {
|
||||
qInfo() << "Vertex shader added successfully";
|
||||
} else {
|
||||
shader_compiled = false;
|
||||
qWarning() << "Vertex shader could not be added";
|
||||
}
|
||||
}
|
||||
if (!shader_frag_path_.isEmpty()) {
|
||||
if (shader_program_->addShaderFromSourceFile(QOpenGLShader::Fragment, meta->path + "/" + shader_frag_path_)) {
|
||||
qInfo() << "Fragment shader added successfully";
|
||||
} else {
|
||||
shader_compiled = false;
|
||||
qWarning() << "Fragment shader could not be added";
|
||||
}
|
||||
}
|
||||
if (shader_compiled) {
|
||||
if (shader_program_->link()) {
|
||||
qInfo() << "Shader program linked successfully";
|
||||
} else {
|
||||
qWarning() << "Shader program failed to link";
|
||||
}
|
||||
}
|
||||
*/
|
||||
isOpen = true;
|
||||
}
|
||||
} else {
|
||||
isOpen = true;
|
||||
}
|
||||
*/
|
||||
isOpen = true;
|
||||
}
|
||||
|
||||
void Effect::close() {
|
||||
void Node::close() {
|
||||
if (!isOpen) {
|
||||
qWarning() << "Tried to close an effect that was already closed";
|
||||
}
|
||||
@@ -613,43 +588,43 @@ void Effect::close() {
|
||||
isOpen = false;
|
||||
}
|
||||
|
||||
bool Effect::is_shader_linked() {
|
||||
bool Node::is_shader_linked() {
|
||||
return shader_program_ != nullptr && shader_program_->isLinked();
|
||||
}
|
||||
|
||||
QOpenGLShaderProgram *Effect::GetShaderPipeline()
|
||||
QOpenGLShaderProgram *Node::GetShaderPipeline()
|
||||
{
|
||||
return shader_program_.get();
|
||||
}
|
||||
|
||||
int Effect::Flags()
|
||||
int Node::Flags()
|
||||
{
|
||||
return flags_;
|
||||
}
|
||||
|
||||
void Effect::SetFlags(int flags)
|
||||
void Node::SetFlags(int flags)
|
||||
{
|
||||
flags_ = flags;
|
||||
}
|
||||
|
||||
int Effect::getIterations() {
|
||||
int Node::getIterations() {
|
||||
return iterations;
|
||||
}
|
||||
|
||||
void Effect::setIterations(int i) {
|
||||
void Node::setIterations(int i) {
|
||||
iterations = i;
|
||||
}
|
||||
|
||||
void Effect::process_image(double, uint8_t *, uint8_t *, int){}
|
||||
void Node::process_image(double, uint8_t *, uint8_t *, int){}
|
||||
|
||||
EffectPtr Effect::copy(Clip *c) {
|
||||
EffectPtr copy = Effect::Create(c, meta);
|
||||
NodePtr Node::copy(Clip *c) {
|
||||
NodePtr copy = Create(c);
|
||||
copy->SetEnabled(IsEnabled());
|
||||
copy_field_keyframes(copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
|
||||
void Node::process_shader(double timecode, GLTextureCoords&, int iteration) {
|
||||
/*
|
||||
shader_program_->bind();
|
||||
|
||||
@@ -704,9 +679,9 @@ void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
|
||||
*/
|
||||
}
|
||||
|
||||
void Effect::process_coords(double, GLTextureCoords&, int) {}
|
||||
void Node::process_coords(double, GLTextureCoords&, int) {}
|
||||
|
||||
GLuint Effect::process_superimpose(QOpenGLContext* ctx, double timecode) {
|
||||
GLuint Node::process_superimpose(QOpenGLContext* ctx, double timecode) {
|
||||
bool dimensions_changed = false;
|
||||
bool redrew_image = false;
|
||||
|
||||
@@ -760,11 +735,11 @@ GLuint Effect::process_superimpose(QOpenGLContext* ctx, double timecode) {
|
||||
return texture;
|
||||
}
|
||||
|
||||
void Effect::process_audio(double, double, float **, int, int, int) {}
|
||||
void Node::process_audio(double, double, float **, int, int, int) {}
|
||||
|
||||
void Effect::gizmo_draw(double, GLTextureCoords &) {}
|
||||
void Node::gizmo_draw(double, GLTextureCoords &) {}
|
||||
|
||||
void Effect::gizmo_move(EffectGizmo* gizmo, int x_movement, int y_movement, double timecode, bool done) {
|
||||
void Node::gizmo_move(EffectGizmo* gizmo, int x_movement, int y_movement, double timecode, bool done) {
|
||||
// Loop through each gizmo to find `gizmo`
|
||||
for (int i=0;i<gizmos.size();i++) {
|
||||
|
||||
@@ -833,7 +808,7 @@ void Effect::gizmo_move(EffectGizmo* gizmo, int x_movement, int y_movement, doub
|
||||
}
|
||||
}
|
||||
|
||||
void Effect::gizmo_world_to_screen(const QMatrix4x4& matrix, const QMatrix4x4& projection) {
|
||||
void Node::gizmo_world_to_screen(const QMatrix4x4& matrix, const QMatrix4x4& projection) {
|
||||
for (int i=0;i<gizmos.size();i++) {
|
||||
EffectGizmo* g = gizmos.at(i);
|
||||
|
||||
@@ -854,21 +829,21 @@ void Effect::gizmo_world_to_screen(const QMatrix4x4& matrix, const QMatrix4x4& p
|
||||
}
|
||||
}
|
||||
|
||||
bool Effect::are_gizmos_enabled() {
|
||||
bool Node::are_gizmos_enabled() {
|
||||
return (gizmos.size() > 0);
|
||||
}
|
||||
|
||||
double Effect::Now()
|
||||
double Node::Now()
|
||||
{
|
||||
return playhead_to_clip_seconds(parent_clip, parent_clip->track()->sequence()->playhead);
|
||||
}
|
||||
|
||||
long Effect::NowInFrames()
|
||||
long Node::NowInFrames()
|
||||
{
|
||||
return playhead_to_clip_frame(parent_clip, parent_clip->track()->sequence()->playhead);
|
||||
}
|
||||
|
||||
void Effect::redraw(double) {
|
||||
void Node::redraw(double) {
|
||||
/*
|
||||
// run javascript
|
||||
QPainter p(&img);
|
||||
@@ -912,7 +887,7 @@ void Effect::redraw(double) {
|
||||
*/
|
||||
}
|
||||
|
||||
bool Effect::valueHasChanged(double timecode) {
|
||||
bool Node::valueHasChanged(double timecode) {
|
||||
if (cachedValues.isEmpty()) {
|
||||
|
||||
for (int i=0;i<row_count();i++) {
|
||||
@@ -943,7 +918,7 @@ bool Effect::valueHasChanged(double timecode) {
|
||||
}
|
||||
}
|
||||
|
||||
void Effect::delete_texture() {
|
||||
void Node::delete_texture() {
|
||||
if (texture_ctx != nullptr) {
|
||||
texture_ctx->functions()->glDeleteTextures(1, &texture);
|
||||
texture = 0;
|
||||
@@ -951,7 +926,18 @@ void Effect::delete_texture() {
|
||||
}
|
||||
}
|
||||
|
||||
const EffectMeta* Effect::GetMetaFromName(const QString& input) {
|
||||
int GetNodeLibraryIndexFromId(const QString& id) {
|
||||
for (int i=0;i<olive::node_library.size();i++) {
|
||||
if (olive::node_library.at(i)->id() == id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
const EffectMeta* Node::GetMetaFromName(const QString& input) {
|
||||
int split_index = input.indexOf('/');
|
||||
QString category;
|
||||
if (split_index > -1) {
|
||||
@@ -968,3 +954,4 @@ const EffectMeta* Effect::GetMetaFromName(const QString& input) {
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
*/
|
||||
@@ -40,44 +40,45 @@
|
||||
#include <QXmlStreamWriter>
|
||||
#include <random>
|
||||
|
||||
#include "ui/collapsiblewidget.h"
|
||||
#include "effectrow.h"
|
||||
#include "effectgizmo.h"
|
||||
#include "timeline/tracktypes.h"
|
||||
#include "rendering/qopenglshaderprogramptr.h"
|
||||
#include "nodes/inputs.h"
|
||||
#include "inputs.h"
|
||||
#include "effects/effectgizmo.h"
|
||||
|
||||
class EffectGizmo;
|
||||
class KeyframeDataChange;
|
||||
|
||||
class Clip;
|
||||
using ClipPtr = std::shared_ptr<Clip>;
|
||||
|
||||
class Effect;
|
||||
using EffectPtr = std::shared_ptr<Effect>;
|
||||
class Node;
|
||||
using NodePtr = std::shared_ptr<Node>;
|
||||
|
||||
struct EffectMeta {
|
||||
QString name;
|
||||
QString category;
|
||||
QString filename;
|
||||
QString path;
|
||||
QString tooltip;
|
||||
int internal;
|
||||
int type;
|
||||
int subtype;
|
||||
enum NodeType {
|
||||
kTransformEffect,
|
||||
kTextInput,
|
||||
kSolidInput,
|
||||
kNoiseInput,
|
||||
kVolumeEffect,
|
||||
kPanEffect,
|
||||
kToneInput,
|
||||
kShakeEffect,
|
||||
kTimecodeEffect,
|
||||
kMaskEffect,
|
||||
kFillLeftRightEffect,
|
||||
kVstEffect,
|
||||
kCornerPinEffect,
|
||||
kRichTextInput,
|
||||
kMediaInput,
|
||||
kShaderEffect,
|
||||
kImageOutput,
|
||||
kCrossDissolveTransition,
|
||||
kLinearFadeTransition,
|
||||
kExponentialFadeTransition,
|
||||
kLogarithmicFadeTransition,
|
||||
kInvalidNode
|
||||
};
|
||||
|
||||
struct BlendMode {
|
||||
QString name;
|
||||
QString url;
|
||||
QString function_name;
|
||||
|
||||
bool loaded;
|
||||
};
|
||||
|
||||
namespace olive {
|
||||
extern QVector<EffectMeta> effects;
|
||||
extern QVector<BlendMode> blend_modes;
|
||||
|
||||
// TODO weird place to put this?
|
||||
extern QString generated_blending_shader;
|
||||
}
|
||||
|
||||
double log_volume(double linear);
|
||||
|
||||
enum EffectType {
|
||||
@@ -92,24 +93,6 @@ enum EffectKeyframeType {
|
||||
EFFECT_KEYFRAME_HOLD
|
||||
};
|
||||
|
||||
enum EffectInternal {
|
||||
EFFECT_INTERNAL_TRANSFORM,
|
||||
EFFECT_INTERNAL_TEXT,
|
||||
EFFECT_INTERNAL_SOLID,
|
||||
EFFECT_INTERNAL_NOISE,
|
||||
EFFECT_INTERNAL_VOLUME,
|
||||
EFFECT_INTERNAL_PAN,
|
||||
EFFECT_INTERNAL_TONE,
|
||||
EFFECT_INTERNAL_SHAKE,
|
||||
EFFECT_INTERNAL_TIMECODE,
|
||||
EFFECT_INTERNAL_MASK,
|
||||
EFFECT_INTERNAL_FILLLEFTRIGHT,
|
||||
EFFECT_INTERNAL_VST,
|
||||
EFFECT_INTERNAL_CORNERPIN,
|
||||
EFFECT_INTERNAL_RICHTEXT,
|
||||
EFFECT_INTERNAL_COUNT
|
||||
};
|
||||
|
||||
struct GLTextureCoords {
|
||||
QMatrix4x4 matrix;
|
||||
|
||||
@@ -123,20 +106,25 @@ struct GLTextureCoords {
|
||||
QVector2D texture_bottom_left;
|
||||
QVector2D texture_bottom_right;
|
||||
|
||||
int blendmode;
|
||||
float opacity;
|
||||
};
|
||||
|
||||
class Effect : public QObject {
|
||||
class Node : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Effect(Clip *c, const EffectMeta* em);
|
||||
~Effect();
|
||||
Node(Clip *c);
|
||||
~Node();
|
||||
|
||||
Clip* parent_clip;
|
||||
const EffectMeta* meta;
|
||||
int id;
|
||||
QString name;
|
||||
|
||||
virtual QString name() = 0;
|
||||
virtual QString id() = 0;
|
||||
virtual QString category();
|
||||
virtual QString description() = 0;
|
||||
virtual EffectType type() = 0;
|
||||
virtual olive::TrackType subtype() = 0;
|
||||
virtual bool IsCreatable();
|
||||
virtual NodePtr Create(Clip *c) = 0;
|
||||
|
||||
void AddRow(EffectRow* row);
|
||||
|
||||
@@ -152,8 +140,8 @@ public:
|
||||
|
||||
virtual void refresh();
|
||||
|
||||
virtual EffectPtr copy(Clip* c);
|
||||
void copy_field_keyframes(EffectPtr e);
|
||||
virtual NodePtr copy(Clip* c);
|
||||
void copy_field_keyframes(NodePtr e);
|
||||
|
||||
virtual void load(QXmlStreamReader& stream);
|
||||
virtual void custom_load(QXmlStreamReader& stream);
|
||||
@@ -233,9 +221,6 @@ public:
|
||||
return distribution(generator);
|
||||
}
|
||||
|
||||
static EffectPtr Create(Clip *c, const EffectMeta *em);
|
||||
static const EffectMeta* GetInternalMeta(int internal_id, int type);
|
||||
static const EffectMeta* GetMetaFromName(const QString& input);
|
||||
public slots:
|
||||
void FieldChanged();
|
||||
void SetEnabled(bool b);
|
||||
@@ -287,4 +272,8 @@ private:
|
||||
void validate_meta_path();
|
||||
};
|
||||
|
||||
namespace olive {
|
||||
extern QVector<NodePtr> node_library;
|
||||
}
|
||||
|
||||
#endif // EFFECT_H
|
||||
+1
-1
@@ -8,7 +8,7 @@ NodeGraph::NodeGraph() :
|
||||
|
||||
}
|
||||
|
||||
Effect *NodeGraph::OutputNode()
|
||||
Node *NodeGraph::OutputNode()
|
||||
{
|
||||
return output_node_.get();
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
#ifndef NODEGRAPH_H
|
||||
#define NODEGRAPH_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class NodeGraph
|
||||
{
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
void AddNode(EffectPtr node);
|
||||
void AddNode(NodePtr node);
|
||||
|
||||
/**
|
||||
* @brief Process the graph
|
||||
@@ -39,15 +39,15 @@ public:
|
||||
*
|
||||
* The node to set as the output node. The graph takes ownership of the node and the user cannot delete it.
|
||||
*/
|
||||
void SetOutputNode(EffectPtr node);
|
||||
void SetOutputNode(NodePtr node);
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set output node
|
||||
*/
|
||||
Effect* OutputNode();
|
||||
Node* OutputNode();
|
||||
|
||||
private:
|
||||
EffectPtr output_node_;
|
||||
NodePtr output_node_;
|
||||
};
|
||||
|
||||
#endif // NODEGRAPH_H
|
||||
|
||||
@@ -1,6 +1,42 @@
|
||||
#include "nodeimageoutput.h"
|
||||
|
||||
NodeImageOutput::NodeImageOutput()
|
||||
NodeImageOutput::NodeImageOutput(Clip *c) :
|
||||
Node(c)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString NodeImageOutput::name()
|
||||
{
|
||||
return tr("Image Output");
|
||||
}
|
||||
|
||||
QString NodeImageOutput::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.imageoutput";
|
||||
}
|
||||
|
||||
QString NodeImageOutput::category()
|
||||
{
|
||||
return tr("Outputs");
|
||||
}
|
||||
|
||||
QString NodeImageOutput::description()
|
||||
{
|
||||
return tr("Used for outputting images outside of the node graph.");
|
||||
}
|
||||
|
||||
EffectType NodeImageOutput::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType NodeImageOutput::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
NodePtr NodeImageOutput::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<NodeImageOutput>(c);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
#ifndef NODEIMAGEOUTPUT_H
|
||||
#define NODEIMAGEOUTPUT_H
|
||||
|
||||
#include "nodes/node.h"
|
||||
|
||||
class NodeImageOutput
|
||||
class NodeImageOutput : public Node
|
||||
{
|
||||
public:
|
||||
NodeImageOutput();
|
||||
NodeImageOutput(Clip* c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
};
|
||||
|
||||
#endif // NODEIMAGEOUTPUT_H
|
||||
#endif // NODEIMAGEOUTPUT_H
|
||||
|
||||
@@ -1,6 +1,41 @@
|
||||
#include "nodemedia.h"
|
||||
|
||||
NodeMedia::NodeMedia()
|
||||
NodeMedia::NodeMedia(Clip* c) :
|
||||
Node(c)
|
||||
{
|
||||
}
|
||||
|
||||
QString NodeMedia::name()
|
||||
{
|
||||
return tr("Media");
|
||||
}
|
||||
|
||||
QString NodeMedia::id()
|
||||
{
|
||||
return "org.olivevideoeditor.Olive.media";
|
||||
}
|
||||
|
||||
QString NodeMedia::category()
|
||||
{
|
||||
return tr("Inputs");
|
||||
}
|
||||
|
||||
QString NodeMedia::description()
|
||||
{
|
||||
return tr("Retrieve frames from a media source.");
|
||||
}
|
||||
|
||||
EffectType NodeMedia::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType NodeMedia::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
NodePtr NodeMedia::Create(Clip *c)
|
||||
{
|
||||
return std::make_shared<NodeMedia>(c);
|
||||
}
|
||||
|
||||
+12
-2
@@ -1,10 +1,20 @@
|
||||
#ifndef MEDIANODE_H
|
||||
#define MEDIANODE_H
|
||||
|
||||
class NodeMedia
|
||||
#include "nodes/node.h"
|
||||
|
||||
class NodeMedia : public Node
|
||||
{
|
||||
public:
|
||||
NodeMedia();
|
||||
NodeMedia(Clip *c);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
};
|
||||
|
||||
#endif // MEDIANODE_H
|
||||
|
||||
+58
-23
@@ -1,10 +1,18 @@
|
||||
#include "nodeshader.h"
|
||||
|
||||
NodeShader::NodeShader(Clip* c, const EffectMeta *em) :
|
||||
Effect(c, em)
|
||||
NodeShader::NodeShader(Clip* c,
|
||||
const QString &name,
|
||||
const QString &id,
|
||||
const QString &category,
|
||||
const QString &filename) :
|
||||
Node(c),
|
||||
name_(name),
|
||||
id_(id),
|
||||
category_(category),
|
||||
filename_(filename)
|
||||
{
|
||||
if (em != nullptr && !em->filename.isEmpty() && em->internal == -1) {
|
||||
QFile effect_file(em->filename);
|
||||
if (!filename_.isEmpty()) {
|
||||
QFile effect_file(filename_);
|
||||
if (effect_file.open(QFile::ReadOnly)) {
|
||||
QXmlStreamReader reader(&effect_file);
|
||||
|
||||
@@ -29,7 +37,7 @@ NodeShader::NodeShader(Clip* c, const EffectMeta *em) :
|
||||
}
|
||||
|
||||
if (id.isEmpty() || name.isEmpty() || type == olive::nodes::kInvalid) {
|
||||
qCritical() << "Couldn't load field from" << em->filename << "- ID, type, and name cannot be empty.";
|
||||
qCritical() << "Couldn't load field from" << filename_ << "- ID, type, and name cannot be empty.";
|
||||
} else {
|
||||
EffectRow* field = nullptr;
|
||||
|
||||
@@ -158,29 +166,56 @@ NodeShader::NodeShader(Clip* c, const EffectMeta *em) :
|
||||
shader_function_name_ = attr.value().toString();
|
||||
}
|
||||
}
|
||||
}/* else if (reader.name() == "superimpose" && reader.isStartElement()) {
|
||||
enable_superimpose = true;
|
||||
const QXmlStreamAttributes& attributes = reader.attributes();
|
||||
for (int i=0;i<attributes.size();i++) {
|
||||
const QXmlStreamAttribute& attr = attributes.at(i);
|
||||
if (attr.name() == "script") {
|
||||
QFile script_file(get_effects_dir() + "/" + attr.value().toString());
|
||||
if (script_file.open(QFile::ReadOnly)) {
|
||||
script = script_file.readAll();
|
||||
} else {
|
||||
qCritical() << "Failed to open superimpose script file for" << em->filename;
|
||||
enable_superimpose = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
} else if (reader.name() == "description" && reader.isStartElement()) {
|
||||
reader.readNext();
|
||||
description_ = reader.text().toString();
|
||||
}
|
||||
reader.readNext();
|
||||
}
|
||||
|
||||
effect_file.close();
|
||||
} else {
|
||||
qCritical() << "Failed to open effect file" << em->filename;
|
||||
qCritical() << "Failed to open effect file" << filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString NodeShader::name()
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
QString NodeShader::id()
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
QString NodeShader::category()
|
||||
{
|
||||
return category_;
|
||||
}
|
||||
|
||||
QString NodeShader::description()
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
|
||||
EffectType NodeShader::type()
|
||||
{
|
||||
return EFFECT_TYPE_EFFECT;
|
||||
}
|
||||
|
||||
olive::TrackType NodeShader::subtype()
|
||||
{
|
||||
return olive::kTypeVideo;
|
||||
}
|
||||
|
||||
bool NodeShader::IsCreatable()
|
||||
{
|
||||
return !filename_.isEmpty();
|
||||
}
|
||||
|
||||
NodePtr NodeShader::Create(Clip *)
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
#ifndef NODESHADER_H
|
||||
#define NODESHADER_H
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
|
||||
class NodeShader : public Effect {
|
||||
class NodeShader : public Node {
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeShader(Clip *c, const EffectMeta *em);
|
||||
NodeShader(Clip *c,
|
||||
const QString& name,
|
||||
const QString& id,
|
||||
const QString& category,
|
||||
const QString& filename);
|
||||
|
||||
virtual QString name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString category() override;
|
||||
virtual QString description() override;
|
||||
virtual EffectType type() override;
|
||||
virtual olive::TrackType subtype() override;
|
||||
virtual bool IsCreatable() override;
|
||||
virtual NodePtr Create(Clip *c) override;
|
||||
|
||||
private:
|
||||
QString name_;
|
||||
QString id_;
|
||||
QString category_;
|
||||
QString description_;
|
||||
QString filename_;
|
||||
};
|
||||
|
||||
#endif // NODESHADER_H
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "buttonwidget.h"
|
||||
|
||||
ButtonWidget::ButtonWidget(Effect* parent, const QString& name, const QString& text) :
|
||||
ButtonWidget::ButtonWidget(Node* parent, const QString& name, const QString& text) :
|
||||
EffectRow(parent, nullptr, name, false, false)
|
||||
{
|
||||
ButtonField* button_field = new ButtonField(this, text);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
class ButtonWidget : public EffectRow
|
||||
{
|
||||
public:
|
||||
ButtonWidget(Effect* parent, const QString& name, const QString& text);
|
||||
ButtonWidget(Node* parent, const QString& name, const QString& text);
|
||||
|
||||
/**
|
||||
* @brief Wrapper for ButtonField::SetCheckable.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "labelwidget.h"
|
||||
|
||||
LabelWidget::LabelWidget(Effect *parent, const QString &name, const QString &text) :
|
||||
LabelWidget::LabelWidget(Node *parent, const QString &name, const QString &text) :
|
||||
EffectRow(parent, nullptr, name, false, false)
|
||||
{
|
||||
AddField(new LabelField(this, text));
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
class LabelWidget : public EffectRow
|
||||
{
|
||||
public:
|
||||
LabelWidget(Effect* parent, const QString& name, const QString& text);
|
||||
LabelWidget(Node* parent, const QString& name, const QString& text);
|
||||
};
|
||||
|
||||
#endif // LABELWIDGET_H
|
||||
|
||||
@@ -106,7 +106,6 @@ SOURCES += \
|
||||
effects/internal/logarithmicfadetransition.cpp \
|
||||
effects/internal/cornerpineffect.cpp \
|
||||
global/math.cpp \
|
||||
effects/effect.cpp \
|
||||
effects/effectrow.cpp \
|
||||
effects/effectgizmo.cpp \
|
||||
ui/resizablescrollbar.cpp \
|
||||
@@ -207,7 +206,8 @@ SOURCES += \
|
||||
nodes/nodes/nodemedia.cpp \
|
||||
nodes/nodes/nodeshader.cpp \
|
||||
decoders/ffmpegdecoder.cpp \
|
||||
decoders/decoder.cpp
|
||||
decoders/decoder.cpp \
|
||||
nodes/node.cpp
|
||||
|
||||
HEADERS += \
|
||||
ui/mainwindow.h \
|
||||
@@ -265,7 +265,6 @@ HEADERS += \
|
||||
effects/internal/logarithmicfadetransition.h \
|
||||
effects/internal/cornerpineffect.h \
|
||||
global/math.h \
|
||||
effects/effect.h \
|
||||
effects/effectrow.h \
|
||||
effects/internal/cubetransition.h \
|
||||
effects/effectgizmo.h \
|
||||
@@ -371,7 +370,9 @@ HEADERS += \
|
||||
nodes/nodes/nodeshader.h \
|
||||
nodes/nodes.h \
|
||||
decoders/ffmpegdecoder.h \
|
||||
decoders/decoder.h
|
||||
decoders/decoder.h \
|
||||
nodes/node.h \
|
||||
timeline/tracktypes.h
|
||||
|
||||
FORMS +=
|
||||
|
||||
|
||||
+25
-24
@@ -32,7 +32,7 @@
|
||||
#include <QApplication>
|
||||
|
||||
#include "panels/panels.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "effects/effectloaders.h"
|
||||
#include "effects/transition.h"
|
||||
#include "timeline/clip.h"
|
||||
@@ -95,24 +95,24 @@ void EffectControls::menu_select(QAction* q) {
|
||||
for (int i=0;i<selected_clips_.size();i++) {
|
||||
Clip* c = selected_clips_.at(i);
|
||||
if (c->type() == effect_menu_subtype) {
|
||||
const EffectMeta* meta = reinterpret_cast<const EffectMeta*>(q->data().value<quintptr>());
|
||||
NodeType node_type = static_cast<NodeType>(q->data().toInt());
|
||||
if (effect_menu_type == EFFECT_TYPE_TRANSITION) {
|
||||
if (c->opening_transition == nullptr) {
|
||||
ca->append(new AddTransitionCommand(c,
|
||||
nullptr,
|
||||
nullptr,
|
||||
meta,
|
||||
node_type,
|
||||
olive::config.default_transition_length));
|
||||
}
|
||||
if (c->closing_transition == nullptr) {
|
||||
ca->append(new AddTransitionCommand(nullptr,
|
||||
c,
|
||||
nullptr,
|
||||
meta,
|
||||
node_type,
|
||||
olive::config.default_transition_length));
|
||||
}
|
||||
} else {
|
||||
ca->append(new AddEffectCommand(c, nullptr, meta));
|
||||
ca->append(new AddEffectCommand(c, nullptr, node_type));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,7 +138,7 @@ void EffectControls::scroll_to_frame(long frame) {
|
||||
scroll_to_frame_internal(horizontalScrollBar, frame - keyframeView->visible_in, zoom, keyframeView->width());
|
||||
}
|
||||
|
||||
void EffectControls::show_effect_menu(int type, Track::Type subtype) {
|
||||
void EffectControls::show_effect_menu(EffectType type, olive::TrackType subtype) {
|
||||
effect_menu_type = type;
|
||||
effect_menu_subtype = subtype;
|
||||
|
||||
@@ -147,24 +147,25 @@ void EffectControls::show_effect_menu(int type, Track::Type subtype) {
|
||||
Menu effects_menu(this);
|
||||
effects_menu.setToolTipsVisible(true);
|
||||
|
||||
for (int i=0;i<olive::effects.size();i++) {
|
||||
const EffectMeta& em = olive::effects.at(i);
|
||||
for (int i=0;i<olive::node_library.size();i++) {
|
||||
|
||||
if (em.type == type && em.subtype == subtype) {
|
||||
NodePtr node = olive::node_library.at(i);
|
||||
|
||||
if (node != nullptr && node->type() == type && node->subtype() == subtype) {
|
||||
QAction* action = new QAction(&effects_menu);
|
||||
action->setText(em.name);
|
||||
action->setData(reinterpret_cast<quintptr>(&em));
|
||||
if (!em.tooltip.isEmpty()) {
|
||||
action->setToolTip(em.tooltip);
|
||||
action->setText(node->name());
|
||||
action->setData(i);
|
||||
if (!node->description().isEmpty()) {
|
||||
action->setToolTip(node->description());
|
||||
}
|
||||
|
||||
QMenu* parent = &effects_menu;
|
||||
if (!em.category.isEmpty()) {
|
||||
if (!node->category().isEmpty()) {
|
||||
bool found = false;
|
||||
for (int j=0;j<effects_menu.actions().size();j++) {
|
||||
QAction* action = effects_menu.actions().at(j);
|
||||
if (action->menu() != nullptr) {
|
||||
if (action->menu()->title() == em.category) {
|
||||
if (action->menu()->title() == node->category()) {
|
||||
parent = action->menu();
|
||||
found = true;
|
||||
break;
|
||||
@@ -174,12 +175,12 @@ void EffectControls::show_effect_menu(int type, Track::Type subtype) {
|
||||
if (!found) {
|
||||
parent = new Menu(&effects_menu);
|
||||
parent->setToolTipsVisible(true);
|
||||
parent->setTitle(em.category);
|
||||
parent->setTitle(node->category());
|
||||
|
||||
bool found = false;
|
||||
for (int i=0;i<effects_menu.actions().size();i++) {
|
||||
QAction* comp_action = effects_menu.actions().at(i);
|
||||
if (comp_action->text() > em.category) {
|
||||
if (comp_action->text() > node->category()) {
|
||||
effects_menu.insertMenu(comp_action, parent);
|
||||
found = true;
|
||||
break;
|
||||
@@ -444,19 +445,19 @@ bool EffectControls::focused()
|
||||
}
|
||||
|
||||
void EffectControls::video_effect_click() {
|
||||
show_effect_menu(EFFECT_TYPE_EFFECT, Track::kTypeVideo);
|
||||
show_effect_menu(EFFECT_TYPE_EFFECT, olive::kTypeVideo);
|
||||
}
|
||||
|
||||
void EffectControls::audio_effect_click() {
|
||||
show_effect_menu(EFFECT_TYPE_EFFECT, Track::kTypeAudio);
|
||||
show_effect_menu(EFFECT_TYPE_EFFECT, olive::kTypeAudio);
|
||||
}
|
||||
|
||||
void EffectControls::video_transition_click() {
|
||||
show_effect_menu(EFFECT_TYPE_TRANSITION, Track::kTypeVideo);
|
||||
show_effect_menu(EFFECT_TYPE_TRANSITION, olive::kTypeVideo);
|
||||
}
|
||||
|
||||
void EffectControls::audio_transition_click() {
|
||||
show_effect_menu(EFFECT_TYPE_TRANSITION, Track::kTypeAudio);
|
||||
show_effect_menu(EFFECT_TYPE_TRANSITION, olive::kTypeAudio);
|
||||
}
|
||||
|
||||
void EffectControls::resizeEvent(QResizeEvent*) {
|
||||
@@ -491,12 +492,12 @@ void EffectControls::LoadEvent()
|
||||
QVBoxLayout* layout = nullptr;
|
||||
|
||||
EffectUI* container = open_effects_.at(i);
|
||||
Effect* e = open_effects_.at(i)->GetEffect();
|
||||
Node* e = open_effects_.at(i)->GetEffect();
|
||||
|
||||
if (e->meta->subtype == Track::kTypeVideo) {
|
||||
if (e->subtype() == olive::kTypeVideo) {
|
||||
vcontainer->setVisible(true);
|
||||
layout = video_effect_layout;
|
||||
} else if (e->meta->subtype == Track::kTypeAudio) {
|
||||
} else if (e->subtype() == olive::kTypeAudio) {
|
||||
acontainer->setVisible(true);
|
||||
layout = audio_effect_layout;
|
||||
}
|
||||
|
||||
@@ -94,14 +94,14 @@ protected:
|
||||
virtual void ClearEvent() override;
|
||||
virtual void LoadEvent() override;
|
||||
private:
|
||||
void show_effect_menu(int type, Track::Type subtype);
|
||||
void show_effect_menu(EffectType type, olive::TrackType subtype);
|
||||
void load_keyframes();
|
||||
void UpdateTitle();
|
||||
|
||||
void setup_ui();
|
||||
|
||||
int effect_menu_type;
|
||||
Track::Type effect_menu_subtype;
|
||||
olive::TrackType effect_menu_subtype;
|
||||
QString panel_name;
|
||||
|
||||
QWidget* video_effect_area;
|
||||
|
||||
@@ -76,7 +76,7 @@ void EffectsPanel::Load() {
|
||||
Clip* c = selected_clips_.at(i);
|
||||
|
||||
// Create a list of the effects we'll open
|
||||
QVector<Effect*> effects_to_open;
|
||||
QVector<Node*> effects_to_open;
|
||||
|
||||
// Determine based on the current selections whether to load all effects or just the transitions
|
||||
bool whole_clip_is_selected = c->IsSelected();
|
||||
@@ -100,7 +100,7 @@ void EffectsPanel::Load() {
|
||||
// Check if we've already opened an effect of this type before
|
||||
bool already_opened = false;
|
||||
for (int k=0;k<open_effects_.size();k++) {
|
||||
if (open_effects_.at(k)->GetEffect()->meta == effects_to_open.at(j)->meta
|
||||
if (open_effects_.at(k)->GetEffect()->id() == effects_to_open.at(j)->id()
|
||||
&& !open_effects_.at(k)->IsAttachedToClip(c)) {
|
||||
|
||||
open_effects_.at(k)->AddAdditionalEffect(effects_to_open.at(j));
|
||||
@@ -137,7 +137,7 @@ void EffectsPanel::Load() {
|
||||
LoadEvent();
|
||||
}
|
||||
|
||||
bool EffectsPanel::IsEffectSelected(Effect *e)
|
||||
bool EffectsPanel::IsEffectSelected(Node *e)
|
||||
{
|
||||
for (int i=0;i<open_effects_.size();i++) {
|
||||
if (open_effects_.at(i)->GetEffect() == e && open_effects_.at(i)->IsSelected()) {
|
||||
@@ -174,9 +174,9 @@ void EffectsPanel::copy(bool del) {
|
||||
|
||||
for (int i=0;i<open_effects_.size();i++) {
|
||||
if (open_effects_.at(i)->IsSelected()) {
|
||||
Effect* e = open_effects_.at(i)->GetEffect();
|
||||
Node* e = open_effects_.at(i)->GetEffect();
|
||||
|
||||
if (e->meta->type == EFFECT_TYPE_EFFECT) {
|
||||
if (e->type() == EFFECT_TYPE_EFFECT) {
|
||||
|
||||
if (!cleared) {
|
||||
olive::clipboard.Clear();
|
||||
@@ -205,12 +205,12 @@ void EffectsPanel::copy(bool del) {
|
||||
}
|
||||
}
|
||||
|
||||
void EffectsPanel::DeleteEffect(ComboAction* ca, Effect* effect_ref) {
|
||||
if (effect_ref->meta->type == EFFECT_TYPE_EFFECT) {
|
||||
void EffectsPanel::DeleteEffect(ComboAction* ca, Node* effect_ref) {
|
||||
if (effect_ref->type() == EFFECT_TYPE_EFFECT) {
|
||||
|
||||
ca->append(new EffectDeleteCommand(effect_ref));
|
||||
|
||||
} else if (effect_ref->meta->type == EFFECT_TYPE_TRANSITION) {
|
||||
} else if (effect_ref->type() == EFFECT_TYPE_TRANSITION) {
|
||||
|
||||
// Retrieve shared ptr for this transition
|
||||
|
||||
@@ -258,7 +258,7 @@ void EffectsPanel::DeleteSelectedEffects() {
|
||||
}
|
||||
}
|
||||
|
||||
void EffectsPanel::open_effect(Effect* e) {
|
||||
void EffectsPanel::open_effect(Node* e) {
|
||||
EffectUI* container = new EffectUI(e);
|
||||
|
||||
connect(container, SIGNAL(CutRequested()), this, SLOT(cut()));
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
|
||||
virtual bool focused() override;
|
||||
|
||||
bool IsEffectSelected(Effect* e);
|
||||
bool IsEffectSelected(Node* e);
|
||||
void DeleteSelectedEffects();
|
||||
|
||||
public slots:
|
||||
@@ -32,8 +32,8 @@ protected:
|
||||
QVector<EffectUI*> open_effects_;
|
||||
private:
|
||||
void Load();
|
||||
void open_effect(Effect *e);
|
||||
void DeleteEffect(ComboAction* ca, Effect* effect_ref);
|
||||
void open_effect(Node *e);
|
||||
void DeleteEffect(ComboAction* ca, Node* effect_ref);
|
||||
private slots:
|
||||
void deselect_all_effects(QWidget*);
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "timeline/timelinetools.h"
|
||||
#include "ui/labelslider.h"
|
||||
#include "ui/graphview.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "effects/effectfields.h"
|
||||
#include "effects/effectrow.h"
|
||||
#include "timeline/clip.h"
|
||||
@@ -210,7 +210,7 @@ void GraphEditor::set_row(EffectRow *r) {
|
||||
if (found_vals) {
|
||||
row = r;
|
||||
current_row_desc->setText(row->GetParentEffect()->parent_clip->name()
|
||||
+ " :: " + row->GetParentEffect()->meta->name
|
||||
+ " :: " + row->GetParentEffect()->name()
|
||||
+ " :: " + row->name());
|
||||
header->set_visible_in(r->GetParentEffect()->parent_clip->timeline_in());
|
||||
|
||||
|
||||
+20
-20
@@ -221,10 +221,10 @@ void Timeline::SetSequence(SequencePtr sequence)
|
||||
return;
|
||||
}
|
||||
|
||||
sequence_ = sequence;
|
||||
sequence_ = sequence;
|
||||
update_sequence();
|
||||
video_area->SetTrackList(sequence_.get(), Track::kTypeVideo);
|
||||
audio_area->SetTrackList(sequence_.get(), Track::kTypeAudio);
|
||||
video_area->SetTrackList(sequence_.get(), olive::kTypeVideo);
|
||||
audio_area->SetTrackList(sequence_.get(), olive::kTypeAudio);
|
||||
repaint_timeline();
|
||||
|
||||
emit SequenceChanged(sequence_);
|
||||
@@ -276,14 +276,14 @@ void Timeline::add_transition() {
|
||||
for (int i=0;i<selected_clips.size();i++) {
|
||||
Clip* c = selected_clips.at(i);
|
||||
|
||||
int transition_to_add = (c->type() == Track::kTypeVideo) ? TRANSITION_INTERNAL_CROSSDISSOLVE
|
||||
: TRANSITION_INTERNAL_LINEARFADE;
|
||||
NodeType transition_to_add = (c->type() == olive::kTypeVideo) ? kCrossDissolveTransition
|
||||
: kLinearFadeTransition;
|
||||
|
||||
if (c->opening_transition == nullptr) {
|
||||
ca->append(new AddTransitionCommand(c,
|
||||
nullptr,
|
||||
nullptr,
|
||||
Effect::GetInternalMeta(transition_to_add, EFFECT_TYPE_TRANSITION),
|
||||
transition_to_add,
|
||||
olive::config.default_transition_length));
|
||||
adding = true;
|
||||
}
|
||||
@@ -292,7 +292,7 @@ void Timeline::add_transition() {
|
||||
ca->append(new AddTransitionCommand(nullptr,
|
||||
c,
|
||||
nullptr,
|
||||
Effect::GetInternalMeta(transition_to_add, EFFECT_TYPE_TRANSITION),
|
||||
transition_to_add,
|
||||
olive::config.default_transition_length));
|
||||
adding = true;
|
||||
}
|
||||
@@ -873,23 +873,23 @@ void Timeline::transition_tool_click() {
|
||||
|
||||
Menu transition_menu(this);
|
||||
|
||||
for (int i=0;i<olive::effects.size();i++) {
|
||||
const EffectMeta& em = olive::effects.at(i);
|
||||
if (em.type == EFFECT_TYPE_TRANSITION && em.subtype == Track::kTypeVideo) {
|
||||
QAction* a = transition_menu.addAction(em.name);
|
||||
for (int i=0;i<olive::node_library.size();i++) {
|
||||
NodePtr node = olive::node_library.at(i);
|
||||
if (node->type() == EFFECT_TYPE_TRANSITION && node->subtype() == olive::kTypeVideo) {
|
||||
QAction* a = transition_menu.addAction(node->name());
|
||||
a->setObjectName("v");
|
||||
a->setData(reinterpret_cast<quintptr>(&em));
|
||||
a->setData(i);
|
||||
}
|
||||
}
|
||||
|
||||
transition_menu.addSeparator();
|
||||
|
||||
for (int i=0;i<olive::effects.size();i++) {
|
||||
const EffectMeta& em = olive::effects.at(i);
|
||||
if (em.type == EFFECT_TYPE_TRANSITION && em.subtype == Track::kTypeAudio) {
|
||||
QAction* a = transition_menu.addAction(em.name);
|
||||
for (int i=0;i<olive::node_library.size();i++) {
|
||||
NodePtr node = olive::node_library.at(i);
|
||||
if (node->type() == EFFECT_TYPE_TRANSITION && node->subtype() == olive::kTypeVideo) {
|
||||
QAction* a = transition_menu.addAction(node->name());
|
||||
a->setObjectName("a");
|
||||
a->setData(reinterpret_cast<quintptr>(&em));
|
||||
a->setData(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,12 +901,12 @@ void Timeline::transition_tool_click() {
|
||||
}
|
||||
|
||||
void Timeline::transition_menu_select(QAction* a) {
|
||||
transition_tool_meta = reinterpret_cast<const EffectMeta*>(a->data().value<quintptr>());
|
||||
transition_tool_meta = static_cast<NodeType>(a->data().toInt());
|
||||
|
||||
if (a->objectName() == "v") {
|
||||
transition_tool_side = Track::kTypeVideo;
|
||||
transition_tool_side = olive::kTypeVideo;
|
||||
} else {
|
||||
transition_tool_side = Track::kTypeAudio;
|
||||
transition_tool_side = olive::kTypeAudio;
|
||||
}
|
||||
|
||||
timeline_area->setCursor(Qt::CrossCursor);
|
||||
|
||||
+2
-2
@@ -114,8 +114,8 @@ public:
|
||||
bool transition_tool_proc;
|
||||
Clip* transition_tool_open_clip;
|
||||
Clip* transition_tool_close_clip;
|
||||
const EffectMeta* transition_tool_meta;
|
||||
Track::Type transition_tool_side;
|
||||
NodeType transition_tool_meta;
|
||||
olive::TrackType transition_tool_side;
|
||||
|
||||
// hand tool variables
|
||||
bool hand_moving;
|
||||
|
||||
+3
-3
@@ -752,7 +752,7 @@ void Viewer::set_media(Media* m) {
|
||||
new_sequence->frame_rate = video_stream.video_frame_rate * footage->speed;
|
||||
}
|
||||
|
||||
ClipPtr c = std::make_shared<Clip>(new_sequence->GetTrackList(Track::kTypeVideo)->First());
|
||||
ClipPtr c = std::make_shared<Clip>(new_sequence->GetTrackList(olive::kTypeVideo)->First());
|
||||
c->set_media(media, video_stream.file_index);
|
||||
c->set_timeline_in(0);
|
||||
c->set_timeline_out(footage->get_length_in_frames(new_sequence->frame_rate));
|
||||
@@ -760,7 +760,7 @@ void Viewer::set_media(Media* m) {
|
||||
// FIXME: Move this magic number to Config
|
||||
c->set_timeline_out(150);
|
||||
}
|
||||
Track* track = new_sequence->GetTrackList(Track::kTypeVideo)->First();
|
||||
Track* track = new_sequence->GetTrackList(olive::kTypeVideo)->First();
|
||||
c->set_track(track);
|
||||
c->set_clip_in(0);
|
||||
c->refresh();
|
||||
@@ -774,7 +774,7 @@ void Viewer::set_media(Media* m) {
|
||||
const FootageStream& audio_stream = footage->audio_tracks.at(0);
|
||||
new_sequence->audio_frequency = audio_stream.audio_frequency;
|
||||
|
||||
Track* track = new_sequence->GetTrackList(Track::kTypeAudio)->First();
|
||||
Track* track = new_sequence->GetTrackList(olive::kTypeAudio)->First();
|
||||
ClipPtr c = std::make_shared<Clip>(track);
|
||||
c->set_media(media, audio_stream.file_index);
|
||||
c->set_timeline_in(0);
|
||||
|
||||
+25
-18
@@ -60,7 +60,7 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
|
||||
QString tag = stream.name().toString();
|
||||
|
||||
// variables to store effect metadata in
|
||||
int effect_id = -1;
|
||||
QString effect_id;
|
||||
QString effect_name;
|
||||
bool effect_enabled = true;
|
||||
long effect_length = -1;
|
||||
@@ -68,10 +68,10 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
|
||||
// loop through attributes for effect metadata
|
||||
for (int j=0;j<stream.attributes().size();j++) {
|
||||
const QXmlStreamAttribute& attr = stream.attributes().at(j);
|
||||
if (attr.name() == "id") {
|
||||
effect_id = attr.value().toInt();
|
||||
} else if (attr.name() == "enabled") {
|
||||
if (attr.name() == "enabled") {
|
||||
effect_enabled = (attr.value() == "1");
|
||||
} else if (attr.name() == "id") {
|
||||
effect_id = attr.value().toString();
|
||||
} else if (attr.name() == "name") {
|
||||
effect_name = attr.value().toString();
|
||||
} else if (attr.name() == "length") {
|
||||
@@ -116,30 +116,35 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
|
||||
// for all the effects to finish loading
|
||||
olive::effects_loaded.lock();
|
||||
|
||||
const EffectMeta* meta = nullptr;
|
||||
NodeType type = kInvalidNode;
|
||||
|
||||
// find effect with this name
|
||||
if (!effect_name.isEmpty()) {
|
||||
meta = Effect::GetMetaFromName(effect_name);
|
||||
if (!effect_id.isEmpty()) {
|
||||
for (int i=0;i<olive::node_library.size();i++) {
|
||||
if (i != kInvalidNode && olive::node_library.at(i)->id() == effect_id) {
|
||||
type = static_cast<NodeType>(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
olive::effects_loaded.unlock();
|
||||
|
||||
int type;
|
||||
TransitionType ttype;
|
||||
if (tag == "opening") {
|
||||
type = kTransitionOpening;
|
||||
ttype = kTransitionOpening;
|
||||
} else if (tag == "closing") {
|
||||
type = kTransitionClosing;
|
||||
ttype = kTransitionClosing;
|
||||
} else {
|
||||
type = kTransitionNone;
|
||||
ttype = kTransitionNone;
|
||||
}
|
||||
|
||||
// effect construction
|
||||
if (cancelled_) return;
|
||||
if (type == kTransitionNone) {
|
||||
if (meta == nullptr) {
|
||||
if (ttype == kTransitionNone) {
|
||||
if (type == kInvalidNode) {
|
||||
// create void effect
|
||||
EffectPtr ve(new VoidEffect(c, effect_name));
|
||||
NodePtr ve = std::make_shared<VoidEffect>(c, effect_name, effect_id);
|
||||
ve->SetEnabled(effect_enabled);
|
||||
ve->load(stream);
|
||||
|
||||
@@ -147,7 +152,7 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
|
||||
|
||||
c->effects.append(ve);
|
||||
} else {
|
||||
EffectPtr e(Effect::Create(c, meta));
|
||||
NodePtr e = olive::node_library[type]->Create(c);
|
||||
e->SetEnabled(effect_enabled);
|
||||
e->load(stream);
|
||||
|
||||
@@ -156,14 +161,16 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
|
||||
c->effects.append(e);
|
||||
}
|
||||
} else {
|
||||
TransitionPtr t = Transition::Create(c, nullptr, meta);
|
||||
if (effect_length > -1) t->set_length(effect_length);
|
||||
TransitionPtr t = std::static_pointer_cast<Transition>(olive::node_library[type]->Create(c));
|
||||
if (effect_length > -1) {
|
||||
t->set_length(effect_length);
|
||||
}
|
||||
t->SetEnabled(effect_enabled);
|
||||
t->load(stream);
|
||||
|
||||
t->moveToThread(QApplication::instance()->thread());
|
||||
|
||||
if (type == kTransitionOpening) {
|
||||
if (ttype == kTransitionOpening) {
|
||||
c->opening_transition = t;
|
||||
} else {
|
||||
c->closing_transition = t;
|
||||
|
||||
@@ -62,7 +62,7 @@ void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int
|
||||
timecode_end = timecode_start + samples_to_seconds(nb_samples, frame->channels, frame->sample_rate);
|
||||
|
||||
for (int j=0;j<clip->effects.size();j++) {
|
||||
Effect* e = clip->effects.at(j).get();
|
||||
Node* e = clip->effects.at(j).get();
|
||||
if (e->IsEnabled()) {
|
||||
e->process_audio(timecode_start, timecode_end, reinterpret_cast<float**>(frame->data), nb_samples, nb_channels, kTransitionNone);
|
||||
}
|
||||
@@ -805,7 +805,7 @@ void Cacher::CacheVideoWorker() {
|
||||
void Cacher::Reset() {
|
||||
// if we seek to a whole other place in the timeline, we'll need to reset the cache with new values
|
||||
if (clip->media() == nullptr) {
|
||||
if (clip->type() == Track::kTypeAudio) {
|
||||
if (clip->type() == olive::kTypeAudio) {
|
||||
// a null-media audio clip is usually an auto-generated sound clip such as Tone or Noise
|
||||
reached_end = false;
|
||||
audio_target_frame = playhead_;
|
||||
@@ -871,7 +871,7 @@ Cacher::Cacher(Clip* c) :
|
||||
|
||||
void Cacher::OpenWorker() {
|
||||
// set some defaults for the audio cacher
|
||||
if (clip->type() == Track::kTypeAudio) {
|
||||
if (clip->type() == olive::kTypeAudio) {
|
||||
audio_reset_ = false;
|
||||
frame_sample_index_ = -1;
|
||||
audio_buffer_write = 0;
|
||||
@@ -879,7 +879,7 @@ void Cacher::OpenWorker() {
|
||||
reached_end = false;
|
||||
|
||||
if (clip->media() == nullptr) {
|
||||
if (clip->type() == Track::kTypeAudio) {
|
||||
if (clip->type() == olive::kTypeAudio) {
|
||||
frame_ = av_frame_alloc();
|
||||
frame_->format = kDestSampleFmt;
|
||||
frame_->channel_layout = clip->track()->sequence()->audio_layout;
|
||||
@@ -1127,7 +1127,7 @@ void Cacher::OpenWorker() {
|
||||
}
|
||||
|
||||
void Cacher::CacheWorker() {
|
||||
if (clip->type() == Track::kTypeVideo) {
|
||||
if (clip->type() == olive::kTypeVideo) {
|
||||
// clip is a video track, start caching video
|
||||
CacheVideoWorker();
|
||||
} else {
|
||||
@@ -1218,7 +1218,7 @@ void Cacher::Open()
|
||||
caching_ = true;
|
||||
queued_ = false;
|
||||
|
||||
start((clip->type() == Track::kTypeVideo) ? QThread::HighPriority : QThread::TimeCriticalPriority);
|
||||
start((clip->type() == olive::kTypeVideo) ? QThread::HighPriority : QThread::TimeCriticalPriority);
|
||||
}
|
||||
|
||||
void Cacher::Cache(long playhead, bool scrubbing, QVector<Clip*>& nests, int playback_speed)
|
||||
|
||||
@@ -34,7 +34,7 @@ extern "C" {
|
||||
#include "timeline/clip.h"
|
||||
#include "timeline/sequence.h"
|
||||
#include "project/media.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "project/footage.h"
|
||||
#include "effects/transition.h"
|
||||
#include "ui/collapsiblewidget.h"
|
||||
@@ -110,7 +110,6 @@ void olive::rendering::Blit(QOpenGLShaderProgram* pipeline, bool flipped, QMatri
|
||||
pipeline->setUniformValue("mvp_matrix", matrix);
|
||||
pipeline->setUniformValue("texture", 0);
|
||||
|
||||
|
||||
GLuint vertex_location = pipeline->attributeLocation("a_position");
|
||||
m_vbo.bind();
|
||||
func->glEnableVertexAttribArray(vertex_location);
|
||||
@@ -176,7 +175,7 @@ GLuint draw_clip(QOpenGLContext* ctx,
|
||||
void process_effect(QOpenGLContext* ctx,
|
||||
QOpenGLShaderProgram* pipeline,
|
||||
Clip* c,
|
||||
Effect* e,
|
||||
Node* e,
|
||||
double timecode,
|
||||
GLTextureCoords& coords,
|
||||
GLuint& composite_texture,
|
||||
@@ -184,11 +183,11 @@ void process_effect(QOpenGLContext* ctx,
|
||||
bool& texture_failed,
|
||||
int data) {
|
||||
if (e->IsEnabled()) {
|
||||
if (e->Flags() & Effect::CoordsFlag) {
|
||||
if (e->Flags() & Node::CoordsFlag) {
|
||||
e->process_coords(timecode, coords, data);
|
||||
}
|
||||
bool can_process_shaders = ((e->Flags() & Effect::ShaderFlag) && olive::runtime_config.shaders_are_enabled);
|
||||
if (can_process_shaders || (e->Flags() & Effect::SuperimposeFlag)) {
|
||||
bool can_process_shaders = ((e->Flags() & Node::ShaderFlag) && olive::runtime_config.shaders_are_enabled);
|
||||
if (can_process_shaders || (e->Flags() & Node::SuperimposeFlag)) {
|
||||
|
||||
if (!e->is_open()) {
|
||||
e->open();
|
||||
@@ -201,7 +200,7 @@ void process_effect(QOpenGLContext* ctx,
|
||||
fbo_switcher = !fbo_switcher;
|
||||
}
|
||||
}
|
||||
if (e->Flags() & Effect::SuperimposeFlag) {
|
||||
if (e->Flags() & Node::SuperimposeFlag) {
|
||||
GLuint superimpose_texture = e->process_superimpose(ctx, timecode);
|
||||
|
||||
if (superimpose_texture == 0) {
|
||||
@@ -227,7 +226,7 @@ void process_effect(QOpenGLContext* ctx,
|
||||
}
|
||||
|
||||
GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
GLuint final_fbo = params.type == Track::kTypeVideo ? params.main_buffer->buffer() : 0;
|
||||
GLuint final_fbo = params.type == olive::kTypeVideo ? params.main_buffer->buffer() : 0;
|
||||
|
||||
Sequence* s = params.seq;
|
||||
long playhead = s->playhead;
|
||||
@@ -240,7 +239,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
playhead = rescale_frame_number(playhead, params.nests.at(i)->track()->sequence()->frame_rate, s->frame_rate);
|
||||
}
|
||||
|
||||
if (params.type == Track::kTypeVideo && !params.nests.last()->fbo.isEmpty()) {
|
||||
if (params.type == olive::kTypeVideo && !params.nests.last()->fbo.isEmpty()) {
|
||||
params.nests.last()->fbo.at(0).BindBuffer();
|
||||
params.ctx->functions()->glClear(GL_COLOR_BUFFER_BIT);
|
||||
final_fbo = params.nests.last()->fbo.at(0).buffer();
|
||||
@@ -270,7 +269,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
Footage* m = c->media()->to_footage();
|
||||
|
||||
// does the clip have a valid media source?
|
||||
if (!m->invalid && !(c->type() == Track::kTypeAudio && !is_audio_device_set())) {
|
||||
if (!m->invalid && !(c->type() == olive::kTypeAudio && !is_audio_device_set())) {
|
||||
|
||||
// is the media process and ready?
|
||||
if (m->ready) {
|
||||
@@ -287,7 +286,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
clip_is_active = true;
|
||||
|
||||
// increment audio track count
|
||||
if (c->type() == Track::kTypeAudio) audio_track_count++;
|
||||
if (c->type() == olive::kTypeAudio) audio_track_count++;
|
||||
|
||||
} else if (c->IsOpen()) {
|
||||
|
||||
@@ -321,7 +320,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
|
||||
// track sorting is only necessary for video clips
|
||||
// audio clips are mixed equally, so we skip sorting for those
|
||||
if (params.type == Track::kTypeVideo) {
|
||||
if (params.type == olive::kTypeVideo) {
|
||||
|
||||
// insertion sort by track
|
||||
for (int j=0;j<current_clips.size();j++) {
|
||||
@@ -344,7 +343,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
|
||||
QMatrix4x4 projection;
|
||||
|
||||
if (params.type == Track::kTypeVideo) {
|
||||
if (params.type == olive::kTypeVideo) {
|
||||
// set default coordinates based on the sequence, with 0 in the direct center
|
||||
|
||||
params.ctx->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@@ -370,7 +369,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
|
||||
if (got_mutex && c->IsOpen()) {
|
||||
// if clip is a video clip
|
||||
if (c->type() == Track::kTypeVideo) {
|
||||
if (c->type() == olive::kTypeVideo) {
|
||||
|
||||
// textureID variable contains texture to be drawn on screen at the end
|
||||
GLuint textureID = 0;
|
||||
@@ -504,7 +503,6 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
coords.texture_top_right = QVector2D(1.0f, 0.0f);
|
||||
coords.texture_bottom_left = QVector2D(0.0f, 1.0f);
|
||||
coords.texture_bottom_right = QVector2D(1.0f, 1.0f);
|
||||
coords.blendmode = -1;
|
||||
coords.opacity = 1.0;
|
||||
|
||||
// == EFFECT CODE START ==
|
||||
@@ -515,7 +513,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
// run through all of the clip's effects
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
|
||||
Effect* e = c->effects.at(j).get();
|
||||
Node* e = c->effects.at(j).get();
|
||||
process_effect(params.ctx, params.pipeline, c, e, timecode, coords, textureID, fbo_switcher, params.texture_failed, kTransitionNone);
|
||||
|
||||
}
|
||||
@@ -685,9 +683,11 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
|
||||
|
||||
// copy front buffer to back buffer (only if we're using a blending mode)
|
||||
/*
|
||||
if (coords.blendmode >= 0) {
|
||||
draw_clip(params.ctx, params.pipeline, back_buffer_2, comp_texture, true);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -700,7 +700,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, final_fbo);
|
||||
|
||||
// Check if we're using a blend mode (< 0 means no blend mode)
|
||||
if (coords.blendmode < 0) {
|
||||
//if (coords.blendmode < 0) {
|
||||
|
||||
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_1);
|
||||
|
||||
@@ -708,7 +708,9 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
|
||||
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
} else {
|
||||
//} else {
|
||||
|
||||
/*
|
||||
|
||||
// load background texture into texture unit 0
|
||||
params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
|
||||
@@ -739,7 +741,9 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
|
||||
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
//}
|
||||
|
||||
// unbind framebuffer
|
||||
params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
@@ -750,7 +754,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
// == END FINAL DRAW ON SEQUENCE BUFFER ==
|
||||
}
|
||||
}
|
||||
} else if (c->type() == Track::kTypeAudio) {
|
||||
} else if (c->type() == olive::kTypeAudio) {
|
||||
if (c->media() != nullptr && c->media()->get_type() == MEDIA_TYPE_SEQUENCE) {
|
||||
params.nests.append(c);
|
||||
compose_sequence(params);
|
||||
@@ -795,11 +799,10 @@ void olive::rendering::compose_audio(Viewer* viewer, Sequence* seq, int playback
|
||||
params.viewer = viewer;
|
||||
params.ctx = nullptr;
|
||||
params.seq = seq;
|
||||
params.type = Track::kTypeAudio;
|
||||
params.type = olive::kTypeAudio;
|
||||
params.gizmos = nullptr;
|
||||
params.wait_for_mutexes = wait_for_mutexes;
|
||||
params.playback_speed = playback_speed;
|
||||
params.blend_mode_program = nullptr;
|
||||
compose_sequence(params);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
namespace OCIO = OCIO_NAMESPACE::v1;
|
||||
|
||||
#include "timeline/sequence.h"
|
||||
#include "effects/effect.h"
|
||||
#include "nodes/node.h"
|
||||
#include "panels/viewer.h"
|
||||
|
||||
/**
|
||||
@@ -80,16 +80,16 @@ struct ComposeSequenceParams {
|
||||
/**
|
||||
* @brief Set compose mode to video or audio
|
||||
*
|
||||
* Accepts Track::kTypeVideo to render video, Track::kTypeAudio if this function should render audio.
|
||||
* Accepts olive::kTypeVideo to render video, olive::kTypeAudio if this function should render audio.
|
||||
*/
|
||||
Track::Type type;
|
||||
olive::TrackType type;
|
||||
|
||||
/**
|
||||
* @brief Set to the Effect whose gizmos were chosen to be drawn on screen
|
||||
*
|
||||
* The currently active Effect that compose_sequence() will update the gizmos of.
|
||||
*/
|
||||
Effect* gizmos;
|
||||
Node* gizmos;
|
||||
|
||||
/**
|
||||
* @brief A variable that compose_sequence() will set to **TRUE** if any of the clips couldn't be shown.
|
||||
@@ -138,19 +138,6 @@ struct ComposeSequenceParams {
|
||||
*/
|
||||
int playback_speed;
|
||||
|
||||
/**
|
||||
* @brief Blending mode shader
|
||||
*
|
||||
* Used only for video rendering. Never accessed with audio rendering.
|
||||
*
|
||||
* A program containing the current active
|
||||
* blending mode shader that can be bound during rendering. Must be compiled and linked beforehand. See
|
||||
* RenderThread::blend_mode_program for how this is properly set up.
|
||||
*
|
||||
* \see ComposeSequenceParams::video
|
||||
*/
|
||||
QOpenGLShaderProgram* blend_mode_program;
|
||||
|
||||
/**
|
||||
* @brief Premultiply alpha shader
|
||||
*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user