Compositor: Added support for static branching and <property> tags to be able to configure the Compositor at startup.

This commit is contained in:
Fernando García Liñán
2019-02-20 03:05:55 +01:00
parent 31c9df665d
commit 72f3a784de
7 changed files with 120 additions and 36 deletions

View File

@@ -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}")

View File

@@ -27,8 +27,10 @@
#include <simgear/props/props_io.hxx>
#include <simgear/scene/material/EffectCullVisitor.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
#include <simgear/structure/exception.hxx>
#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);

View File

@@ -30,7 +30,7 @@
#include <simgear/scene/util/OsgMath.hxx>
#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> 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);

View File

@@ -24,14 +24,13 @@
#include <simgear/props/vectorPropTemplates.hxx>
#include <simgear/scene/material/EffectGeode.hxx>
#include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/scene/util/OsgMath.hxx>
#include <simgear/scene/util/SGUpdateVisitor.hxx>
#include <simgear/structure/exception.hxx>
#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())

View File

@@ -24,7 +24,6 @@
#include <simgear/scene/material/Effect.hxx>
#include <simgear/structure/Singleton.hxx>
#include <simgear/props/condition.hxx>
#include <simgear/props/props.hxx>
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<osg::Camera> camera;
SGSharedPtr<SGCondition> condition;
/** If null, there is no effect override for this pass. */
osg::ref_ptr<Effect> effect_override;
bool useMastersSceneData;

View File

@@ -0,0 +1,62 @@
// Copyright (C) 2018 Fernando García Liñán <fernandogarcialinan@gmail.com>
//
// 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 <simgear/props/condition.hxx>
#include <simgear/props/props.hxx>
#include <simgear/scene/tgdb/userdata.hxx>
#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<SGCondition> 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

View File

@@ -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 <unordered_map>
@@ -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 */