From 1efd2ec8d49b5cbb0a092374082cf12a54a22777 Mon Sep 17 00:00:00 2001 From: Thomas Wilshaw Date: Sun, 8 May 2022 23:13:04 +0100 Subject: [PATCH 1/3] Implement RGB to B&W node --- app/node/color/CMakeLists.txt | 1 + app/node/color/rgbtobw/CMakeLists.txt | 22 +++++ app/node/color/rgbtobw/rgbtobw.cpp | 129 ++++++++++++++++++++++++++ app/node/color/rgbtobw/rgbtobw.h | 56 +++++++++++ app/node/factory.cpp | 3 + app/node/factory.h | 1 + app/shaders/rgbtobw.frag | 18 ++++ 7 files changed, 230 insertions(+) create mode 100644 app/node/color/rgbtobw/CMakeLists.txt create mode 100644 app/node/color/rgbtobw/rgbtobw.cpp create mode 100644 app/node/color/rgbtobw/rgbtobw.h create mode 100644 app/shaders/rgbtobw.frag diff --git a/app/node/color/CMakeLists.txt b/app/node/color/CMakeLists.txt index 046c499dab..31460ef2d7 100644 --- a/app/node/color/CMakeLists.txt +++ b/app/node/color/CMakeLists.txt @@ -18,6 +18,7 @@ add_subdirectory(colormanager) add_subdirectory(displaytransform) add_subdirectory(ociobase) add_subdirectory(ociogradingtransformlinear) +add_subdirectory(rgbtobw) set(OLIVE_SOURCES ${OLIVE_SOURCES} diff --git a/app/node/color/rgbtobw/CMakeLists.txt b/app/node/color/rgbtobw/CMakeLists.txt new file mode 100644 index 0000000000..1ecb90e72e --- /dev/null +++ b/app/node/color/rgbtobw/CMakeLists.txt @@ -0,0 +1,22 @@ +# 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 . + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + node/color/rgbtobw/rgbtobw.cpp + node/color/rgbtobw/rgbtobw.h + PARENT_SCOPE +) \ No newline at end of file diff --git a/app/node/color/rgbtobw/rgbtobw.cpp b/app/node/color/rgbtobw/rgbtobw.cpp new file mode 100644 index 0000000000..657dc69811 --- /dev/null +++ b/app/node/color/rgbtobw/rgbtobw.cpp @@ -0,0 +1,129 @@ +/*** + + 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 "rgbtobw.h" + +#include "node/project/project.h" + +namespace olive { + +const QString RGBToBWNode::kTextureInput = QStringLiteral("tex_in"); +const QString RGBToBWNode::kCustomWeightsEnableInput = QStringLiteral("custom_weights_enable_in"); +const QString RGBToBWNode::kCustomWeightsInput = QStringLiteral("custom_weights_in"); + +#define super Node + +RGBToBWNode::RGBToBWNode() +{ + AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); + + AddInput(kCustomWeightsEnableInput, NodeValue::kBoolean, false); + + AddInput(kCustomWeightsInput, NodeValue::kVec3, QVector3D{0.33f, 0.33f, 0.33f}); //TEMP + + SetInputProperty(kCustomWeightsInput, QStringLiteral("enabled"), GetStandardValue(kCustomWeightsEnableInput).toBool()); + SetInputProperty(kCustomWeightsInput, QStringLiteral("color0"), QColor(50, 50, 50).name()); // What is disabled colour? + SetInputProperty(kCustomWeightsInput, QStringLiteral("color1"), QColor(50, 50, 50).name()); + SetInputProperty(kCustomWeightsInput, QStringLiteral("color2"), QColor(50, 50, 50).name()); + + SetFlags(kVideoEffect); + SetEffectInput(kTextureInput); +} + +QString RGBToBWNode::Name() const +{ + return tr("RGB to B&&W"); +} + +QString RGBToBWNode::id() const +{ + return QStringLiteral("org.olivevideoeditor.Olive.rgbtobw"); +} + +QVector RGBToBWNode::Category() const +{ + return {kCategoryColor}; +} + +QString RGBToBWNode::Description() const +{ + return tr("Converts an color image to a black and white image"); +} + +void RGBToBWNode::Retranslate() +{ + super::Retranslate(); + + SetInputName(kTextureInput, tr("Input")); + SetInputName(kCustomWeightsEnableInput, tr("Use Custom Weights")); + SetInputName(kCustomWeightsInput, tr("Weights")); + + if (project()) { + // Set luma coefficients + //double luma_coeffs[3] = {0.0f, 0.0f, 0.0f}; + project()->color_manager()->GetDefaultLumaCoefs(luma_coeffs_); + SetStandardValue(kCustomWeightsInput, QVector3D(luma_coeffs_[0], luma_coeffs_[1], luma_coeffs_[2])); + } +} + +void RGBToBWNode::InputValueChangedEvent(const QString &input, int element) +{ + Q_UNUSED(element); + if (input == kCustomWeightsEnableInput) { + if (GetStandardValue(kCustomWeightsEnableInput).toBool()){ + SetInputProperty(kCustomWeightsInput, QStringLiteral("enabled"), true); + SetInputProperty(kCustomWeightsInput, QStringLiteral("color0"), QColor(255, 0, 0).name()); + SetInputProperty(kCustomWeightsInput, QStringLiteral("color1"), QColor(0, 255, 0).name()); + SetInputProperty(kCustomWeightsInput, QStringLiteral("color2"), QColor(0, 0, 255).name()); + } else { + SetInputProperty(kCustomWeightsInput, QStringLiteral("enabled"), false); + SetInputProperty(kCustomWeightsInput, QStringLiteral("color0"), QColor(50, 50, 50).name()); + SetInputProperty(kCustomWeightsInput, QStringLiteral("color1"), QColor(50, 50, 50).name()); + SetInputProperty(kCustomWeightsInput, QStringLiteral("color2"), QColor(50, 50, 50).name()); + } + } + } +ShaderCode RGBToBWNode::GetShaderCode(const ShaderRequest &request) const +{ + Q_UNUSED(request) + return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/rgbtobw.frag")); +} + +void RGBToBWNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const { + ShaderJob job; + + job.InsertValue(value); + + // Set luma coefficients + double luma_coeffs[3] = {0.0f, 0.0f, 0.0f}; // Can this use the cached values? + project()->color_manager()->GetDefaultLumaCoefs(luma_coeffs); + job.InsertValue(QStringLiteral("luma_coeffs"), + NodeValue(NodeValue::kVec3, QVector3D(luma_coeffs[0], luma_coeffs[1], luma_coeffs[2]))); + + + // If there's no texture, no need to run an operation + if (!job.GetValue(kTextureInput).data().isNull()) { + table->Push(NodeValue::kTexture, QVariant::fromValue(job), this); + + } +} + +} + diff --git a/app/node/color/rgbtobw/rgbtobw.h b/app/node/color/rgbtobw/rgbtobw.h new file mode 100644 index 0000000000..b1a624bfe0 --- /dev/null +++ b/app/node/color/rgbtobw/rgbtobw.h @@ -0,0 +1,56 @@ +/*** + + 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 RGBTOBWNODE_H +#define RGBTOBWNODE_H + +#include "node/node.h" + +namespace olive { + +class RGBToBWNode : public Node +{ + Q_OBJECT + public: + RGBToBWNode(); + + NODE_DEFAULT_FUNCTIONS(RGBToBWNode) + + virtual QString Name() const override; + virtual QString id() const override; + virtual QVector Category() const override; + virtual QString Description() const override; + + virtual void Retranslate() override; + virtual void InputValueChangedEvent(const QString &input, int element) override; + + virtual ShaderCode GetShaderCode(const ShaderRequest &request) const override; + virtual void Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const override; + + static const QString kTextureInput; + static const QString kCustomWeightsEnableInput; + static const QString kCustomWeightsInput; + + double luma_coeffs_[3]; +}; + +} // namespace olive + +#endif // RGBTOBWNODE_H diff --git a/app/node/factory.cpp b/app/node/factory.cpp index 4292d50373..8be895278d 100644 --- a/app/node/factory.cpp +++ b/app/node/factory.cpp @@ -31,6 +31,7 @@ #include "block/transition/diptocolor/diptocolortransition.h" #include "color/displaytransform/displaytransform.h" #include "color/ociogradingtransformlinear/ociogradingtransformlinear.h" +#include "color/rgbtobw/rgbtobw.h" #include "distort/cornerpin/cornerpindistortnode.h" #include "distort/crop/cropdistortnode.h" #include "distort/flip/flipdistortnode.h" @@ -290,6 +291,8 @@ Node *NodeFactory::CreateFromFactoryIndex(const NodeFactory::InternalID &id) return new OCIOGradingTransformLinearNode(); case kChromaKey: return new ChromaKeyNode(); + case kRGBToBW: + return new RGBToBWNode(); case kInternalNodeCount: break; diff --git a/app/node/factory.h b/app/node/factory.h index 54e417b3e6..6a8a4ec43f 100644 --- a/app/node/factory.h +++ b/app/node/factory.h @@ -73,6 +73,7 @@ class NodeFactory kDisplayTransform, kOCIOGradingTransformLinear, kChromaKey, + kRGBToBW, // Count value kInternalNodeCount diff --git a/app/shaders/rgbtobw.frag b/app/shaders/rgbtobw.frag new file mode 100644 index 0000000000..af60377773 --- /dev/null +++ b/app/shaders/rgbtobw.frag @@ -0,0 +1,18 @@ +// Input texture +uniform sampler2D tex_in; +uniform vec3 custom_weights_in; +uniform bool custom_weights_enable_in; +uniform vec3 luma_coeffs; + +// Input texture coordinate +in vec2 ove_texcoord; +out vec4 frag_color; + +void main() { + vec4 color = texture(tex_in, ove_texcoord); + if (!custom_weights_enable_in){ + frag_color = vec4(vec3(dot(color.rgb, luma_coeffs)), color.w); + } else { + frag_color = vec4(vec3(dot(color.rgb, custom_weights_in)), color.w); + } +} From e0fcf313200e2008c6d257af98b4c0f58513acb4 Mon Sep 17 00:00:00 2001 From: Thomas Wilshaw Date: Tue, 11 Oct 2022 14:46:26 +0100 Subject: [PATCH 2/3] rbgtobwnode: update to new node system --- app/node/color/rgbtobw/rgbtobw.cpp | 62 +++++++++++++++--------------- app/node/color/rgbtobw/rgbtobw.h | 4 ++ 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/app/node/color/rgbtobw/rgbtobw.cpp b/app/node/color/rgbtobw/rgbtobw.cpp index 657dc69811..b19f6c8e9b 100644 --- a/app/node/color/rgbtobw/rgbtobw.cpp +++ b/app/node/color/rgbtobw/rgbtobw.cpp @@ -30,18 +30,20 @@ const QString RGBToBWNode::kCustomWeightsInput = QStringLiteral("custom_weights_ #define super Node -RGBToBWNode::RGBToBWNode() +RGBToBWNode::RGBToBWNode() : + weights_edited_(false) { AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); AddInput(kCustomWeightsEnableInput, NodeValue::kBoolean, false); AddInput(kCustomWeightsInput, NodeValue::kVec3, QVector3D{0.33f, 0.33f, 0.33f}); //TEMP - - SetInputProperty(kCustomWeightsInput, QStringLiteral("enabled"), GetStandardValue(kCustomWeightsEnableInput).toBool()); - SetInputProperty(kCustomWeightsInput, QStringLiteral("color0"), QColor(50, 50, 50).name()); // What is disabled colour? - SetInputProperty(kCustomWeightsInput, QStringLiteral("color1"), QColor(50, 50, 50).name()); - SetInputProperty(kCustomWeightsInput, QStringLiteral("color2"), QColor(50, 50, 50).name()); + + SetInputProperty(kCustomWeightsInput, QStringLiteral("color0"), QColor(255, 0, 0).name()); + SetInputProperty(kCustomWeightsInput, QStringLiteral("color1"), QColor(0, 255, 0).name()); + SetInputProperty(kCustomWeightsInput, QStringLiteral("color2"), QColor(0, 0, 255).name()); + + UpdateInputs(false); SetFlags(kVideoEffect); SetEffectInput(kTextureInput); @@ -75,29 +77,24 @@ void RGBToBWNode::Retranslate() SetInputName(kCustomWeightsEnableInput, tr("Use Custom Weights")); SetInputName(kCustomWeightsInput, tr("Weights")); - if (project()) { - // Set luma coefficients - //double luma_coeffs[3] = {0.0f, 0.0f, 0.0f}; - project()->color_manager()->GetDefaultLumaCoefs(luma_coeffs_); - SetStandardValue(kCustomWeightsInput, QVector3D(luma_coeffs_[0], luma_coeffs_[1], luma_coeffs_[2])); + // Only set custom weights to their default value if they haven't been edited yet + if (!weights_edited_) { + if (project()) { + project()->color_manager()->GetDefaultLumaCoefs(luma_coeffs_); + SetStandardValue(kCustomWeightsInput, QVector3D(luma_coeffs_[0], luma_coeffs_[1], luma_coeffs_[2])); + } } } void RGBToBWNode::InputValueChangedEvent(const QString &input, int element) { Q_UNUSED(element); + if (input == kCustomWeightsEnableInput) { - if (GetStandardValue(kCustomWeightsEnableInput).toBool()){ - SetInputProperty(kCustomWeightsInput, QStringLiteral("enabled"), true); - SetInputProperty(kCustomWeightsInput, QStringLiteral("color0"), QColor(255, 0, 0).name()); - SetInputProperty(kCustomWeightsInput, QStringLiteral("color1"), QColor(0, 255, 0).name()); - SetInputProperty(kCustomWeightsInput, QStringLiteral("color2"), QColor(0, 0, 255).name()); - } else { - SetInputProperty(kCustomWeightsInput, QStringLiteral("enabled"), false); - SetInputProperty(kCustomWeightsInput, QStringLiteral("color0"), QColor(50, 50, 50).name()); - SetInputProperty(kCustomWeightsInput, QStringLiteral("color1"), QColor(50, 50, 50).name()); - SetInputProperty(kCustomWeightsInput, QStringLiteral("color2"), QColor(50, 50, 50).name()); - } + UpdateInputs(GetStandardValue(kCustomWeightsEnableInput).toBool()); + } + if (input == kCustomWeightsInput) { + weights_edited_ = true; } } ShaderCode RGBToBWNode::GetShaderCode(const ShaderRequest &request) const @@ -106,24 +103,29 @@ ShaderCode RGBToBWNode::GetShaderCode(const ShaderRequest &request) const return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/rgbtobw.frag")); } -void RGBToBWNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const { - ShaderJob job; +void RGBToBWNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const +{ + ShaderJob job(value); - job.InsertValue(value); // Set luma coefficients double luma_coeffs[3] = {0.0f, 0.0f, 0.0f}; // Can this use the cached values? project()->color_manager()->GetDefaultLumaCoefs(luma_coeffs); - job.InsertValue(QStringLiteral("luma_coeffs"), + job.Insert(QStringLiteral("luma_coeffs"), NodeValue(NodeValue::kVec3, QVector3D(luma_coeffs[0], luma_coeffs[1], luma_coeffs[2]))); - // If there's no texture, no need to run an operation - if (!job.GetValue(kTextureInput).data().isNull()) { - table->Push(NodeValue::kTexture, QVariant::fromValue(job), this); - + if (TexturePtr tex = value[kTextureInput].toTexture()) { + table->Push(NodeValue::kTexture, tex->toJob(job), this); + } else { + table->Push(value[kTextureInput]); } } +void RGBToBWNode::UpdateInputs(bool custom_coefficients) +{ + SetInputFlags(kCustomWeightsInput, custom_coefficients ? InputFlags() : InputFlags(kInputFlagHidden)); +} + } diff --git a/app/node/color/rgbtobw/rgbtobw.h b/app/node/color/rgbtobw/rgbtobw.h index b1a624bfe0..6e9f61e9d7 100644 --- a/app/node/color/rgbtobw/rgbtobw.h +++ b/app/node/color/rgbtobw/rgbtobw.h @@ -49,6 +49,10 @@ class RGBToBWNode : public Node static const QString kCustomWeightsInput; double luma_coeffs_[3]; + bool weights_edited_; + + private: + void UpdateInputs(bool cutsom_coefficients); }; } // namespace olive From 91289c7fb4bdf77fbb0e49edae748e80af65829a Mon Sep 17 00:00:00 2001 From: Thomas Wilshaw Date: Tue, 11 Oct 2022 14:50:56 +0100 Subject: [PATCH 3/3] rgbtobwnode: Fix typos --- app/node/color/rgbtobw/CMakeLists.txt | 2 +- app/node/color/rgbtobw/rgbtobw.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/node/color/rgbtobw/CMakeLists.txt b/app/node/color/rgbtobw/CMakeLists.txt index 1ecb90e72e..8b8a573fee 100644 --- a/app/node/color/rgbtobw/CMakeLists.txt +++ b/app/node/color/rgbtobw/CMakeLists.txt @@ -19,4 +19,4 @@ set(OLIVE_SOURCES node/color/rgbtobw/rgbtobw.cpp node/color/rgbtobw/rgbtobw.h PARENT_SCOPE -) \ No newline at end of file +) diff --git a/app/node/color/rgbtobw/rgbtobw.cpp b/app/node/color/rgbtobw/rgbtobw.cpp index b19f6c8e9b..1d47aa7c1d 100644 --- a/app/node/color/rgbtobw/rgbtobw.cpp +++ b/app/node/color/rgbtobw/rgbtobw.cpp @@ -51,7 +51,7 @@ RGBToBWNode::RGBToBWNode() : QString RGBToBWNode::Name() const { - return tr("RGB to B&&W"); + return tr("RGB to B&W"); } QString RGBToBWNode::id() const @@ -66,7 +66,7 @@ QVector RGBToBWNode::Category() const QString RGBToBWNode::Description() const { - return tr("Converts an color image to a black and white image"); + return tr("Converts a color image to black and white"); } void RGBToBWNode::Retranslate()