]> git.mxchange.org Git - flightgear.git/blobdiff - src/Viewer/renderingpipeline.cxx
Remove hard-coded lighting stage
[flightgear.git] / src / Viewer / renderingpipeline.cxx
index dfdcf3388e16675b60d6b8158a8765dee1d528eb..da9cd09a377ca2c026048241cd26ef73c29f96b8 100644 (file)
@@ -51,7 +51,7 @@ namespace flightgear {
 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);
@@ -85,6 +85,41 @@ FGRenderingPipeline* makeRenderingPipeline(const std::string& name,
 
 }
 
+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,
@@ -103,6 +138,29 @@ void findAttrOrHex(const simgear::effect::EffectPropertyMap<T>& pMap,
     }
 }
 
+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 },
@@ -149,19 +207,32 @@ 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(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"))
@@ -171,69 +242,72 @@ FGRenderingPipeline::Buffer::Buffer(SGPropertyNode* prop)
 
     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", "");
+
+    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 {
@@ -258,34 +332,3 @@ private:
     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)
-{
-}