diff --git a/app/node/generator/shape/shapenode.cpp b/app/node/generator/shape/shapenode.cpp index 3da5f51a3..a0aeb7b03 100644 --- a/app/node/generator/shape/shapenode.cpp +++ b/app/node/generator/shape/shapenode.cpp @@ -63,9 +63,11 @@ void ShapeNode::Retranslate() ShaderCode ShapeNode::GetShaderCode(const QString &shader_id) const { - Q_UNUSED(shader_id) - - return ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/shape.frag"))); + if (shader_id == QStringLiteral("shape")) { + return ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/shape.frag"))); + } else { + return super::GetShaderCode(shader_id); + } } void ShapeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const @@ -75,8 +77,22 @@ void ShapeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, Nod job.InsertValue(value); job.InsertValue(QStringLiteral("resolution_in"), NodeValue(NodeValue::kVec2, globals.resolution(), this)); job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn); + job.SetShaderID(QStringLiteral("shape")); - table->Push(NodeValue::kTexture, QVariant::fromValue(job), this); + if (!value[kBaseInput].data().isNull()) { + // Push as merge node + ShaderJob merge; + + merge.SetShaderID(QStringLiteral("mrg")); + merge.InsertValue(MergeNode::kBaseIn, value[kBaseInput]); + merge.InsertValue(MergeNode::kBlendIn, NodeValue(NodeValue::kTexture, QVariant::fromValue(job), this)); + merge.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn); + + table->Push(NodeValue::kTexture, QVariant::fromValue(merge), this); + } else { + // Just push generate job + table->Push(NodeValue::kTexture, QVariant::fromValue(job), this); + } } } diff --git a/app/node/generator/shape/shapenodebase.cpp b/app/node/generator/shape/shapenodebase.cpp index 15a262f29..aa0625957 100644 --- a/app/node/generator/shape/shapenodebase.cpp +++ b/app/node/generator/shape/shapenodebase.cpp @@ -30,12 +30,14 @@ namespace olive { #define super Node -QString ShapeNodeBase::kPositionInput = QStringLiteral("pos_in"); -QString ShapeNodeBase::kSizeInput = QStringLiteral("size_in"); -QString ShapeNodeBase::kColorInput = QStringLiteral("color_in"); +const QString ShapeNodeBase::kBaseInput = QStringLiteral("base_in"); +const QString ShapeNodeBase::kPositionInput = QStringLiteral("pos_in"); +const QString ShapeNodeBase::kSizeInput = QStringLiteral("size_in"); +const QString ShapeNodeBase::kColorInput = QStringLiteral("color_in"); ShapeNodeBase::ShapeNodeBase(bool create_color_input) { + AddInput(kBaseInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); AddInput(kPositionInput, NodeValue::kVec2, QVector2D(0, 0)); AddInput(kSizeInput, NodeValue::kVec2, QVector2D(100, 100)); SetInputProperty(kSizeInput, QStringLiteral("min"), QVector2D(0, 0)); @@ -58,6 +60,9 @@ ShapeNodeBase::ShapeNodeBase(bool create_color_input) for (int i=0; i(pos_n_sz, PointGizmo::kAbsolute); } + + SetEffectInput(kBaseInput); + SetFlags(kVideoEffect); } void ShapeNodeBase::Retranslate() @@ -102,6 +107,15 @@ void ShapeNodeBase::UpdateGizmoPositions(const NodeValueRow &row, const NodeGlob poly_gizmo_->SetPolygon(QRectF(left_pt, top_pt, right_pt - left_pt, bottom_pt - top_pt)); } +ShaderCode ShapeNodeBase::GetShaderCode(const QString &shader_id) const +{ + if (shader_id == QStringLiteral("mrg")) { + return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/alphaover.frag")); + } + + return ShaderCode(); +} + void ShapeNodeBase::GizmoDragMove(double x, double y, const Qt::KeyboardModifiers &modifiers) { DraggableGizmo *gizmo = static_cast(sender()); diff --git a/app/node/generator/shape/shapenodebase.h b/app/node/generator/shape/shapenodebase.h index d7529eff0..4079ad3c3 100644 --- a/app/node/generator/shape/shapenodebase.h +++ b/app/node/generator/shape/shapenodebase.h @@ -24,6 +24,7 @@ #include "node/gizmo/point.h" #include "node/gizmo/polygon.h" #include "node/inputdragger.h" +#include "node/math/merge/merge.h" #include "node/node.h" namespace olive { @@ -40,9 +41,12 @@ public: virtual void UpdateGizmoPositions(const NodeValueRow &row, const NodeGlobals &globals) override; - static QString kPositionInput; - static QString kSizeInput; - static QString kColorInput; + virtual ShaderCode GetShaderCode(const QString &shader_id) const override; + + static const QString kBaseInput; + static const QString kPositionInput; + static const QString kSizeInput; + static const QString kColorInput; protected: PolygonGizmo *poly_gizmo() const diff --git a/app/node/generator/text/textv3.cpp b/app/node/generator/text/textv3.cpp index fc3d5e5bf..af36e74b6 100644 --- a/app/node/generator/text/textv3.cpp +++ b/app/node/generator/text/textv3.cpp @@ -76,6 +76,7 @@ void TextGeneratorV3::Retranslate() super::Retranslate(); SetInputName(kTextInput, tr("Text")); + SetInputName(kBaseInput, tr("Base")); } void TextGeneratorV3::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const @@ -89,7 +90,22 @@ void TextGeneratorV3::Value(const NodeValueRow &value, const NodeGlobals &global job.SetColorspace(project()->color_manager()->GetDefaultInputColorSpace()); if (!job.GetValue(kTextInput).data().toString().isEmpty()) { - table->Push(NodeValue::kTexture, QVariant::fromValue(job), this); + if (!value[kBaseInput].data().isNull()) { + // Push as merge node + ShaderJob merge; + + merge.SetShaderID(QStringLiteral("mrg")); + merge.InsertValue(MergeNode::kBaseIn, value[kBaseInput]); + merge.InsertValue(MergeNode::kBlendIn, NodeValue(NodeValue::kTexture, QVariant::fromValue(job), this)); + merge.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn); + + table->Push(NodeValue::kTexture, QVariant::fromValue(merge), this); + } else { + // Just push generate job + table->Push(NodeValue::kTexture, QVariant::fromValue(job), this); + } + } else if (!value[kBaseInput].data().isNull()) { + table->Push(value[kBaseInput]); } } diff --git a/app/node/traverser.cpp b/app/node/traverser.cpp index a620c3fa8..1d80fca63 100644 --- a/app/node/traverser.cpp +++ b/app/node/traverser.cpp @@ -52,7 +52,7 @@ NodeValueRow NodeTraverser::GenerateRow(NodeValueDatabase *database, const Node row.insert(it.key(), value); } - PreProcessRow(node, range, row); + PreProcessRow(range, row); return row; } @@ -353,7 +353,7 @@ QVector2D NodeTraverser::GenerateResolution() const return QVector2D(video_params_.square_pixel_width(), video_params_.height()); } -void NodeTraverser::PreProcessRow(const Node *node, const TimeRange &range, NodeValueRow &row) +void NodeTraverser::PreProcessRow(const TimeRange &range, NodeValueRow &row) { QByteArray cached_node_hash; @@ -381,11 +381,15 @@ void NodeTraverser::PreProcessRow(const Node *node, const TimeRange &range, Node if (v.canConvert()) { - val.set_data(QVariant::fromValue(ProcessShader(val.source(), range, v.value()))); + ShaderJob job = v.value(); + PreProcessRow(range, job.GetValues()); + val.set_data(QVariant::fromValue(ProcessShader(val.source(), range, job))); } else if (v.canConvert()) { - val.set_data(QVariant::fromValue(ProcessFrameGeneration(val.source(), v.value()))); + GenerateJob job = v.value(); + PreProcessRow(range, job.GetValues()); + val.set_data(QVariant::fromValue(ProcessFrameGeneration(val.source(), job))); } else if (v.canConvert()) { @@ -406,7 +410,7 @@ void NodeTraverser::PreProcessRow(const Node *node, const TimeRange &range, Node } else if (v.canConvert()) { - val.set_data(QVariant::fromValue(ProcessSamples(node, range, v.value()))); + val.set_data(QVariant::fromValue(ProcessSamples(val.source(), range, v.value()))); } diff --git a/app/node/traverser.h b/app/node/traverser.h index 3a15455da..6919f61a9 100644 --- a/app/node/traverser.h +++ b/app/node/traverser.h @@ -109,7 +109,7 @@ protected: } private: - void PreProcessRow(const Node *node, const TimeRange &range, NodeValueRow &row); + void PreProcessRow(const TimeRange &range, NodeValueRow &row); TexturePtr CreateDummyTexture(const VideoParams &p); diff --git a/app/render/job/acceleratedjob.h b/app/render/job/acceleratedjob.h index a40e5a14a..534f4a528 100644 --- a/app/render/job/acceleratedjob.h +++ b/app/render/job/acceleratedjob.h @@ -56,10 +56,8 @@ public: #endif } - const NodeValueRow &GetValues() const - { - return value_map_; - } + const NodeValueRow &GetValues() const { return value_map_; } + NodeValueRow &GetValues() { return value_map_; } private: NodeValueRow value_map_;