#include <simgear/scene/util/SGSceneUserData.hxx>
#include <simgear/scene/tgdb/GroundLightManager.hxx>
#include <simgear/scene/tgdb/pt_lights.hxx>
+#include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/structure/OSGUtils.hxx>
#include <simgear/props/props.hxx>
#include <simgear/timing/sg_time.hxx>
void
FGRenderer::init( void )
{
+ sgUserDataInit( globals->get_props() );
+
_classicalRenderer = !fgGetBool("/sim/rendering/rembrandt/enabled", false);
_shadowMapSize = fgGetInt( "/sim/rendering/shadows/map-size", 4096 );
fgAddChangeListener( new ShadowMapSizeListener, "/sim/rendering/shadows/map-size" );
return buildDeferredGeometryCamera(info, gc, GEOMETRY_CAMERA, attachments);
}
+void buildAttachments(CameraInfo* info, osg::Camera* camera, const std::string& name, const std::vector<ref_ptr<FGRenderingPipeline::Attachment> > &attachments) {
+ BOOST_FOREACH(ref_ptr<FGRenderingPipeline::Attachment> attachment, attachments) {
+ if (attachment->valid())
+ attachBufferToCamera( info, camera, attachment->component, name, attachment->buffer );
+ }
+}
+
osg::Camera* FGRenderer::buildDeferredGeometryCamera( CameraInfo* info, osg::GraphicsContext* gc, const std::string& name, const std::vector<ref_ptr<FGRenderingPipeline::Attachment> > &attachments )
{
osg::Camera* camera = new osg::Camera;
camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
camera->setRenderOrder(osg::Camera::NESTED_RENDER, 0);
camera->setViewport( new osg::Viewport );
- BOOST_FOREACH(ref_ptr<FGRenderingPipeline::Attachment> attachment, attachments) {
- attachBufferToCamera( info, camera, attachment->component, name, attachment->buffer );
- }
+ buildAttachments(info, camera, name, attachments);
camera->setDrawBuffer(GL_FRONT);
camera->setReadBuffer(GL_FRONT);
mainShadowCamera->setAllowEventFocus(false);
mainShadowCamera->setGraphicsContext(gc);
mainShadowCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
- BOOST_FOREACH(ref_ptr<FGRenderingPipeline::Attachment> attachment, attachments) {
- attachBufferToCamera( info, mainShadowCamera, attachment->component, name, attachment->buffer );
- }
+ buildAttachments(info, mainShadowCamera, name, attachments);
mainShadowCamera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
mainShadowCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
mainShadowCamera->setProjectionMatrix(osg::Matrix::identity());
camera->setRenderOrder(osg::Camera::NESTED_RENDER, 50);
camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
camera->setViewport( new osg::Viewport );
- BOOST_FOREACH(ref_ptr<FGRenderingPipeline::Attachment> attachment, attachments) {
- attachBufferToCamera( info, camera, attachment->component, name, attachment->buffer );
- }
+ buildAttachments(info, camera, name, attachments);
camera->setDrawBuffer(GL_FRONT);
camera->setReadBuffer(GL_FRONT);
camera->setClearColor( osg::Vec4( 0., 0., 0., 1. ) );
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setRenderOrder(osg::Camera::NESTED_RENDER, stage->orderNum);
camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
- BOOST_FOREACH(ref_ptr<FGRenderingPipeline::Attachment> attachment, stage->attachments) {
- attachBufferToCamera( info, camera, attachment->component, stage->name, attachment->buffer );
- }
+ buildAttachments(info, camera, stage->name, stage->attachments);
camera->setDrawBuffer(GL_FRONT);
camera->setReadBuffer(GL_FRONT);
camera->setClearColor( osg::Vec4( 1., 1., 1., 1. ) );
const osg::Matrix& projection,
osg::GraphicsContext* gc)
{
+ if (!stage->valid())
+ return;
+
ref_ptr<Camera> camera;
if (stage->type == "geometry")
camera = buildDeferredGeometryCamera(info, gc, stage->name, stage->attachments);
{
for (size_t i = 0; i < rpipe->buffers.size(); ++i) {
osg::ref_ptr<FGRenderingPipeline::Buffer> buffer = rpipe->buffers[i];
- bool fullscreen = buffer->width == -1 && buffer->height == -1;
- info->addBuffer(buffer->name, buildDeferredBuffer( buffer->internalFormat,
- buffer->sourceFormat,
- buffer->sourceType,
- buffer->wrapMode,
- buffer->shadowComparison),
- fullscreen ? buffer->scaleFactor : 0.0f);
- if (!fullscreen) {
- info->getBuffer(buffer->name)->setTextureSize(buffer->width, buffer->height);
+ if (buffer->valid()) {
+ bool fullscreen = buffer->width == -1 && buffer->height == -1;
+ info->addBuffer(buffer->name, buildDeferredBuffer( buffer->internalFormat,
+ buffer->sourceFormat,
+ buffer->sourceType,
+ buffer->wrapMode,
+ buffer->shadowComparison),
+ fullscreen ? buffer->scaleFactor : 0.0f);
+ if (!fullscreen) {
+ info->getBuffer(buffer->name)->setTextureSize(buffer->width, buffer->height);
+ }
}
}
}
}
+void
+FGRenderingPipeline::Conditionable::parseCondition(SGPropertyNode* prop)
+{
+ const SGPropertyNode* predProp = prop->getChild("condition");
+ if (!predProp) {
+ setAlwaysValid(true);
+ } else {
+ try {
+ flightgear::PipelinePredParser parser;
+ SGExpressionb* validExp = dynamic_cast<SGExpressionb*>(parser.read(predProp->getChild(0)));
+ if (validExp)
+ setValidExpression(validExp);
+ else
+ throw simgear::expression::ParseError("pipeline condition is not a boolean expression");
+ }
+ catch (simgear::expression::ParseError& except)
+ {
+ SG_LOG(SG_INPUT, SG_ALERT,
+ "parsing pipeline condition " << except.getMessage());
+ setAlwaysValid(false);
+ }
+ }
+}
+
+void FGRenderingPipeline::Conditionable::setValidExpression(SGExpressionb* exp)
+{
+ _validExpression = exp;
+}
+
+bool FGRenderingPipeline::Conditionable::valid()
+{
+ return _alwaysValid || _validExpression->getValue();
+}
+
template<typename T>
void findAttrOrHex(const simgear::effect::EffectPropertyMap<T>& pMap,
const SGPropertyNode* prop,
if (!nameProp.valid()) {
throw sg_exception("Buffer name is mandatory");
}
+ internalFormat = GL_RGBA8;
+ sourceFormat = GL_RGBA;
+ sourceType = GL_UNSIGNED_BYTE;
+ wrapMode = GL_CLAMP_TO_BORDER_ARB;
name = nameProp->getStringValue();
- findAttrOrHex(internalFormats, prop->getChild("internal-format"), internalFormat);
- findAttrOrHex(sourceFormats, prop->getChild("source-format"), sourceFormat);
- findAttrOrHex(sourceTypes, prop->getChild("source-type"), sourceType);
- findAttrOrHex(wrapModes, prop->getChild("wrap-mode"), wrapMode);
+ SGPropertyNode* internalFormatProp = prop->getChild("internal-format");
+ if (internalFormatProp)
+ findAttrOrHex(internalFormats, internalFormatProp, internalFormat);
+ SGPropertyNode* sourceFormatProp = prop->getChild("source-format");
+ if (sourceFormatProp)
+ findAttrOrHex(sourceFormats, sourceFormatProp, sourceFormat);
+ SGPropertyNode* sourceTypeProp = prop->getChild("source-type");
+ if (sourceTypeProp)
+ findAttrOrHex(sourceTypes, sourceTypeProp, sourceType);
+ SGPropertyNode* wrapModeProp = prop->getChild("wrap-mode");
+ if (wrapModeProp)
+ findAttrOrHex(wrapModes, wrapModeProp, wrapMode);
SGConstPropertyNode_ptr widthProp = getPropertyChild(prop, "width");
if (!widthProp.valid())
width = -1;
scaleFactor = prop->getFloatValue("scale-factor", 1.f);
shadowComparison = prop->getBoolValue("shadow-comparison", false);
+
+ parseCondition(prop);
}
simgear::effect::EffectNameValue<osg::Camera::BufferComponent> componentsInit[] =
for (int i = 0; i < (int)attachments.size(); ++i) {
this->attachments.push_back(new FGRenderingPipeline::Attachment(attachments[i]));
}
+
+ parseCondition(prop);
}
FGRenderingPipeline::Attachment::Attachment(SGPropertyNode* prop)
throw sg_exception("Attachment buffer is mandatory");
}
buffer = bufferProp->getStringValue();
+
+ parseCondition(prop);
}
FGRenderingPipeline::FGRenderingPipeline()
#include <osg/Camera>
#include <string>
+#include <simgear/structure/SGExpression.hxx>
+
namespace simgear
{
class SGReaderWriterOptions;
class FGRenderingPipeline : public osg::Referenced {
public:
- struct Buffer : public osg::Referenced {
+ class Conditionable : public osg::Referenced {
+ public:
+ Conditionable() : _alwaysValid(false) {}
+ void parseCondition(SGPropertyNode* prop);
+ bool getAlwaysValid() const { return _alwaysValid; }
+ void setAlwaysValid(bool val) { _alwaysValid = val; }
+ void setValidExpression(SGExpressionb* exp);
+ bool valid();
+ protected:
+ bool _alwaysValid;
+ SGSharedPtr<SGExpressionb> _validExpression;
+ };
+ struct Buffer : public Conditionable {
Buffer(SGPropertyNode* prop);
std::string name;
//osg::Vec4 borderColor;
};
- struct Pass : public osg::Referenced {
+ struct Pass : public Conditionable {
Pass(SGPropertyNode* prop);
std::string name;
std::string type;
};
- struct Attachment : public osg::Referenced {
+ struct Attachment : public Conditionable {
Attachment(SGPropertyNode* prop);
Attachment(osg::Camera::BufferComponent c, const std::string& b ) : component(c), buffer(b) {}
};
typedef std::vector<osg::ref_ptr<Attachment> > AttachmentList;
- struct Stage : public osg::Referenced {
+ struct Stage : public Conditionable {
Stage(SGPropertyNode* prop);
std::string name;
const simgear::SGReaderWriterOptions* options);
};
+namespace flightgear {
+
+class PipelinePredParser : public simgear::expression::ExpressionParser
+{
+public:
+protected:
+};
+}
+
#endif