FGRenderingPipeline* makeRenderingPipeline(const std::string& name,
const simgear::SGReaderWriterOptions* options)
{
- std::string fileName(name);
+ std::string fileName = "Effects/" + name;
fileName += ".xml";
std::string absFileName
= simgear::SGModelLib::findDataFile(fileName, options);
}
+void
+FGRenderingPipeline::Conditionable::parseCondition(SGPropertyNode* prop)
+{
+ const SGPropertyNode* predProp = prop->getChild("condition");
+ if (!predProp) {
+ setAlwaysValid(true);
+ } else {
+ setAlwaysValid(false);
+ 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,
try {
result = boost::lexical_cast<T>(val);
} catch (boost::bad_lexical_cast &) {
- throw simgear::effect::BuilderException(string("findAttrOrHex: could not find attribute ")
- + string(val));
+ throw simgear::effect::BuilderException(std::string("findAttrOrHex: could not find attribute ")
+ + std::string(val));
}
}
}
+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 globals->get_props()->getNode(propertyProp->getStringValue());
+ }
+ return prop;
+}
+
+const SGPropertyNode* getPropertyChild(const SGPropertyNode* prop,
+ const char* name)
+{
+ const SGPropertyNode* child = prop->getChild(name);
+ if (!child)
+ return 0;
+ else
+ return getPropertyNode(child);
+}
+
simgear::effect::EffectNameValue<GLint> internalFormatInit[] =
{
{ "rgb8", GL_RGB8 },
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(sourceTypes, prop->getChild("wrap-mode"), wrapMode);
- SGPropertyNode_ptr widthProp = prop->getChild("width");
+ 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;
else if (widthProp->getStringValue() == std::string("screen"))
width = -1;
- else
+ else {
width = widthProp->getIntValue();
- SGPropertyNode_ptr heightProp = prop->getChild("height");
+ }
+ SGConstPropertyNode_ptr heightProp = getPropertyChild(prop, "height");
if (!heightProp.valid())
height = -1;
else if (heightProp->getStringValue() == std::string("screen"))
scaleFactor = prop->getFloatValue("scale-factor", 1.f);
shadowComparison = prop->getBoolValue("shadow-comparison", false);
+
+ parseCondition(prop);
}
-FGRenderingPipeline::Stage::Stage(SGPropertyNode* prop)
+simgear::effect::EffectNameValue<osg::Camera::BufferComponent> componentsInit[] =
+{
+ {"depth", osg::Camera::DEPTH_BUFFER},
+ {"stencil", osg::Camera::STENCIL_BUFFER},
+ {"packed-depth-stencil", osg::Camera::PACKED_DEPTH_STENCIL_BUFFER},
+ {"color0", osg::Camera::COLOR_BUFFER0},
+ {"color1", osg::Camera::COLOR_BUFFER1},
+ {"color2", osg::Camera::COLOR_BUFFER2},
+ {"color3", osg::Camera::COLOR_BUFFER3}
+};
+simgear::effect::EffectPropertyMap<osg::Camera::BufferComponent> components(componentsInit);
+
+FGRenderingPipeline::Pass::Pass(SGPropertyNode* prop)
{
SGPropertyNode_ptr nameProp = prop->getChild("name");
if (!nameProp.valid()) {
- throw sg_exception("Stage name is mandatory");
+ throw sg_exception("Pass name is mandatory");
}
name = nameProp->getStringValue();
SGPropertyNode_ptr typeProp = prop->getChild("type");
if (!typeProp.valid()) {
- throw sg_exception("Stage type is mandatory");
+ type = nameProp->getStringValue();
+ } else {
+ type = typeProp->getStringValue();
}
- type = typeProp->getStringValue();
-}
-FGRenderingPipeline::FGRenderingPipeline()
-{
+ orderNum = prop->getIntValue("order-num", -1);
+ effect = prop->getStringValue("effect", "");
+ debugProperty = prop->getStringValue("debug-property", "");
+
+ parseCondition(prop);
}
-flightgear::CameraInfo* FGRenderingPipeline::buildCamera(flightgear::CameraGroup* cgroup, unsigned flags, osg::Camera* camera,
- const osg::Matrix& view, const osg::Matrix& projection, osg::GraphicsContext* gc)
+FGRenderingPipeline::Stage::Stage(SGPropertyNode* prop) : Pass(prop)
{
- flightgear::CameraInfo* info = new flightgear::CameraInfo(flags);
- buildBuffers( info );
-
- for (size_t i = 0; i < stages.size(); ++i) {
- osg::ref_ptr<Stage> stage = stages[i];
- buildStage(info, stage, cgroup, camera, view, projection, gc);
+ needsDuDv = prop->getBoolValue("needs-du-dv", false);
+ scaleFactor = prop->getFloatValue("scale-factor", 1.f);
+
+ std::vector<SGPropertyNode_ptr> attachments = prop->getChildren("attachment");
+ for (int i = 0; i < (int)attachments.size(); ++i) {
+ this->attachments.push_back(new FGRenderingPipeline::Attachment(attachments[i]));
}
- return 0;
+ std::vector<SGPropertyNode_ptr> passes = prop->getChildren("pass");
+ for (int i = 0; i < (int)passes.size(); ++i) {
+ this->passes.push_back(new FGRenderingPipeline::Pass(passes[i]));
+ }
}
-osg::Texture2D* buildDeferredBuffer(GLint internalFormat, GLenum sourceFormat, GLenum sourceType, GLenum wrapMode, bool shadowComparison)
+FGRenderingPipeline::Attachment::Attachment(SGPropertyNode* prop)
{
- osg::Texture2D* tex = new osg::Texture2D;
- tex->setResizeNonPowerOfTwoHint( false );
- tex->setInternalFormat( internalFormat );
- tex->setShadowComparison(shadowComparison);
- if (shadowComparison) {
- tex->setShadowTextureMode(osg::Texture2D::LUMINANCE);
- tex->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
+ simgear::findAttr(components, prop->getChild("component"), component);
+ SGPropertyNode_ptr bufferProp = prop->getChild("buffer");
+ if (!bufferProp.valid()) {
+ throw sg_exception("Attachment buffer is mandatory");
}
- tex->setSourceFormat(sourceFormat);
- tex->setSourceType(sourceType);
- tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
- tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );
- tex->setWrap( osg::Texture::WRAP_S, (osg::Texture::WrapMode)wrapMode );
- tex->setWrap( osg::Texture::WRAP_T, (osg::Texture::WrapMode)wrapMode );
- return tex;
+ buffer = bufferProp->getStringValue();
+
+ parseCondition(prop);
}
-void FGRenderingPipeline::buildBuffers( flightgear::CameraInfo* info )
+FGRenderingPipeline::FGRenderingPipeline()
{
- for (size_t i = 0; i < buffers.size(); ++i) {
- osg::ref_ptr<Buffer> buffer = buffers[i];
- info->addBuffer(buffer->name, buildDeferredBuffer( buffer->internalFormat,
- buffer->sourceFormat,
- buffer->sourceType,
- buffer->wrapMode,
- buffer->shadowComparison) );
- }
}
class FGStageCameraCullCallback : public osg::NodeCallback {
osg::ref_ptr<FGRenderingPipeline::Stage> stage;
flightgear::CameraInfo* info;
};
-
-void FGRenderingPipeline::buildStage(flightgear::CameraInfo* info,
- Stage* stage,
- flightgear::CameraGroup* cgroup,
- osg::Camera* camera,
- const osg::Matrix& view,
- const osg::Matrix& projection,
- osg::GraphicsContext* gc)
-{
- osg::ref_ptr<osg::Camera> stageCamera;
- if (stage->type == "main-camera")
- stageCamera = camera;
- else
- stageCamera = new osg::Camera;
-
- stageCamera->setName(stage->name);
- stageCamera->setGraphicsContext(gc);
- stageCamera->setCullCallback(new FGStageCameraCullCallback(stage, info));
- if (stage->type != "main-camera")
- stageCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
-}
-
-void FGRenderingPipeline::buildMainCamera(flightgear::CameraInfo* info,
- Stage* stage,
- flightgear::CameraGroup* cgroup,
- osg::Camera* camera,
- const osg::Matrix& view,
- const osg::Matrix& projection,
- osg::GraphicsContext* gc)
-{
-}