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/structure/OSGUtils.hxx>
|
||||
#include <simgear/structure/SGExpression.hxx>
|
||||
#include <simgear/props/props_io.hxx>
|
||||
#include <simgear/props/vectorPropTemplates.hxx>
|
||||
#include <simgear/threads/SGThread.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.
|
||||
|
||||
Technique* Effect::chooseTechnique(RenderInfo* info)
|
||||
Technique* Effect::chooseTechnique(RenderInfo* info, const std::string &scheme)
|
||||
{
|
||||
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 0;
|
||||
@ -1308,6 +1310,7 @@ void buildTechnique(Effect* effect, const SGPropertyNode* prop,
|
||||
{
|
||||
Technique* tniq = new Technique;
|
||||
effect->techniques.push_back(tniq);
|
||||
tniq->setScheme(prop->getStringValue("scheme"));
|
||||
const SGPropertyNode* predProp = prop->getChild("predicate");
|
||||
if (!predProp) {
|
||||
tniq->setAlwaysValid(true);
|
||||
@ -1411,12 +1414,60 @@ bool makeParametersFromStateSet(SGPropertyNode* effectRoot, const StateSet* ss)
|
||||
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
|
||||
// passes.
|
||||
static SGMutex realizeTechniques_lock;
|
||||
bool Effect::realizeTechniques(const SGReaderWriterOptions* options)
|
||||
{
|
||||
SGGuard<SGMutex> g(realizeTechniques_lock);
|
||||
mergeSchemesFallbacks(this, options);
|
||||
|
||||
if (_isRealized)
|
||||
return true;
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
SGPropertyNode_ptr root;
|
||||
// Pointer to the parameters node, if it exists
|
||||
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 releaseGLObjects(osg::State* state = 0) const;
|
||||
/**
|
||||
|
@ -34,9 +34,9 @@ namespace simgear
|
||||
|
||||
using osgUtil::CullVisitor;
|
||||
|
||||
EffectCullVisitor::EffectCullVisitor(bool collectLights, Effect *effectOverride) :
|
||||
EffectCullVisitor::EffectCullVisitor(bool collectLights, const std::string &effScheme) :
|
||||
_collectLights(collectLights),
|
||||
_effectOverride(effectOverride)
|
||||
_effScheme(effScheme)
|
||||
{
|
||||
}
|
||||
|
||||
@ -62,18 +62,12 @@ void EffectCullVisitor::apply(osg::Geode& node)
|
||||
if (_collectLights && ( eg->getNodeMask() & MODELLIGHT_BIT ) ) {
|
||||
_lightList.push_back( eg );
|
||||
}
|
||||
Effect *effect;
|
||||
if (_effectOverride) {
|
||||
effect = _effectOverride;
|
||||
} else {
|
||||
effect = eg->getEffect();
|
||||
if (!effect) {
|
||||
CullVisitor::apply(node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Effect* effect = eg->getEffect();
|
||||
Technique* technique = 0;
|
||||
if (!(technique = effect->chooseTechnique(&getRenderInfo()))) {
|
||||
if (!effect) {
|
||||
CullVisitor::apply(node);
|
||||
return;
|
||||
} else if (!(technique = effect->chooseTechnique(&getRenderInfo(), _effScheme))) {
|
||||
return;
|
||||
}
|
||||
// push the node's state.
|
||||
|
@ -34,7 +34,7 @@ class EffectGeode;
|
||||
class EffectCullVisitor : public osgUtil::CullVisitor
|
||||
{
|
||||
public:
|
||||
EffectCullVisitor(bool collectLights = false, Effect *effectOverride = 0);
|
||||
EffectCullVisitor(bool collectLights = false, const std::string &effScheme = "");
|
||||
EffectCullVisitor(const EffectCullVisitor&);
|
||||
virtual osgUtil::CullVisitor* clone() const;
|
||||
using osgUtil::CullVisitor::apply;
|
||||
@ -49,7 +49,7 @@ private:
|
||||
std::map<std::string,osg::ref_ptr<osg::Texture2D> > _bufferList;
|
||||
std::vector<osg::ref_ptr<EffectGeode> > _lightList;
|
||||
bool _collectLights;
|
||||
osg::ref_ptr<Effect> _effectOverride;
|
||||
std::string _effScheme;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
@ -98,6 +98,8 @@ public:
|
||||
void setGLExtensionsPred(float glVersion,
|
||||
const std::vector<std::string>& extensions);
|
||||
void refreshValidity();
|
||||
const std::string &getScheme() const { return _scheme; }
|
||||
void setScheme(const std::string &scheme) { _scheme = scheme; }
|
||||
protected:
|
||||
// Validity of technique in a graphics context.
|
||||
struct ContextInfo : public osg::Referenced
|
||||
@ -117,6 +119,7 @@ protected:
|
||||
osg::ref_ptr<osg::StateSet> _shadowingStateSet;
|
||||
SGSharedPtr<SGExpressionb> _validExpression;
|
||||
int _contextIdLocation;
|
||||
std::string _scheme;
|
||||
};
|
||||
|
||||
class TechniquePredParser : public expression::ExpressionParser
|
||||
|
@ -274,7 +274,7 @@ Compositor::addPass(Pass *pass)
|
||||
identifier = sceneView->getCullVisitor()->getIdentifier();
|
||||
|
||||
sceneView->setCullVisitor(
|
||||
new EffectCullVisitor(false, pass->effect_override));
|
||||
new EffectCullVisitor(false, pass->effect_scheme));
|
||||
sceneView->getCullVisitor()->setIdentifier(identifier.get());
|
||||
|
||||
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!");
|
||||
}
|
||||
pass->type = root->getStringValue("type");
|
||||
|
||||
std::string eff_override_file = root->getStringValue("effect-override");
|
||||
if (!eff_override_file.empty())
|
||||
pass->effect_override = makeEffect(eff_override_file, true, options);
|
||||
pass->effect_scheme = root->getStringValue("effect-scheme");
|
||||
|
||||
osg::Camera *camera = new Camera;
|
||||
pass->camera = camera;
|
||||
|
@ -57,9 +57,8 @@ struct Pass : public osg::Referenced {
|
||||
int render_order;
|
||||
std::string name;
|
||||
std::string type;
|
||||
std::string effect_scheme;
|
||||
osg::ref_ptr<osg::Camera> camera;
|
||||
/** If null, there is no effect override for this pass. */
|
||||
osg::ref_ptr<Effect> effect_override;
|
||||
bool useMastersSceneData;
|
||||
osg::Node::NodeMask cull_mask;
|
||||
/** Whether the cull mask is ANDed with the view master camera cull mask. */
|
||||
|
Loading…
Reference in New Issue
Block a user