From a4369c4d79741c600782593101c6fe4fb47af7bd Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Sat, 31 Aug 2019 14:45:09 +1000 Subject: [PATCH] filled out alpha over and opacity nodes --- app/core.cpp | 3 + app/node/CMakeLists.txt | 1 + app/node/blend/alphaover/alphaover.cpp | 74 ++++++++++++++++++- app/node/blend/alphaover/alphaover.h | 26 +++++++ app/node/blend/blend.cpp | 20 ++++++ app/node/blend/blend.h | 20 ++++++ app/node/color/CMakeLists.txt | 22 ++++++ app/node/color/opacity/CMakeLists.txt | 22 ++++++ app/node/color/opacity/opacity.cpp | 98 ++++++++++++++++++++++++++ app/node/color/opacity/opacity.h | 50 +++++++++++++ app/node/input/media/media.cpp | 4 +- app/render/renderinstance.cpp | 14 ++++ app/render/renderinstance.h | 5 ++ 13 files changed, 355 insertions(+), 4 deletions(-) create mode 100644 app/node/color/CMakeLists.txt create mode 100644 app/node/color/opacity/CMakeLists.txt create mode 100644 app/node/color/opacity/opacity.cpp create mode 100644 app/node/color/opacity/opacity.h diff --git a/app/core.cpp b/app/core.cpp index 757bbc99e..ca0314a43 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -220,6 +220,7 @@ void Core::CreateNewFolder() // FIXME: Test code #include "node/blend/alphaover/alphaover.h" +#include "node/color/opacity/opacity.h" #include "node/output/timeline/timeline.h" #include "node/output/track/track.h" #include "node/output/viewer/viewer.h" @@ -309,6 +310,8 @@ void Core::CreateNewSequence() // FIXME: Test code AlphaOverBlend* blend = new AlphaOverBlend(); new_sequence->AddNode(blend); + OpacityNode* opac = new OpacityNode(); + new_sequence->AddNode(opac); // End test code vo->AttachViewer(olive::panel_focus_manager->MostRecentlyFocused()); diff --git a/app/node/CMakeLists.txt b/app/node/CMakeLists.txt index 8d3af812e..8e42cd998 100644 --- a/app/node/CMakeLists.txt +++ b/app/node/CMakeLists.txt @@ -16,6 +16,7 @@ add_subdirectory(blend) add_subdirectory(block) +add_subdirectory(color) add_subdirectory(generator) add_subdirectory(input) add_subdirectory(output) diff --git a/app/node/blend/alphaover/alphaover.cpp b/app/node/blend/alphaover/alphaover.cpp index 008c425aa..240666734 100644 --- a/app/node/blend/alphaover/alphaover.cpp +++ b/app/node/blend/alphaover/alphaover.cpp @@ -1,8 +1,32 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 "alphaover.h" +#include "node/processor/renderer/renderer.h" +#include "render/gl/functions.h" #include "render/rendertexture.h" +#include "render/gl/shadergenerators.h" -AlphaOverBlend::AlphaOverBlend() +AlphaOverBlend::AlphaOverBlend() : + shader_(nullptr) { } @@ -22,10 +46,54 @@ QString AlphaOverBlend::Description() return tr("A blending node that composites one texture over another using its alpha channel."); } +void AlphaOverBlend::Release() +{ + shader_ = nullptr; +} + QVariant AlphaOverBlend::Value(NodeOutput *param, const rational &time) { - Q_UNUSED(param) - Q_UNUSED(time) + // Find the current Renderer instance + RenderInstance* renderer = RendererProcessor::CurrentInstance(); + + // If nothing is available, don't return a texture + if (renderer == nullptr) { + return 0; + } + + // The only parameter should be texture output, but for future proofing we put this here + if (param == texture_output()) { + RenderTexturePtr base = base_input()->get_value(time).value(); + RenderTexturePtr blend = blend_input()->get_value(time).value(); + + // Set compositing strategy to alpha over + renderer->context()->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + // Attach framebuffer to the backbuffer of base + renderer->buffer()->Attach(base); + renderer->buffer()->Bind(); + + // Bind blend + blend->Bind(); + + // Get default pipeline shader + // FIXME: Come up with a good way to share pipeline shaders since a lot of nodes will just use the default + if (shader_ == nullptr) { + shader_ = olive::ShaderGenerator::DefaultPipeline(); + } + + // Draw blend on base + olive::gl::Blit(shader_); + + // Release all + blend->Release(); + renderer->buffer()->Detach(); + renderer->buffer()->Release(); + + // Return base texture which now has blend composited on top + // NOTE: Blend texture will be implicitly deleted here (if it's not used anywhere else) + return QVariant::fromValue(base); + } return 0; } diff --git a/app/node/blend/alphaover/alphaover.h b/app/node/blend/alphaover/alphaover.h index 29896570f..38a3faf7d 100644 --- a/app/node/blend/alphaover/alphaover.h +++ b/app/node/blend/alphaover/alphaover.h @@ -1,7 +1,28 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 ALPHAOVER_H #define ALPHAOVER_H #include "node/blend/blend.h" +#include "render/gl/shaderptr.h" class AlphaOverBlend : public BlendNode { @@ -12,8 +33,13 @@ public: virtual QString id() override; virtual QString Description() override; + virtual void Release() override; + protected: virtual QVariant Value(NodeOutput* param, const rational& time) override; + +private: + ShaderPtr shader_; }; #endif // ALPHAOVER_H diff --git a/app/node/blend/blend.cpp b/app/node/blend/blend.cpp index a48a58d35..c04b8eaeb 100644 --- a/app/node/blend/blend.cpp +++ b/app/node/blend/blend.cpp @@ -1,3 +1,23 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 "blend.h" BlendNode::BlendNode() diff --git a/app/node/blend/blend.h b/app/node/blend/blend.h index 209ea1f5d..9f4e1ba96 100644 --- a/app/node/blend/blend.h +++ b/app/node/blend/blend.h @@ -1,3 +1,23 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 BLEND_H #define BLEND_H diff --git a/app/node/color/CMakeLists.txt b/app/node/color/CMakeLists.txt new file mode 100644 index 000000000..eb35cc108 --- /dev/null +++ b/app/node/color/CMakeLists.txt @@ -0,0 +1,22 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2019 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 . + +add_subdirectory(opacity) + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + PARENT_SCOPE +) diff --git a/app/node/color/opacity/CMakeLists.txt b/app/node/color/opacity/CMakeLists.txt new file mode 100644 index 000000000..13c645217 --- /dev/null +++ b/app/node/color/opacity/CMakeLists.txt @@ -0,0 +1,22 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2019 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/opacity/opacity.h + node/color/opacity/opacity.cpp + PARENT_SCOPE +) diff --git a/app/node/color/opacity/opacity.cpp b/app/node/color/opacity/opacity.cpp new file mode 100644 index 000000000..a9bc19f0d --- /dev/null +++ b/app/node/color/opacity/opacity.cpp @@ -0,0 +1,98 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 "opacity.h" + +#include "node/processor/renderer/renderer.h" +#include "render/gl/functions.h" +#include "render/rendertexture.h" + +OpacityNode::OpacityNode() +{ + opacity_input_ = new NodeInput("opacity_in"); + opacity_input_->add_data_input(NodeParam::kFloat); + AddParameter(opacity_input_); + + texture_input_ = new NodeInput("tex_in"); + texture_input_->add_data_input(NodeParam::kTexture); + AddParameter(texture_input_); + + texture_output_ = new NodeOutput("tex_out"); + texture_output_->set_data_type(NodeParam::kTexture); + AddParameter(texture_output_); +} + +QString OpacityNode::Name() +{ + return tr("Opacity"); +} + +QString OpacityNode::Category() +{ + return tr("Color"); +} + +QString OpacityNode::Description() +{ + return tr("Adjust an image's opacity."); +} + +QString OpacityNode::id() +{ + return "org.olivevideoeditor.Olive.opacity"; +} + +QVariant OpacityNode::Value(NodeOutput *output, const rational &time) +{ + // Find the current Renderer instance + RenderInstance* renderer = RendererProcessor::CurrentInstance(); + + // If nothing is available, don't return a texture + if (renderer == nullptr) { + return 0; + } + + if (output == texture_output_) { + RenderTexturePtr input_tex = texture_input_->get_value(time).value(); + + // Attach texture's back buffer as frame buffer + renderer->buffer()->AttachBackBuffer(input_tex); + renderer->buffer()->Bind(); + + // Bind texture's front buffer to draw with + input_tex->Bind(); + + // Set opacity to value + ShaderPtr pipeline = renderer->default_pipeline(); + pipeline->setUniformValue("opacity", opacity_input_->get_value(time).toFloat()*0.01f); + + // Blit + olive::gl::Blit(renderer->default_pipeline()); + + // Reset to full opacity + pipeline->setUniformValue("opacity", 1.0f); + + input_tex->Release(); + renderer->buffer()->Release(); + renderer->buffer()->Detach(); + } + + return 0; +} diff --git a/app/node/color/opacity/opacity.h b/app/node/color/opacity/opacity.h new file mode 100644 index 000000000..b90096b13 --- /dev/null +++ b/app/node/color/opacity/opacity.h @@ -0,0 +1,50 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 OPACITYNODE_H +#define OPACITYNODE_H + +#include "node/node.h" +#include "render/gl/shaderptr.h" + +class OpacityNode : public Node +{ + Q_OBJECT +public: + OpacityNode(); + + virtual QString Name() override; + virtual QString Category() override; + virtual QString Description() override; + + virtual QString id() override; + + virtual QVariant Value(NodeOutput *output, const rational &time) override; + +private: + NodeInput* opacity_input_; + + NodeInput* texture_input_; + + NodeOutput* texture_output_; + +}; + +#endif // OPACITYNODE_H diff --git a/app/node/input/media/media.cpp b/app/node/input/media/media.cpp index b549ed639..83ffb64ce 100644 --- a/app/node/input/media/media.cpp +++ b/app/node/input/media/media.cpp @@ -26,9 +26,9 @@ #include "decoder/ffmpeg/ffmpegdecoder.h" #include "node/processor/renderer/renderer.h" #include "project/item/footage/footage.h" -#include "render/pixelservice.h" #include "render/gl/shadergenerators.h" #include "render/gl/functions.h" +#include "render/pixelservice.h" MediaInput::MediaInput() : decoder_(nullptr), @@ -220,6 +220,8 @@ QVariant MediaInput::Value(NodeOutput *output, const rational &time) pipeline_ = olive::ShaderGenerator::DefaultPipeline(); } + renderer->context()->functions()->glBlendFunc(GL_ONE, GL_ZERO); + // Draw onto the output texture using the renderer's framebuffer renderer->buffer()->Attach(output_texture); renderer->buffer()->Bind(); diff --git a/app/render/renderinstance.cpp b/app/render/renderinstance.cpp index 3941e6de1..6a4674cf7 100644 --- a/app/render/renderinstance.cpp +++ b/app/render/renderinstance.cpp @@ -22,6 +22,8 @@ #include +#include "render/gl/shadergenerators.h" + RenderInstance::RenderInstance(const int& width, const int& height, const olive::PixelFormat& format, @@ -70,13 +72,20 @@ bool RenderInstance::Start() buffer_.Create(&ctx_); + // Set viewport to the compositing dimensions ctx_.functions()->glViewport(0, 0, width_, height_); + // Set up default pipeline + default_pipeline_ = olive::ShaderGenerator::DefaultPipeline(); + return true; } void RenderInstance::Stop() { + // Destroy pipeline + default_pipeline_ = nullptr; + // Destroy buffer buffer_.Destroy(); @@ -121,3 +130,8 @@ const olive::RenderMode &RenderInstance::mode() const { return mode_; } + +ShaderPtr RenderInstance::default_pipeline() const +{ + return default_pipeline_; +} diff --git a/app/render/renderinstance.h b/app/render/renderinstance.h index 0d6c47a6d..6978695af 100644 --- a/app/render/renderinstance.h +++ b/app/render/renderinstance.h @@ -25,6 +25,7 @@ #include #include +#include "render/gl/shaderptr.h" #include "render/renderframebuffer.h" #include "render/rendermodes.h" @@ -63,6 +64,8 @@ public: const olive::RenderMode& mode() const; + ShaderPtr default_pipeline() const; + private: QOpenGLContext ctx_; @@ -81,6 +84,8 @@ private: olive::RenderMode mode_; int divider_; + + ShaderPtr default_pipeline_; }; #endif // GLINSTANCE_H