diff --git a/app/node/generator/noise/noise.cpp b/app/node/generator/noise/noise.cpp index 64ea2266a..213910ad4 100644 --- a/app/node/generator/noise/noise.cpp +++ b/app/node/generator/noise/noise.cpp @@ -20,8 +20,11 @@ #include "noise.h" +#include "widget/slider/floatslider.h" + namespace olive { +const QString NoiseGeneratorNode::kBaseIn = QStringLiteral("base_in"); const QString NoiseGeneratorNode::kColorInput = QStringLiteral("color_in"); const QString NoiseGeneratorNode::kStrengthInput = QStringLiteral("strength_in"); @@ -29,9 +32,16 @@ const QString NoiseGeneratorNode::kStrengthInput = QStringLiteral("strength_in") NoiseGeneratorNode::NoiseGeneratorNode() { - AddInput(kStrengthInput, NodeValue::kFloat, 20); + AddInput(kBaseIn, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); + + AddInput(kStrengthInput, NodeValue::kFloat, 0.2); + SetInputProperty(kStrengthInput, QStringLiteral("view"), FloatSlider::kPercentage); + SetInputProperty(kStrengthInput, QStringLiteral("min"), 0); AddInput(kColorInput, NodeValue::kBoolean, false); + + SetEffectInput(kBaseIn); + SetFlags(kVideoEffect); } Node* NoiseGeneratorNode::copy() const @@ -63,12 +73,13 @@ void NoiseGeneratorNode::Retranslate() { super::Retranslate(); + SetInputName(kBaseIn, tr("Base")); SetInputName(kStrengthInput, tr("Strength")); SetInputName(kColorInput, tr("Color")); } -ShaderCode NoiseGeneratorNode::GetShaderCode(const QString& shader_id) const { - Q_UNUSED(shader_id) +ShaderCode NoiseGeneratorNode::GetShaderCode(const QString& shader_id) const +{ return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/noise.frag")); } @@ -79,8 +90,6 @@ void NoiseGeneratorNode::Value(const NodeValueRow &value, const NodeGlobals &glo job.InsertValue(value); job.InsertValue(QStringLiteral("time_in"), NodeValue(NodeValue::kFloat, globals.time().in().toDouble(), this)); - table->Push(NodeValue::kTexture, QVariant::fromValue(job), this); - } } diff --git a/app/node/generator/noise/noise.h b/app/node/generator/noise/noise.h index 31dfd2f3b..36cbd7fe8 100644 --- a/app/node/generator/noise/noise.h +++ b/app/node/generator/noise/noise.h @@ -44,8 +44,10 @@ class NoiseGeneratorNode : public Node { virtual ShaderCode GetShaderCode(const QString &shader_id) const override; virtual void Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const override; + static const QString kBaseIn; static const QString kColorInput; static const QString kStrengthInput; + }; } // namespace olive diff --git a/app/node/generator/polygon/polygon.cpp b/app/node/generator/polygon/polygon.cpp index cfccc83c2..40283689b 100644 --- a/app/node/generator/polygon/polygon.cpp +++ b/app/node/generator/polygon/polygon.cpp @@ -30,7 +30,7 @@ namespace olive { const QString PolygonGenerator::kPointsInput = QStringLiteral("points_in"); const QString PolygonGenerator::kColorInput = QStringLiteral("color_in"); -#define super Node +#define super GeneratorWithMerge PolygonGenerator::PolygonGenerator() { @@ -102,7 +102,7 @@ void PolygonGenerator::Value(const NodeValueRow &value, const NodeGlobals &globa job.SetRequestedFormat(VideoParams::kFormatFloat32); job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn); - table->Push(NodeValue::kTexture, QVariant::fromValue(job), this); + PushMergableJob(value, QVariant::fromValue(job), table); } void PolygonGenerator::GenerateFrame(FramePtr frame, const GenerateJob &job) const diff --git a/app/node/generator/polygon/polygon.h b/app/node/generator/polygon/polygon.h index e1c66573a..2f2e4e467 100644 --- a/app/node/generator/polygon/polygon.h +++ b/app/node/generator/polygon/polygon.h @@ -24,6 +24,7 @@ #include #include "common/bezier.h" +#include "node/generator/shape/generatorwithmerge.h" #include "node/gizmo/line.h" #include "node/gizmo/path.h" #include "node/gizmo/point.h" @@ -32,7 +33,7 @@ namespace olive { -class PolygonGenerator : public Node +class PolygonGenerator : public GeneratorWithMerge { Q_OBJECT public: diff --git a/app/node/generator/shape/CMakeLists.txt b/app/node/generator/shape/CMakeLists.txt index b3d0fed04..275b80e75 100644 --- a/app/node/generator/shape/CMakeLists.txt +++ b/app/node/generator/shape/CMakeLists.txt @@ -16,6 +16,8 @@ set(OLIVE_SOURCES ${OLIVE_SOURCES} + node/generator/shape/generatorwithmerge.cpp + node/generator/shape/generatorwithmerge.h node/generator/shape/shapenode.cpp node/generator/shape/shapenode.h node/generator/shape/shapenodebase.cpp diff --git a/app/node/generator/shape/generatorwithmerge.cpp b/app/node/generator/shape/generatorwithmerge.cpp new file mode 100644 index 000000000..363ba4d12 --- /dev/null +++ b/app/node/generator/shape/generatorwithmerge.cpp @@ -0,0 +1,71 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2021 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#include "generatorwithmerge.h" + +#include "node/math/merge/merge.h" + +namespace olive { + +#define super Node + +const QString GeneratorWithMerge::kBaseInput = QStringLiteral("base_in"); + +GeneratorWithMerge::GeneratorWithMerge() +{ + AddInput(kBaseInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); + SetEffectInput(kBaseInput); + SetFlags(kVideoEffect); +} + +void GeneratorWithMerge::Retranslate() +{ + super::Retranslate(); + + SetInputName(kBaseInput, tr("Base")); +} + +ShaderCode GeneratorWithMerge::GetShaderCode(const QString &shader_id) const +{ + if (shader_id == QStringLiteral("mrg")) { + return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/alphaover.frag")); + } + + return ShaderCode(); +} + +void GeneratorWithMerge::PushMergableJob(const NodeValueRow &value, const QVariant &job, NodeValueTable *table) const +{ + 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, job, this)); + + table->Push(NodeValue::kTexture, QVariant::fromValue(merge), this); + } else { + // Just push generate job + table->Push(NodeValue::kTexture, job, this); + } +} + +} diff --git a/app/node/generator/shape/generatorwithmerge.h b/app/node/generator/shape/generatorwithmerge.h new file mode 100644 index 000000000..9345f2d64 --- /dev/null +++ b/app/node/generator/shape/generatorwithmerge.h @@ -0,0 +1,49 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2021 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#ifndef GENERATORWITHMERGE_H +#define GENERATORWITHMERGE_H + +#include "node/node.h" + +namespace olive { + +class GeneratorWithMerge : public Node +{ + Q_OBJECT +public: + GeneratorWithMerge(); + + NODE_DEFAULT_DESTRUCTOR(GeneratorWithMerge) + + virtual void Retranslate() override; + + virtual ShaderCode GetShaderCode(const QString &shader_id) const override; + + static const QString kBaseInput; + +protected: + void PushMergableJob(const NodeValueRow &value, const QVariant &job, NodeValueTable *table) const; + +}; + +} + +#endif // GENERATORWITHMERGE_H diff --git a/app/node/generator/shape/shapenode.cpp b/app/node/generator/shape/shapenode.cpp index a0aeb7b03..34db8dfcb 100644 --- a/app/node/generator/shape/shapenode.cpp +++ b/app/node/generator/shape/shapenode.cpp @@ -79,20 +79,7 @@ void ShapeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, Nod job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn); job.SetShaderID(QStringLiteral("shape")); - 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); - } + PushMergableJob(value, QVariant::fromValue(job), table); } } diff --git a/app/node/generator/shape/shapenodebase.cpp b/app/node/generator/shape/shapenodebase.cpp index 9a5e2ed6d..4eb411079 100644 --- a/app/node/generator/shape/shapenodebase.cpp +++ b/app/node/generator/shape/shapenodebase.cpp @@ -28,16 +28,14 @@ namespace olive { -#define super Node +#define super GeneratorWithMerge -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)); @@ -60,16 +58,12 @@ ShapeNodeBase::ShapeNodeBase(bool create_color_input) for (int i=0; i(pos_n_sz, PointGizmo::kAbsolute); } - - SetEffectInput(kBaseInput); - SetFlags(kVideoEffect); } void ShapeNodeBase::Retranslate() { super::Retranslate(); - SetInputName(kBaseInput, tr("Base")); SetInputName(kPositionInput, tr("Position")); SetInputName(kSizeInput, tr("Size")); @@ -108,15 +102,6 @@ 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 4079ad3c3..451c32dea 100644 --- a/app/node/generator/shape/shapenodebase.h +++ b/app/node/generator/shape/shapenodebase.h @@ -21,15 +21,15 @@ #ifndef SHAPENODEBASE_H #define SHAPENODEBASE_H +#include "generatorwithmerge.h" #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 { -class ShapeNodeBase : public Node +class ShapeNodeBase : public GeneratorWithMerge { Q_OBJECT public: @@ -41,9 +41,6 @@ public: virtual void UpdateGizmoPositions(const NodeValueRow &row, const NodeGlobals &globals) override; - 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; diff --git a/app/node/generator/text/textv3.cpp b/app/node/generator/text/textv3.cpp index e56c445e3..4413d6f65 100644 --- a/app/node/generator/text/textv3.cpp +++ b/app/node/generator/text/textv3.cpp @@ -89,20 +89,7 @@ void TextGeneratorV3::Value(const NodeValueRow &value, const NodeGlobals &global job.SetColorspace(project()->color_manager()->GetDefaultInputColorSpace()); if (!job.GetValue(kTextInput).data().toString().isEmpty()) { - 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); - } + PushMergableJob(value, QVariant::fromValue(job), table); } else if (!value[kBaseInput].data().isNull()) { table->Push(value[kBaseInput]); } diff --git a/app/node/traverser.cpp b/app/node/traverser.cpp index cf04d8e72..7eb8087cf 100644 --- a/app/node/traverser.cpp +++ b/app/node/traverser.cpp @@ -306,6 +306,7 @@ void NodeTraverser::ResolveJobs(NodeValue &val, const TimeRange &range) TexturePtr tex = CreateTexture(tex_params); + PreProcessRow(range, job.GetValues()); ProcessShader(tex, val.source(), range, job); val.set_data(QVariant::fromValue(tex)); @@ -322,6 +323,7 @@ void NodeTraverser::ResolveJobs(NodeValue &val, const TimeRange &range) TexturePtr tex = CreateTexture(tex_params); + PreProcessRow(range, job.GetValues()); ProcessFrameGeneration(tex, val.source(), job); val.set_data(QVariant::fromValue(tex)); diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp index 8b7dbb0e7..dce266726 100644 --- a/app/render/renderprocessor.cpp +++ b/app/render/renderprocessor.cpp @@ -511,10 +511,6 @@ void RenderProcessor::ProcessShader(TexturePtr destination, const Node *node, co } } - VideoParams tex_params = GetCacheVideoParams(); - - tex_params.set_channel_count(GetChannelCountFromJob(job)); - // Run shader render_ctx_->BlitToTexture(shader, job, destination.get()); } diff --git a/app/shaders/noise.frag b/app/shaders/noise.frag index 4a2296e91..7439eea76 100644 --- a/app/shaders/noise.frag +++ b/app/shaders/noise.frag @@ -2,7 +2,9 @@ uniform float time_in; uniform float strength_in; uniform bool color_in; -//uniform bool blend; + +uniform sampler2D base_in; +uniform bool base_in_enabled; in vec2 ove_texcoord; out vec4 frag_color; @@ -22,7 +24,7 @@ bool isNan( float val ) } float gold_noise(vec2 coordinate, float seed){ - float value = fract(tan(distance(coordinate*(seed+PHI), vec2(PHI, PI)))*SQ2)*(strength_in*0.01); + float value = fract(tan(distance(coordinate*(seed+PHI), vec2(PHI, PI)))*SQ2)*(strength_in); return isNan(value) ? 0.0 : value; } @@ -34,5 +36,11 @@ void main(void) { noise = vec3(gold_noise(ove_texcoord, time_in + 69420.0)); } + if (base_in_enabled) { + vec4 base = texture(base_in, ove_texcoord); + base.rgb += noise; + frag_color = base; + } else { frag_color = vec4(noise, 1.0); + } }