diff --git a/src/Viewer/CameraGroup.cxx b/src/Viewer/CameraGroup.cxx index 87bfe3c9b..71b11d065 100644 --- a/src/Viewer/CameraGroup.cxx +++ b/src/Viewer/CameraGroup.cxx @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -1036,8 +1035,6 @@ CameraInfo* CameraGroup::buildGUICamera(SGPropertyNode* cameraNode, CameraGroup* CameraGroup::buildCameraGroup(osgViewer::Viewer* viewer, SGPropertyNode* gnode) { - sgUserDataInit( globals->get_props() ); - CameraGroup* cgroup = new CameraGroup(viewer); for (int i = 0; i < gnode->nChildren(); ++i) { SGPropertyNode* pNode = gnode->getChild(i); diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx index 75e2e4216..731eefced 100644 --- a/src/Viewer/renderer.cxx +++ b/src/Viewer/renderer.cxx @@ -79,6 +79,7 @@ #include #include #include +#include #include #include #include @@ -502,6 +503,8 @@ public: 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" ); @@ -822,6 +825,13 @@ osg::Camera* FGRenderer::buildDefaultDeferredGeometryCamera( CameraInfo* info, o return buildDeferredGeometryCamera(info, gc, GEOMETRY_CAMERA, attachments); } +void buildAttachments(CameraInfo* info, osg::Camera* camera, const std::string& name, const std::vector > &attachments) { + BOOST_FOREACH(ref_ptr 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 > &attachments ) { osg::Camera* camera = new osg::Camera; @@ -837,9 +847,7 @@ osg::Camera* FGRenderer::buildDeferredGeometryCamera( CameraInfo* info, osg::Gra camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); camera->setRenderOrder(osg::Camera::NESTED_RENDER, 0); camera->setViewport( new osg::Viewport ); - BOOST_FOREACH(ref_ptr attachment, attachments) { - attachBufferToCamera( info, camera, attachment->component, name, attachment->buffer ); - } + buildAttachments(info, camera, name, attachments); camera->setDrawBuffer(GL_FRONT); camera->setReadBuffer(GL_FRONT); @@ -907,9 +915,7 @@ osg::Camera* FGRenderer::buildDeferredShadowCamera( CameraInfo* info, osg::Graph mainShadowCamera->setAllowEventFocus(false); mainShadowCamera->setGraphicsContext(gc); mainShadowCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); - BOOST_FOREACH(ref_ptr 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()); @@ -1131,9 +1137,7 @@ osg::Camera* FGRenderer::buildDeferredLightingCamera( CameraInfo* info, osg::Gra camera->setRenderOrder(osg::Camera::NESTED_RENDER, 50); camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); camera->setViewport( new osg::Viewport ); - BOOST_FOREACH(ref_ptr 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. ) ); @@ -1289,9 +1293,7 @@ FGRenderer::buildDeferredFullscreenCamera( flightgear::CameraInfo* info, osg::Gr 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 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. ) ); @@ -1405,6 +1407,9 @@ void FGRenderer::buildStage(FGRenderingPipeline* rpipe, CameraInfo* info, const osg::Matrix& projection, osg::GraphicsContext* gc) { + if (!stage->valid()) + return; + ref_ptr camera; if (stage->type == "geometry") camera = buildDeferredGeometryCamera(info, gc, stage->name, stage->attachments); @@ -1432,15 +1437,17 @@ void FGRenderer::buildBuffers(FGRenderingPipeline* rpipe, CameraInfo* info) { for (size_t i = 0; i < rpipe->buffers.size(); ++i) { osg::ref_ptr 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); + } } } } diff --git a/src/Viewer/renderingpipeline.cxx b/src/Viewer/renderingpipeline.cxx index 9b3cd9606..1dc3043d6 100644 --- a/src/Viewer/renderingpipeline.cxx +++ b/src/Viewer/renderingpipeline.cxx @@ -85,6 +85,40 @@ FGRenderingPipeline* makeRenderingPipeline(const std::string& name, } +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(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 void findAttrOrHex(const simgear::effect::EffectPropertyMap& pMap, const SGPropertyNode* prop, @@ -172,11 +206,23 @@ FGRenderingPipeline::Buffer::Buffer(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; @@ -195,6 +241,8 @@ FGRenderingPipeline::Buffer::Buffer(SGPropertyNode* prop) scaleFactor = prop->getFloatValue("scale-factor", 1.f); shadowComparison = prop->getBoolValue("shadow-comparison", false); + + parseCondition(prop); } simgear::effect::EffectNameValue componentsInit[] = @@ -232,6 +280,8 @@ FGRenderingPipeline::Stage::Stage(SGPropertyNode* prop) 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) @@ -242,6 +292,8 @@ FGRenderingPipeline::Attachment::Attachment(SGPropertyNode* prop) throw sg_exception("Attachment buffer is mandatory"); } buffer = bufferProp->getStringValue(); + + parseCondition(prop); } FGRenderingPipeline::FGRenderingPipeline() diff --git a/src/Viewer/renderingpipeline.hxx b/src/Viewer/renderingpipeline.hxx index 2fc705d41..e05037e38 100644 --- a/src/Viewer/renderingpipeline.hxx +++ b/src/Viewer/renderingpipeline.hxx @@ -6,6 +6,8 @@ #include #include +#include + namespace simgear { class SGReaderWriterOptions; @@ -24,7 +26,19 @@ namespace flightgear { 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 _validExpression; + }; + struct Buffer : public Conditionable { Buffer(SGPropertyNode* prop); std::string name; @@ -40,14 +54,14 @@ public: //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) {} @@ -56,7 +70,7 @@ public: }; typedef std::vector > AttachmentList; - struct Stage : public osg::Referenced { + struct Stage : public Conditionable { Stage(SGPropertyNode* prop); std::string name; @@ -78,4 +92,13 @@ public: const simgear::SGReaderWriterOptions* options); }; +namespace flightgear { + +class PipelinePredParser : public simgear::expression::ExpressionParser +{ +public: +protected: +}; +} + #endif