Merge /u/fgarlin/simgear/ branch next into next
https://sourceforge.net/p/flightgear/simgear/merge-requests/55/
This commit is contained in:
commit
39eb9837e9
@ -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;
|
||||||
|
@ -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;
|
||||||
/**
|
/**
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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. */
|
||||||
|
Loading…
Reference in New Issue
Block a user