From 72f3a784de9417ce7ef6a38c153a6e19b63391c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Garc=C3=ADa=20Li=C3=B1=C3=A1n?= Date: Wed, 20 Feb 2019 03:05:55 +0100 Subject: [PATCH] Compositor: Added support for static branching and tags to be able to configure the Compositor at startup. --- simgear/scene/viewer/CMakeLists.txt | 3 +- simgear/scene/viewer/Compositor.cxx | 14 +++-- simgear/scene/viewer/CompositorBuffer.cxx | 46 +++++++++----- simgear/scene/viewer/CompositorPass.cxx | 11 ++-- simgear/scene/viewer/CompositorPass.hxx | 4 -- simgear/scene/viewer/CompositorUtil.cxx | 62 +++++++++++++++++++ ...ompositorCommon.hxx => CompositorUtil.hxx} | 16 ++++- 7 files changed, 120 insertions(+), 36 deletions(-) create mode 100644 simgear/scene/viewer/CompositorUtil.cxx rename simgear/scene/viewer/{CompositorCommon.hxx => CompositorUtil.hxx} (78%) diff --git a/simgear/scene/viewer/CMakeLists.txt b/simgear/scene/viewer/CMakeLists.txt index df57469b..d26297fc 100644 --- a/simgear/scene/viewer/CMakeLists.txt +++ b/simgear/scene/viewer/CMakeLists.txt @@ -1,9 +1,9 @@ set(HEADERS ClusteredForward.hxx Compositor.hxx - CompositorCommon.hxx CompositorBuffer.hxx CompositorPass.hxx + CompositorUtil.hxx ) set(SOURCES @@ -11,6 +11,7 @@ set(SOURCES Compositor.cxx CompositorBuffer.cxx CompositorPass.cxx + CompositorUtil.cxx ) simgear_scene_component(viewer scene/viewer "${SOURCES}" "${HEADERS}") diff --git a/simgear/scene/viewer/Compositor.cxx b/simgear/scene/viewer/Compositor.cxx index 8058d0d3..dd267504 100644 --- a/simgear/scene/viewer/Compositor.cxx +++ b/simgear/scene/viewer/Compositor.cxx @@ -27,8 +27,10 @@ #include #include #include -#include #include +#include + +#include "CompositorUtil.hxx" namespace simgear { namespace compositor { @@ -45,6 +47,8 @@ Compositor::create(osg::View *view, // Read all buffers first so passes can use them PropertyList p_buffers = property_list->getChildren("buffer"); for (auto const &p_buffer : p_buffers) { + if (!checkConditional(p_buffer)) + continue; const std::string &buffer_name = p_buffer->getStringValue("name"); if (buffer_name.empty()) { SG_LOG(SG_INPUT, SG_ALERT, "Compositor::build: Buffer requires " @@ -58,6 +62,8 @@ Compositor::create(osg::View *view, // Read passes PropertyList p_passes = property_list->getChildren("pass"); for (auto const &p_pass : p_passes) { + if (!checkConditional(p_pass)) + continue; Pass *pass = buildPass(compositor.get(), p_pass); if (pass) compositor->addPass(pass); @@ -189,11 +195,7 @@ Compositor::setCameraCullMasks(osg::Node::NodeMask nm) for (const auto &pass : _passes) { osg::Camera *camera = pass->camera; osg::Node::NodeMask pass_cm = nm; - // Disable traversal of the scene graph if the pass isn't enabled - if (!pass->isEnabled()) - pass_cm &= 0x0; - else - pass_cm &= pass->cull_mask; + pass_cm &= pass->cull_mask; camera->setCullMask(pass_cm); camera->setCullMaskLeft(pass_cm); diff --git a/simgear/scene/viewer/CompositorBuffer.cxx b/simgear/scene/viewer/CompositorBuffer.cxx index 183e4de5..2acb6be9 100644 --- a/simgear/scene/viewer/CompositorBuffer.cxx +++ b/simgear/scene/viewer/CompositorBuffer.cxx @@ -30,7 +30,7 @@ #include #include "Compositor.hxx" -#include "CompositorCommon.hxx" +#include "CompositorUtil.hxx" namespace simgear { namespace compositor { @@ -103,23 +103,37 @@ buildBuffer(Compositor *compositor, const SGPropertyNode *node) osg::ref_ptr buffer = new Buffer; osg::Texture *texture; - int width; - if (node->getStringValue("width") == std::string("screen")) { - float w_scale = node->getFloatValue("screen-width-scale", 1.0f); - buffer->width_scale = w_scale; - width = w_scale * compositor->getViewport()->width(); - } else { - width = node->getIntValue("width"); + int width = 0; + const SGPropertyNode *p_width = getPropertyChild(node, "width"); + if (p_width) { + if (p_width->getStringValue() == std::string("screen")) { + buffer->width_scale = 1.0f; + const SGPropertyNode *p_w_scale = getPropertyChild(node, "screen-width-scale"); + if (p_w_scale) + buffer->width_scale = p_w_scale->getFloatValue(); + width = buffer->width_scale * compositor->getViewport()->width(); + } else { + width = p_width->getIntValue(); + } } - int height; - if (node->getStringValue("height") == std::string("screen")) { - float h_scale = node->getFloatValue("screen-height-scale", 1.0f); - buffer->height_scale = h_scale; - height = h_scale * compositor->getViewport()->height(); - } else { - height = node->getIntValue("height"); + int height = 0; + const SGPropertyNode *p_height = getPropertyChild(node, "height"); + if (p_height) { + if (p_height->getStringValue() == std::string("screen")) { + buffer->height_scale = 1.0f; + const SGPropertyNode *p_h_scale = getPropertyChild(node, "screen-height-scale"); + if (p_h_scale) + buffer->height_scale = p_h_scale->getFloatValue(); + height = buffer->height_scale * compositor->getViewport()->height(); + } else { + height = p_height->getIntValue(); + } } - int depth = node->getIntValue("depth"); + int depth = 0; + const SGPropertyNode *p_depth = getPropertyChild(node, "depth"); + if (p_depth) + depth = p_depth->getIntValue(); + if (type == "1d") { osg::Texture1D *tex1D = new osg::Texture1D; tex1D->setTextureWidth(width); diff --git a/simgear/scene/viewer/CompositorPass.cxx b/simgear/scene/viewer/CompositorPass.cxx index d62a8a90..96f6e9e0 100644 --- a/simgear/scene/viewer/CompositorPass.cxx +++ b/simgear/scene/viewer/CompositorPass.cxx @@ -24,14 +24,13 @@ #include #include -#include #include #include #include #include "ClusteredForward.hxx" #include "Compositor.hxx" -#include "CompositorCommon.hxx" +#include "CompositorUtil.hxx" namespace simgear { namespace compositor { @@ -65,10 +64,6 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root) } pass->type = root->getStringValue("type"); - const SGPropertyNode *condition = root->getChild("condition"); - if (condition) - pass->condition = sgReadCondition(getPropertyRoot(), condition); - std::string eff_override_file = root->getStringValue("effect-override"); if (!eff_override_file.empty()) pass->effect_override = makeEffect(eff_override_file, true, 0); @@ -115,6 +110,8 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root) PropertyList p_bindings = root->getChildren("binding"); for (auto const &p_binding : p_bindings) { + if (!checkConditional(p_binding)) + continue; try { std::string buffer_name = p_binding->getStringValue("buffer"); if (buffer_name.empty()) @@ -190,6 +187,8 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root) } for (auto const &p_attachment : p_attachments) { + if (!checkConditional(p_attachment)) + continue; try { std::string buffer_name = p_attachment->getStringValue("buffer"); if (buffer_name.empty()) diff --git a/simgear/scene/viewer/CompositorPass.hxx b/simgear/scene/viewer/CompositorPass.hxx index cb59a83c..fae90d29 100644 --- a/simgear/scene/viewer/CompositorPass.hxx +++ b/simgear/scene/viewer/CompositorPass.hxx @@ -24,7 +24,6 @@ #include #include -#include #include namespace simgear { @@ -51,12 +50,9 @@ struct Pass : public osg::Referenced { viewport_width_scale(0.0f), viewport_height_scale(0.0f) {} - bool isEnabled() const { return (condition == 0) || condition->test(); } - std::string name; std::string type; osg::ref_ptr camera; - SGSharedPtr condition; /** If null, there is no effect override for this pass. */ osg::ref_ptr effect_override; bool useMastersSceneData; diff --git a/simgear/scene/viewer/CompositorUtil.cxx b/simgear/scene/viewer/CompositorUtil.cxx new file mode 100644 index 00000000..9595e7f3 --- /dev/null +++ b/simgear/scene/viewer/CompositorUtil.cxx @@ -0,0 +1,62 @@ +// Copyright (C) 2018 Fernando García Liñán +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +#include +#include +#include + +#include "CompositorUtil.hxx" + +namespace simgear { +namespace compositor { + +bool +checkConditional(const SGPropertyNode *node) +{ + const SGPropertyNode *p_condition = node->getChild("condition"); + if (!p_condition) + return true; + SGSharedPtr condition = + sgReadCondition(getPropertyRoot(), p_condition); + return !condition || condition->test(); +} + +const SGPropertyNode * +getPropertyNode(const SGPropertyNode *prop) +{ + if (!prop) + return 0; + if (prop->nChildren() > 0) { + const SGPropertyNode *propertyProp = prop->getChild("property"); + if (!propertyProp) + return prop; + return getPropertyRoot()->getNode(propertyProp->getStringValue()); + } + return prop; +} + +const SGPropertyNode * +getPropertyChild(const SGPropertyNode *prop, + const char *name) +{ + const SGPropertyNode *child = prop->getChild(name); + if (!child) + return 0; + return getPropertyNode(child); +} + +} // namespace compositor +} // namespace simgear diff --git a/simgear/scene/viewer/CompositorCommon.hxx b/simgear/scene/viewer/CompositorUtil.hxx similarity index 78% rename from simgear/scene/viewer/CompositorCommon.hxx rename to simgear/scene/viewer/CompositorUtil.hxx index 17d519ae..d5385908 100644 --- a/simgear/scene/viewer/CompositorCommon.hxx +++ b/simgear/scene/viewer/CompositorUtil.hxx @@ -14,8 +14,8 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -#ifndef SG_COMPOSITOR_COMMON_HXX -#define SG_COMPOSITOR_COMMON_HXX +#ifndef SG_COMPOSITOR_UTIL_HXX +#define SG_COMPOSITOR_UTIL_HXX #include @@ -56,7 +56,17 @@ bool findPropString(const SGPropertyNode *parent, return false; } +/** + * Check if node should be enabled based on a condition tag. + * If no condition tag is found inside or it is malformed, it will be enabled. + */ +bool checkConditional(const SGPropertyNode *node); + +const SGPropertyNode *getPropertyNode(const SGPropertyNode *prop); +const SGPropertyNode *getPropertyChild(const SGPropertyNode *prop, + const char *name); + } // namespace compositor } // namespace simgear -#endif /* SG_COMPOSITOR_COMMON_HXX */ +#endif /* SG_COMPOSITOR_UTIL_HXX */