Merge /u/fgarlin/simgear/ branch next into next

https://sourceforge.net/p/flightgear/simgear/merge-requests/55/
This commit is contained in:
Richard Harrison 2019-05-05 13:50:27 +00:00
commit 39eb9837e9
8 changed files with 69 additions and 25 deletions

View File

@ -77,6 +77,7 @@
#include <simgear/scene/util/StateAttributeFactory.hxx> #include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/structure/OSGUtils.hxx> #include <simgear/structure/OSGUtils.hxx>
#include <simgear/structure/SGExpression.hxx> #include <simgear/structure/SGExpression.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/props/vectorPropTemplates.hxx> #include <simgear/props/vectorPropTemplates.hxx>
#include <simgear/threads/SGThread.hxx> #include <simgear/threads/SGThread.hxx>
#include <simgear/threads/SGGuard.hxx> #include <simgear/threads/SGGuard.hxx>
@ -245,11 +246,12 @@ int Effect::getGenerator(Effect::Generator what) const
// There should always be a valid technique in an effect. // There should always be a valid technique in an effect.
Technique* Effect::chooseTechnique(RenderInfo* info) Technique* Effect::chooseTechnique(RenderInfo* info, const std::string &scheme)
{ {
BOOST_FOREACH(ref_ptr<Technique>& technique, techniques) BOOST_FOREACH(ref_ptr<Technique>& technique, techniques)
{ {
if (technique->valid(info) == Technique::VALID) if (technique->valid(info) == Technique::VALID &&
technique->getScheme() == scheme)
return technique.get(); return technique.get();
} }
return 0; return 0;
@ -1308,6 +1310,7 @@ void buildTechnique(Effect* effect, const SGPropertyNode* prop,
{ {
Technique* tniq = new Technique; Technique* tniq = new Technique;
effect->techniques.push_back(tniq); effect->techniques.push_back(tniq);
tniq->setScheme(prop->getStringValue("scheme"));
const SGPropertyNode* predProp = prop->getChild("predicate"); const SGPropertyNode* predProp = prop->getChild("predicate");
if (!predProp) { if (!predProp) {
tniq->setAlwaysValid(true); tniq->setAlwaysValid(true);
@ -1411,12 +1414,60 @@ bool makeParametersFromStateSet(SGPropertyNode* effectRoot, const StateSet* ss)
return true; return true;
} }
SGPropertyNode_ptr schemeList;
void mergeSchemesFallbacks(Effect *effect, const SGReaderWriterOptions *options)
{
if (!schemeList) {
schemeList = new SGPropertyNode;
const string schemes_file("Effects/schemes.xml");
string absFileName
= SGModelLib::findDataFile(schemes_file, options);
if (absFileName.empty()) {
SG_LOG(SG_INPUT, SG_ALERT, "Could not find '" << schemes_file << "'");
return;
}
try {
readProperties(absFileName, schemeList, 0, true);
} catch (sg_io_exception& e) {
SG_LOG(SG_INPUT, SG_ALERT, "Error reading '" << schemes_file <<
"': " << e.getFormattedMessage());
return;
}
}
PropertyList p_schemes = schemeList->getChildren("scheme");
for (const auto &p_scheme : p_schemes) {
string scheme_name = p_scheme->getStringValue("name");
string fallback_name = p_scheme->getStringValue("fallback");
if (scheme_name.empty() || fallback_name.empty())
continue;
vector<SGPropertyNode_ptr> techniques = effect->root->getChildren("technique");
auto it = std::find_if(techniques.begin(), techniques.end(),
[&scheme_name](const SGPropertyNode_ptr &tniq) {
return tniq->getStringValue("scheme") == scheme_name;
});
// Only merge the fallback effect if we haven't found a technique
// implementing the scheme
if (it == techniques.end()) {
ref_ptr<Effect> fallback = makeEffect(fallback_name, false, options);
if (fallback) {
SGPropertyNode *new_root = new SGPropertyNode;
mergePropertyTrees(new_root, effect->root, fallback->root);
effect->root = new_root;
effect->parametersProp = effect->root->getChild("parameters");
}
}
}
}
// Walk the techniques property tree, building techniques and // Walk the techniques property tree, building techniques and
// passes. // passes.
static SGMutex realizeTechniques_lock; static SGMutex realizeTechniques_lock;
bool Effect::realizeTechniques(const SGReaderWriterOptions* options) bool Effect::realizeTechniques(const SGReaderWriterOptions* options)
{ {
SGGuard<SGMutex> g(realizeTechniques_lock); SGGuard<SGMutex> g(realizeTechniques_lock);
mergeSchemesFallbacks(this, options);
if (_isRealized) if (_isRealized)
return true; return true;

View File

@ -92,7 +92,7 @@ public:
SGPropertyNode_ptr root; SGPropertyNode_ptr root;
// Pointer to the parameters node, if it exists // Pointer to the parameters node, if it exists
SGPropertyNode_ptr parametersProp; SGPropertyNode_ptr parametersProp;
Technique* chooseTechnique(osg::RenderInfo* renderInfo); Technique* chooseTechnique(osg::RenderInfo* renderInfo, const std::string &scheme);
virtual void resizeGLObjectBuffers(unsigned int maxSize); virtual void resizeGLObjectBuffers(unsigned int maxSize);
virtual void releaseGLObjects(osg::State* state = 0) const; virtual void releaseGLObjects(osg::State* state = 0) const;
/** /**

View File

@ -34,9 +34,9 @@ namespace simgear
using osgUtil::CullVisitor; using osgUtil::CullVisitor;
EffectCullVisitor::EffectCullVisitor(bool collectLights, Effect *effectOverride) : EffectCullVisitor::EffectCullVisitor(bool collectLights, const std::string &effScheme) :
_collectLights(collectLights), _collectLights(collectLights),
_effectOverride(effectOverride) _effScheme(effScheme)
{ {
} }
@ -62,18 +62,12 @@ void EffectCullVisitor::apply(osg::Geode& node)
if (_collectLights && ( eg->getNodeMask() & MODELLIGHT_BIT ) ) { if (_collectLights && ( eg->getNodeMask() & MODELLIGHT_BIT ) ) {
_lightList.push_back( eg ); _lightList.push_back( eg );
} }
Effect *effect; Effect* effect = eg->getEffect();
if (_effectOverride) {
effect = _effectOverride;
} else {
effect = eg->getEffect();
if (!effect) {
CullVisitor::apply(node);
return;
}
}
Technique* technique = 0; Technique* technique = 0;
if (!(technique = effect->chooseTechnique(&getRenderInfo()))) { if (!effect) {
CullVisitor::apply(node);
return;
} else if (!(technique = effect->chooseTechnique(&getRenderInfo(), _effScheme))) {
return; return;
} }
// push the node's state. // push the node's state.

View File

@ -34,7 +34,7 @@ class EffectGeode;
class EffectCullVisitor : public osgUtil::CullVisitor class EffectCullVisitor : public osgUtil::CullVisitor
{ {
public: public:
EffectCullVisitor(bool collectLights = false, Effect *effectOverride = 0); EffectCullVisitor(bool collectLights = false, const std::string &effScheme = "");
EffectCullVisitor(const EffectCullVisitor&); EffectCullVisitor(const EffectCullVisitor&);
virtual osgUtil::CullVisitor* clone() const; virtual osgUtil::CullVisitor* clone() const;
using osgUtil::CullVisitor::apply; using osgUtil::CullVisitor::apply;
@ -49,7 +49,7 @@ private:
std::map<std::string,osg::ref_ptr<osg::Texture2D> > _bufferList; std::map<std::string,osg::ref_ptr<osg::Texture2D> > _bufferList;
std::vector<osg::ref_ptr<EffectGeode> > _lightList; std::vector<osg::ref_ptr<EffectGeode> > _lightList;
bool _collectLights; bool _collectLights;
osg::ref_ptr<Effect> _effectOverride; std::string _effScheme;
}; };
} }
#endif #endif

View File

@ -98,6 +98,8 @@ public:
void setGLExtensionsPred(float glVersion, void setGLExtensionsPred(float glVersion,
const std::vector<std::string>& extensions); const std::vector<std::string>& extensions);
void refreshValidity(); void refreshValidity();
const std::string &getScheme() const { return _scheme; }
void setScheme(const std::string &scheme) { _scheme = scheme; }
protected: protected:
// Validity of technique in a graphics context. // Validity of technique in a graphics context.
struct ContextInfo : public osg::Referenced struct ContextInfo : public osg::Referenced
@ -117,6 +119,7 @@ protected:
osg::ref_ptr<osg::StateSet> _shadowingStateSet; osg::ref_ptr<osg::StateSet> _shadowingStateSet;
SGSharedPtr<SGExpressionb> _validExpression; SGSharedPtr<SGExpressionb> _validExpression;
int _contextIdLocation; int _contextIdLocation;
std::string _scheme;
}; };
class TechniquePredParser : public expression::ExpressionParser class TechniquePredParser : public expression::ExpressionParser

View File

@ -274,7 +274,7 @@ Compositor::addPass(Pass *pass)
identifier = sceneView->getCullVisitor()->getIdentifier(); identifier = sceneView->getCullVisitor()->getIdentifier();
sceneView->setCullVisitor( sceneView->setCullVisitor(
new EffectCullVisitor(false, pass->effect_override)); new EffectCullVisitor(false, pass->effect_scheme));
sceneView->getCullVisitor()->setIdentifier(identifier.get()); sceneView->getCullVisitor()->setIdentifier(identifier.get());
identifier = sceneView->getCullVisitorLeft()->getIdentifier(); identifier = sceneView->getCullVisitorLeft()->getIdentifier();

View File

@ -67,10 +67,7 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root,
<< " has no name. It won't be addressable by name!"); << " has no name. It won't be addressable by name!");
} }
pass->type = root->getStringValue("type"); pass->type = root->getStringValue("type");
pass->effect_scheme = root->getStringValue("effect-scheme");
std::string eff_override_file = root->getStringValue("effect-override");
if (!eff_override_file.empty())
pass->effect_override = makeEffect(eff_override_file, true, options);
osg::Camera *camera = new Camera; osg::Camera *camera = new Camera;
pass->camera = camera; pass->camera = camera;

View File

@ -57,9 +57,8 @@ struct Pass : public osg::Referenced {
int render_order; int render_order;
std::string name; std::string name;
std::string type; std::string type;
std::string effect_scheme;
osg::ref_ptr<osg::Camera> camera; osg::ref_ptr<osg::Camera> camera;
/** If null, there is no effect override for this pass. */
osg::ref_ptr<Effect> effect_override;
bool useMastersSceneData; bool useMastersSceneData;
osg::Node::NodeMask cull_mask; osg::Node::NodeMask cull_mask;
/** Whether the cull mask is ANDed with the view master camera cull mask. */ /** Whether the cull mask is ANDed with the view master camera cull mask. */