Compositor: Added support for static branching and <property> tags to be able to configure the Compositor at startup.
This commit is contained in:
@@ -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}")
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
|
||||
62
simgear/scene/viewer/CompositorUtil.cxx
Normal file
62
simgear/scene/viewer/CompositorUtil.cxx
Normal 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
|
||||
@@ -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 */
|
||||
Reference in New Issue
Block a user