Merge branch 'UniformFactory' into next
Merging in Stuart's fix for the Effect system
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <boost/tr1/unordered_map.hpp>
|
#include <boost/tr1/unordered_map.hpp>
|
||||||
|
|
||||||
@@ -77,7 +78,8 @@
|
|||||||
#include <simgear/structure/OSGUtils.hxx>
|
#include <simgear/structure/OSGUtils.hxx>
|
||||||
#include <simgear/structure/SGExpression.hxx>
|
#include <simgear/structure/SGExpression.hxx>
|
||||||
#include <simgear/props/vectorPropTemplates.hxx>
|
#include <simgear/props/vectorPropTemplates.hxx>
|
||||||
|
#include <simgear/threads/SGThread.hxx>
|
||||||
|
#include <simgear/threads/SGGuard.hxx>
|
||||||
|
|
||||||
namespace simgear
|
namespace simgear
|
||||||
{
|
{
|
||||||
@@ -87,6 +89,148 @@ using namespace osgUtil;
|
|||||||
|
|
||||||
using namespace effect;
|
using namespace effect;
|
||||||
|
|
||||||
|
class UniformFactoryImpl {
|
||||||
|
public:
|
||||||
|
ref_ptr<Uniform> getUniform( Effect * effect,
|
||||||
|
const string & name,
|
||||||
|
Uniform::Type uniformType,
|
||||||
|
SGConstPropertyNode_ptr valProp,
|
||||||
|
const SGReaderWriterOptions* options );
|
||||||
|
void updateListeners( SGPropertyNode* propRoot );
|
||||||
|
void addListener(DeferredPropertyListener* listener);
|
||||||
|
private:
|
||||||
|
// Default names for vector property components
|
||||||
|
static const char* vec3Names[];
|
||||||
|
static const char* vec4Names[];
|
||||||
|
|
||||||
|
SGMutex _mutex;
|
||||||
|
|
||||||
|
typedef boost::tuple<std::string, Uniform::Type, std::string> UniformCacheKey;
|
||||||
|
typedef boost::tuple<ref_ptr<Uniform>, SGPropertyChangeListener*> UniformCacheValue;
|
||||||
|
//std::map<UniformCacheKey,UniformCacheValue > uniformCache;
|
||||||
|
std::map<UniformCacheKey,ref_ptr<Uniform> > uniformCache;
|
||||||
|
|
||||||
|
typedef std::queue<DeferredPropertyListener*> DeferredListenerList;
|
||||||
|
DeferredListenerList deferredListenerList;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* UniformFactoryImpl::vec3Names[] = {"x", "y", "z"};
|
||||||
|
const char* UniformFactoryImpl::vec4Names[] = {"x", "y", "z", "w"};
|
||||||
|
|
||||||
|
ref_ptr<Uniform> UniformFactoryImpl::getUniform( Effect * effect,
|
||||||
|
const string & name,
|
||||||
|
Uniform::Type uniformType,
|
||||||
|
SGConstPropertyNode_ptr valProp,
|
||||||
|
const SGReaderWriterOptions* options )
|
||||||
|
{
|
||||||
|
SGGuard<SGMutex> scopeLock(_mutex);
|
||||||
|
std::string val = "0";
|
||||||
|
|
||||||
|
if (valProp->nChildren() == 0) {
|
||||||
|
// Completely static value
|
||||||
|
val = valProp->getStringValue();
|
||||||
|
} else {
|
||||||
|
// Value references <parameters> section of Effect
|
||||||
|
const SGPropertyNode* prop = getEffectPropertyNode(effect, valProp);
|
||||||
|
|
||||||
|
if (prop) {
|
||||||
|
if (prop->nChildren() == 0) {
|
||||||
|
// Static value in parameters section
|
||||||
|
val = prop->getStringValue();
|
||||||
|
} else {
|
||||||
|
// Dynamic property value in parameters section
|
||||||
|
val = getGlobalProperty(prop, options);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SG_LOG(SG_GL,SG_DEBUG,"Invalid parameter " << valProp->getName() << " for uniform " << name << " in Effect ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UniformCacheKey key = boost::make_tuple(name, uniformType, val);
|
||||||
|
//UniformCacheValue value = uniformCache[key];
|
||||||
|
//ref_ptr<Uniform> uniform = value.get_head();
|
||||||
|
ref_ptr<Uniform> uniform = uniformCache[key];
|
||||||
|
|
||||||
|
if (uniform.valid()) {
|
||||||
|
// We've got a hit to cache - simply return it
|
||||||
|
return uniform;
|
||||||
|
}
|
||||||
|
|
||||||
|
SG_LOG(SG_GL,SG_DEBUG,"new uniform " << name << " value " << uniformCache.size());
|
||||||
|
uniformCache[key] = uniform = new Uniform;
|
||||||
|
DeferredPropertyListener* updater = 0;
|
||||||
|
|
||||||
|
uniform->setName(name);
|
||||||
|
uniform->setType(uniformType);
|
||||||
|
switch (uniformType) {
|
||||||
|
case Uniform::BOOL:
|
||||||
|
updater = initFromParameters(effect, valProp, uniform.get(),
|
||||||
|
static_cast<bool (Uniform::*)(bool)>(&Uniform::set),
|
||||||
|
options);
|
||||||
|
break;
|
||||||
|
case Uniform::FLOAT:
|
||||||
|
updater = initFromParameters(effect, valProp, uniform.get(),
|
||||||
|
static_cast<bool (Uniform::*)(float)>(&Uniform::set),
|
||||||
|
options);
|
||||||
|
break;
|
||||||
|
case Uniform::FLOAT_VEC3:
|
||||||
|
updater = initFromParameters(effect, valProp, uniform.get(),
|
||||||
|
static_cast<bool (Uniform::*)(const Vec3&)>(&Uniform::set),
|
||||||
|
vec3Names, options);
|
||||||
|
break;
|
||||||
|
case Uniform::FLOAT_VEC4:
|
||||||
|
updater = initFromParameters(effect, valProp, uniform.get(),
|
||||||
|
static_cast<bool (Uniform::*)(const Vec4&)>(&Uniform::set),
|
||||||
|
vec4Names, options);
|
||||||
|
break;
|
||||||
|
case Uniform::INT:
|
||||||
|
case Uniform::SAMPLER_1D:
|
||||||
|
case Uniform::SAMPLER_2D:
|
||||||
|
case Uniform::SAMPLER_3D:
|
||||||
|
case Uniform::SAMPLER_1D_SHADOW:
|
||||||
|
case Uniform::SAMPLER_2D_SHADOW:
|
||||||
|
case Uniform::SAMPLER_CUBE:
|
||||||
|
updater = initFromParameters(effect, valProp, uniform.get(),
|
||||||
|
static_cast<bool (Uniform::*)(int)>(&Uniform::set),
|
||||||
|
options);
|
||||||
|
break;
|
||||||
|
default: // avoid compiler warning
|
||||||
|
SG_LOG(SG_ALL,SG_ALERT,"UNKNOWN Uniform type '" << uniformType << "'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
addListener(updater);
|
||||||
|
return uniform;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UniformFactoryImpl::addListener(DeferredPropertyListener* listener)
|
||||||
|
{
|
||||||
|
if (listener != 0) {
|
||||||
|
// Uniform requires a property listener. Add it to the list to be
|
||||||
|
// created when the main thread gets to it.
|
||||||
|
deferredListenerList.push(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UniformFactoryImpl::updateListeners( SGPropertyNode* propRoot )
|
||||||
|
{
|
||||||
|
SGGuard<SGMutex> scopeLock(_mutex);
|
||||||
|
|
||||||
|
if (deferredListenerList.empty()) return;
|
||||||
|
|
||||||
|
SG_LOG(SG_GL,SG_DEBUG,"Adding " << deferredListenerList.size() << " listeners for effects.");
|
||||||
|
|
||||||
|
// Instantiate all queued listeners
|
||||||
|
while (! deferredListenerList.empty()) {
|
||||||
|
DeferredPropertyListener* listener = deferredListenerList.front();
|
||||||
|
listener->activate(propRoot);
|
||||||
|
deferredListenerList.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Singleton<UniformFactoryImpl> UniformFactory;
|
||||||
|
|
||||||
|
|
||||||
Effect::Effect()
|
Effect::Effect()
|
||||||
: _cache(0), _isRealized(false)
|
: _cache(0), _isRealized(false)
|
||||||
{
|
{
|
||||||
@@ -104,6 +248,8 @@ Effect::Effect(const Effect& rhs, const CopyOp& copyop)
|
|||||||
techniques.push_back(static_cast<Technique*>(copyop(itr->get())));
|
techniques.push_back(static_cast<Technique*>(copyop(itr->get())));
|
||||||
|
|
||||||
generator = rhs.generator;
|
generator = rhs.generator;
|
||||||
|
_name = rhs._name;
|
||||||
|
_name += " clone";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume that the last technique is always valid.
|
// Assume that the last technique is always valid.
|
||||||
@@ -173,10 +319,6 @@ void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default names for vector property components
|
|
||||||
const char* vec3Names[] = {"x", "y", "z"};
|
|
||||||
const char* vec4Names[] = {"x", "y", "z", "w"};
|
|
||||||
|
|
||||||
osg::Vec4f getColor(const SGPropertyNode* prop)
|
osg::Vec4f getColor(const SGPropertyNode* prop)
|
||||||
{
|
{
|
||||||
if (prop->nChildren() == 0) {
|
if (prop->nChildren() == 0) {
|
||||||
@@ -898,10 +1040,10 @@ struct UniformBuilder :public PassAttributeBuilder
|
|||||||
}
|
}
|
||||||
if (!isAttributeActive(effect, prop))
|
if (!isAttributeActive(effect, prop))
|
||||||
return;
|
return;
|
||||||
const SGPropertyNode* nameProp = prop->getChild("name");
|
SGConstPropertyNode_ptr nameProp = prop->getChild("name");
|
||||||
const SGPropertyNode* typeProp = prop->getChild("type");
|
SGConstPropertyNode_ptr typeProp = prop->getChild("type");
|
||||||
const SGPropertyNode* positionedProp = prop->getChild("positioned");
|
SGConstPropertyNode_ptr positionedProp = prop->getChild("positioned");
|
||||||
const SGPropertyNode* valProp = prop->getChild("value");
|
SGConstPropertyNode_ptr valProp = prop->getChild("value");
|
||||||
string name;
|
string name;
|
||||||
Uniform::Type uniformType = Uniform::FLOAT;
|
Uniform::Type uniformType = Uniform::FLOAT;
|
||||||
if (nameProp) {
|
if (nameProp) {
|
||||||
@@ -941,44 +1083,9 @@ struct UniformBuilder :public PassAttributeBuilder
|
|||||||
} else {
|
} else {
|
||||||
findAttr(uniformTypes, typeProp, uniformType);
|
findAttr(uniformTypes, typeProp, uniformType);
|
||||||
}
|
}
|
||||||
ref_ptr<Uniform> uniform = new Uniform;
|
ref_ptr<Uniform> uniform = UniformFactory::instance()->
|
||||||
uniform->setName(name);
|
getUniform( effect, name, uniformType, valProp, options );
|
||||||
uniform->setType(uniformType);
|
|
||||||
switch (uniformType) {
|
|
||||||
case Uniform::BOOL:
|
|
||||||
initFromParameters(effect, valProp, uniform.get(),
|
|
||||||
static_cast<bool (Uniform::*)(bool)>(&Uniform::set),
|
|
||||||
options);
|
|
||||||
break;
|
|
||||||
case Uniform::FLOAT:
|
|
||||||
initFromParameters(effect, valProp, uniform.get(),
|
|
||||||
static_cast<bool (Uniform::*)(float)>(&Uniform::set),
|
|
||||||
options);
|
|
||||||
break;
|
|
||||||
case Uniform::FLOAT_VEC3:
|
|
||||||
initFromParameters(effect, valProp, uniform.get(),
|
|
||||||
static_cast<bool (Uniform::*)(const Vec3&)>(&Uniform::set),
|
|
||||||
vec3Names, options);
|
|
||||||
break;
|
|
||||||
case Uniform::FLOAT_VEC4:
|
|
||||||
initFromParameters(effect, valProp, uniform.get(),
|
|
||||||
static_cast<bool (Uniform::*)(const Vec4&)>(&Uniform::set),
|
|
||||||
vec4Names, options);
|
|
||||||
break;
|
|
||||||
case Uniform::INT:
|
|
||||||
case Uniform::SAMPLER_1D:
|
|
||||||
case Uniform::SAMPLER_2D:
|
|
||||||
case Uniform::SAMPLER_3D:
|
|
||||||
case Uniform::SAMPLER_1D_SHADOW:
|
|
||||||
case Uniform::SAMPLER_2D_SHADOW:
|
|
||||||
case Uniform::SAMPLER_CUBE:
|
|
||||||
initFromParameters(effect, valProp, uniform.get(),
|
|
||||||
static_cast<bool (Uniform::*)(int)>(&Uniform::set),
|
|
||||||
options);
|
|
||||||
break;
|
|
||||||
default: // avoid compiler warning
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// optimize common uniforms
|
// optimize common uniforms
|
||||||
if (uniformType == Uniform::SAMPLER_2D || uniformType == Uniform::INT)
|
if (uniformType == Uniform::SAMPLER_2D || uniformType == Uniform::INT)
|
||||||
{
|
{
|
||||||
@@ -1345,6 +1452,10 @@ void Effect::InitializeCallback::doUpdate(osg::Node* node, osg::NodeVisitor* nv)
|
|||||||
if (!effect)
|
if (!effect)
|
||||||
return;
|
return;
|
||||||
SGPropertyNode* root = getPropertyRoot();
|
SGPropertyNode* root = getPropertyRoot();
|
||||||
|
|
||||||
|
// Initialize all queued listeners
|
||||||
|
UniformFactory::instance()->updateListeners(root);
|
||||||
|
|
||||||
for (vector<SGSharedPtr<Updater> >::iterator itr = effect->_extraData.begin(),
|
for (vector<SGSharedPtr<Updater> >::iterator itr = effect->_extraData.begin(),
|
||||||
end = effect->_extraData.end();
|
end = effect->_extraData.end();
|
||||||
itr != end;
|
itr != end;
|
||||||
@@ -1356,28 +1467,6 @@ void Effect::InitializeCallback::doUpdate(osg::Node* node, osg::NodeVisitor* nv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::UpdateCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
|
||||||
{
|
|
||||||
EffectGeode* eg = dynamic_cast<EffectGeode*>(node);
|
|
||||||
if (!eg)
|
|
||||||
return;
|
|
||||||
Effect* effect = eg->getEffect();
|
|
||||||
if (!effect)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (vector<SGSharedPtr<Updater> >::iterator itr = effect->_extraData.begin(),
|
|
||||||
end = effect->_extraData.end();
|
|
||||||
itr != end;
|
|
||||||
++itr) {
|
|
||||||
PropertyPoller * poller
|
|
||||||
= dynamic_cast<PropertyPoller*>(itr->ptr());
|
|
||||||
if (poller)
|
|
||||||
poller->pollProperties(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
traverse(node, nv);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Effect::Key::EqualTo::operator()(const Effect::Key& lhs,
|
bool Effect::Key::EqualTo::operator()(const Effect::Key& lhs,
|
||||||
const Effect::Key& rhs) const
|
const Effect::Key& rhs) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -73,17 +73,13 @@ private:
|
|||||||
bool _initialized;
|
bool _initialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PropertyPoller
|
class DeferredPropertyListener {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
PropertyPoller() {};
|
virtual void activate(SGPropertyNode* propRoot) {};
|
||||||
virtual ~PropertyPoller() {};
|
virtual ~DeferredPropertyListener() {};
|
||||||
virtual void pollProperties(Effect* effect)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Effect : public osg::Object
|
class Effect : public osg::Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -132,17 +128,6 @@ public:
|
|||||||
{
|
{
|
||||||
void doUpdate(osg::Node* node, osg::NodeVisitor* nv);
|
void doUpdate(osg::Node* node, osg::NodeVisitor* nv);
|
||||||
};
|
};
|
||||||
friend struct UpdateCallback;
|
|
||||||
struct UpdateCallback : public osg::NodeCallback
|
|
||||||
{
|
|
||||||
UpdateCallback() {}
|
|
||||||
UpdateCallback(const UpdateCallback& nc, const osg::CopyOp& copyop)
|
|
||||||
: osg::NodeCallback(nc, copyop)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
|
|
||||||
};
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<SGSharedPtr<Updater> > _extraData;
|
std::vector<SGSharedPtr<Updater> > _extraData;
|
||||||
~Effect();
|
~Effect();
|
||||||
|
|||||||
@@ -495,44 +495,42 @@ make_OSGFunctor(Obj* obj, void (Obj::*const func)(const OSGParam&))
|
|||||||
|
|
||||||
template<typename OSGParamType, typename ObjType, typename F>
|
template<typename OSGParamType, typename ObjType, typename F>
|
||||||
class ScalarChangeListener
|
class ScalarChangeListener
|
||||||
: public SGPropertyChangeListener, public InitializeWhenAdded,
|
: public SGPropertyChangeListener, public DeferredPropertyListener
|
||||||
public PropertyPoller,
|
|
||||||
public Effect::Updater
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScalarChangeListener(ObjType* obj, const F& setter,
|
ScalarChangeListener(ObjType* obj, const F& setter,
|
||||||
const std::string& propName)
|
const std::string& propName)
|
||||||
: _obj(obj), _setter(setter), _propName(propName)
|
: _obj(obj), _setter(setter)
|
||||||
{
|
{
|
||||||
|
_propName = new std::string(propName);
|
||||||
|
SG_LOG(SG_GL,SG_DEBUG,"Creating ScalarChangeListener for " << *_propName );
|
||||||
}
|
}
|
||||||
virtual ~ScalarChangeListener()
|
virtual ~ScalarChangeListener()
|
||||||
{
|
{
|
||||||
|
delete _propName;
|
||||||
|
_propName = 0;
|
||||||
}
|
}
|
||||||
void valueChanged(SGPropertyNode* node)
|
void valueChanged(SGPropertyNode* node)
|
||||||
{
|
{
|
||||||
_setter(_obj.get(), node->getValue<OSGParamType>());
|
_setter(_obj.get(), node->getValue<OSGParamType>());
|
||||||
}
|
}
|
||||||
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
|
void activate(SGPropertyNode* propRoot)
|
||||||
{
|
{
|
||||||
_listenProp = makeNode(propRoot, _propName);
|
SG_LOG(SG_GL,SG_DEBUG,"Adding change listener to " << *_propName );
|
||||||
// if ( _listenProp.valid() )
|
SGPropertyNode* listenProp = makeNode(propRoot, *_propName);
|
||||||
// _listenProp->addChangeListener(this, true);
|
delete _propName;
|
||||||
}
|
_propName = 0;
|
||||||
void pollProperties(Effect* effect)
|
if (listenProp)
|
||||||
{
|
listenProp->addChangeListener(this, true);
|
||||||
if( false == _listenProp.valid() ) return;
|
|
||||||
valueChanged(_listenProp);
|
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
SGPropertyNode_ptr _listenProp;
|
|
||||||
osg::ref_ptr<ObjType> _obj;
|
osg::ref_ptr<ObjType> _obj;
|
||||||
F _setter;
|
F _setter;
|
||||||
std::string _propName;
|
std::string* _propName;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename Func>
|
template<typename T, typename Func>
|
||||||
class EffectExtendedPropListener : public InitializeWhenAdded,
|
class EffectExtendedPropListener : public DeferredPropertyListener
|
||||||
public Effect::Updater
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<typename Itr>
|
template<typename Itr>
|
||||||
@@ -551,7 +549,7 @@ public:
|
|||||||
delete _propName;
|
delete _propName;
|
||||||
delete _childNames;
|
delete _childNames;
|
||||||
}
|
}
|
||||||
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
|
void activate(SGPropertyNode* propRoot)
|
||||||
{
|
{
|
||||||
SGPropertyNode* parent = 0;
|
SGPropertyNode* parent = 0;
|
||||||
if (_propName)
|
if (_propName)
|
||||||
@@ -575,7 +573,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename Func, typename Itr>
|
template<typename T, typename Func, typename Itr>
|
||||||
Effect::Updater*
|
DeferredPropertyListener*
|
||||||
new_EEPropListener(const Func& func, const std::string* propName,
|
new_EEPropListener(const Func& func, const std::string* propName,
|
||||||
const Itr& namesBegin, const Itr& namesEnd)
|
const Itr& namesBegin, const Itr& namesEnd)
|
||||||
{
|
{
|
||||||
@@ -609,32 +607,33 @@ inline void setDynamicVariance(osg::Object* obj)
|
|||||||
* used.
|
* used.
|
||||||
*/
|
*/
|
||||||
template<typename OSGParamType, typename ObjType, typename F>
|
template<typename OSGParamType, typename ObjType, typename F>
|
||||||
void
|
DeferredPropertyListener*
|
||||||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
||||||
const F& setter, const SGReaderWriterOptions* options)
|
const F& setter, const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
|
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
|
||||||
|
ScalarChangeListener<OSGParamType, ObjType, F>* listener = 0;
|
||||||
if (!valProp)
|
if (!valProp)
|
||||||
return;
|
return listener;
|
||||||
if (valProp->nChildren() == 0) {
|
if (valProp->nChildren() == 0) {
|
||||||
setter(obj, valProp->getValue<OSGParamType>());
|
setter(obj, valProp->getValue<OSGParamType>());
|
||||||
} else {
|
} else {
|
||||||
setDynamicVariance(obj);
|
setDynamicVariance(obj);
|
||||||
std::string propName = getGlobalProperty(valProp, options);
|
std::string propName = getGlobalProperty(valProp, options);
|
||||||
ScalarChangeListener<OSGParamType, ObjType, F>* listener
|
listener
|
||||||
= new ScalarChangeListener<OSGParamType, ObjType, F>(obj, setter,
|
= new ScalarChangeListener<OSGParamType, ObjType, F>(obj, setter,
|
||||||
propName);
|
propName);
|
||||||
effect->addUpdater(listener);
|
|
||||||
}
|
}
|
||||||
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OSGParamType, typename ObjType, typename SetterReturn>
|
template<typename OSGParamType, typename ObjType, typename SetterReturn>
|
||||||
inline void
|
inline DeferredPropertyListener*
|
||||||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
||||||
SetterReturn (ObjType::*setter)(const OSGParamType),
|
SetterReturn (ObjType::*setter)(const OSGParamType),
|
||||||
const SGReaderWriterOptions* options)
|
const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
initFromParameters<OSGParamType>(effect, prop, obj,
|
return initFromParameters<OSGParamType>(effect, prop, obj,
|
||||||
boost::bind(setter, _1, _2), options);
|
boost::bind(setter, _1, _2), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,16 +658,17 @@ initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
|||||||
*/
|
*/
|
||||||
template<typename OSGParamType, typename ObjType, typename NameItrType,
|
template<typename OSGParamType, typename ObjType, typename NameItrType,
|
||||||
typename F>
|
typename F>
|
||||||
void
|
DeferredPropertyListener*
|
||||||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
||||||
const F& setter,
|
const F& setter,
|
||||||
NameItrType nameItr, const SGReaderWriterOptions* options)
|
NameItrType nameItr, const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
typedef typename Bridge<OSGParamType>::sg_type sg_type;
|
typedef typename Bridge<OSGParamType>::sg_type sg_type;
|
||||||
|
DeferredPropertyListener* listener = 0;
|
||||||
const int numComponents = props::NumComponents<sg_type>::num_components;
|
const int numComponents = props::NumComponents<sg_type>::num_components;
|
||||||
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
|
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
|
||||||
if (!valProp)
|
if (!valProp)
|
||||||
return;
|
return listener;
|
||||||
if (valProp->nChildren() == 0) { // Has <use>?
|
if (valProp->nChildren() == 0) { // Has <use>?
|
||||||
setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()));
|
setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()));
|
||||||
} else {
|
} else {
|
||||||
@@ -678,22 +678,22 @@ initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
|||||||
if (paramNames.empty())
|
if (paramNames.empty())
|
||||||
throw BuilderException();
|
throw BuilderException();
|
||||||
std::vector<std::string>::const_iterator pitr = paramNames.begin();
|
std::vector<std::string>::const_iterator pitr = paramNames.begin();
|
||||||
Effect::Updater* listener
|
listener
|
||||||
= new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType>
|
= new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType>
|
||||||
(obj, setter),
|
(obj, setter),
|
||||||
0, pitr, pitr + numComponents);
|
0, pitr, pitr + numComponents);
|
||||||
effect->addUpdater(listener);
|
|
||||||
}
|
}
|
||||||
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OSGParamType, typename ObjType, typename NameItrType,
|
template<typename OSGParamType, typename ObjType, typename NameItrType,
|
||||||
typename SetterReturn>
|
typename SetterReturn>
|
||||||
inline void
|
inline DeferredPropertyListener*
|
||||||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
|
||||||
SetterReturn (ObjType::*setter)(const OSGParamType&),
|
SetterReturn (ObjType::*setter)(const OSGParamType&),
|
||||||
NameItrType nameItr, const SGReaderWriterOptions* options)
|
NameItrType nameItr, const SGReaderWriterOptions* options)
|
||||||
{
|
{
|
||||||
initFromParameters<OSGParamType>(effect, prop, obj,
|
return initFromParameters<OSGParamType>(effect, prop, obj,
|
||||||
boost::bind(setter, _1, _2), nameItr,
|
boost::bind(setter, _1, _2), nameItr,
|
||||||
options);
|
options);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,9 +52,7 @@ void EffectGeode::setEffect(Effect* effect)
|
|||||||
_effect = effect;
|
_effect = effect;
|
||||||
if (!_effect)
|
if (!_effect)
|
||||||
return;
|
return;
|
||||||
//TODO: do we leak the callbacks or does the geode own pointer afterwards?
|
|
||||||
addUpdateCallback(new Effect::InitializeCallback);
|
addUpdateCallback(new Effect::InitializeCallback);
|
||||||
addUpdateCallback(new Effect::UpdateCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectGeode::resizeGLObjectBuffers(unsigned int maxSize)
|
void EffectGeode::resizeGLObjectBuffers(unsigned int maxSize)
|
||||||
|
|||||||
@@ -858,10 +858,14 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
const SGPropertyNode* colorNode = envProp->getChild("constant-color");
|
const SGPropertyNode* colorNode = envProp->getChild("constant-color");
|
||||||
if (colorNode)
|
if (colorNode) {
|
||||||
initFromParameters(effect, colorNode, result,
|
DeferredPropertyListener* listener = initFromParameters(effect, colorNode, result,
|
||||||
&TexEnvCombine::setConstantColor, colorFields,
|
&TexEnvCombine::setConstantColor, colorFields,
|
||||||
options);
|
options);
|
||||||
|
if (listener != 0) {
|
||||||
|
SG_LOG(SG_ALL,SG_ALERT,"Texture with property defined parameter");
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user