00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef SIMGEAR_EFFECT_HXX
00018 #define SIMGEAR_EFFECT_HXX 1
00019
00020 #include <vector>
00021 #include <string>
00022 #include <boost/tr1/unordered_map.hpp>
00023
00024 #include <boost/functional/hash.hpp>
00025
00026 #include <osg/Object>
00027 #include <osgDB/ReaderWriter>
00028
00029 #include <simgear/props/props.hxx>
00030 #include <simgear/scene/util/UpdateOnceCallback.hxx>
00031
00032 namespace osg
00033 {
00034 class Drawable;
00035 class StateSet;
00036 class RenderInfo;
00037 }
00038
00039 namespace osgUtil
00040 {
00041 class CullVisitor;
00042 }
00043
00044 namespace simgear
00045 {
00046 class Technique;
00047 class Effect;
00048
00056 class InitializeWhenAdded
00057 {
00058 public:
00059 InitializeWhenAdded() : _initialized(false) {};
00060 virtual ~InitializeWhenAdded() {};
00061 void initOnAdd(Effect* effect, SGPropertyNode* propRoot)
00062 {
00063 if (!_initialized) {
00064 initOnAddImpl(effect, propRoot);
00065 _initialized = true;
00066 }
00067 }
00068 bool getInitialized() const { return _initialized; }
00069 private:
00070 virtual void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) = 0;
00071 bool _initialized;
00072 };
00073
00074 class Effect : public osg::Object
00075 {
00076 public:
00077 META_Object(simgear,Effect)
00078 Effect();
00079 Effect(const Effect& rhs,
00080 const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
00081 osg::StateSet* getDefaultStateSet();
00082 std::vector<osg::ref_ptr<Technique> > techniques;
00083 SGPropertyNode_ptr root;
00084
00085 SGPropertyNode_ptr parametersProp;
00086 Technique* chooseTechnique(osg::RenderInfo* renderInfo);
00087 virtual void resizeGLObjectBuffers(unsigned int maxSize);
00088 virtual void releaseGLObjects(osg::State* state = 0) const;
00092 bool realizeTechniques(const osgDB::ReaderWriter::Options* options = 0);
00098 struct Updater : public virtual SGReferenced
00099 {
00100 virtual ~Updater() {}
00101 };
00102 void addUpdater(Updater* data) { _extraData.push_back(data); }
00103
00104
00105 friend struct InitializeCallback;
00106 struct InitializeCallback : public UpdateOnceCallback
00107 {
00108 void doUpdate(osg::Node* node, osg::NodeVisitor* nv);
00109 };
00110 protected:
00111 std::vector<SGSharedPtr<Updater> > _extraData;
00112 ~Effect();
00113
00114
00115
00116 struct Key
00117 {
00118 Key() {}
00119 Key(SGPropertyNode* unmerged_, const osgDB::FilePathList& paths_)
00120 : unmerged(unmerged_), paths(paths_)
00121 {
00122 }
00123 Key& operator=(const Key& rhs)
00124 {
00125 unmerged = rhs.unmerged;
00126 paths = rhs.paths;
00127 return *this;
00128 }
00129 SGPropertyNode_ptr unmerged;
00130 osgDB::FilePathList paths;
00131 struct EqualTo
00132 {
00133 bool operator()(const Key& lhs, const Key& rhs) const;
00134 };
00135 };
00136 typedef std::tr1::unordered_map<Key, osg::ref_ptr<Effect>,
00137 boost::hash<Key>, Key::EqualTo> Cache;
00138 Cache* getCache()
00139 {
00140 if (!_cache)
00141 _cache = new Cache;
00142 return _cache;
00143 }
00144 Cache* _cache;
00145 friend size_t hash_value(const Key& key);
00146 friend Effect* makeEffect(SGPropertyNode* prop, bool realizeTechniques,
00147 const osgDB::ReaderWriter::Options* options);
00148 bool _isRealized;
00149 };
00150
00151 size_t hash_value(const Effect::Key&);
00152
00153
00154 Effect* makeEffect(const std::string& name,
00155 bool realizeTechniques,
00156 const osgDB::ReaderWriter::Options* options = 0);
00157
00158 Effect* makeEffect(SGPropertyNode* prop,
00159 bool realizeTechniques,
00160 const osgDB::ReaderWriter::Options* options = 0);
00161
00162 bool makeParametersFromStateSet(SGPropertyNode* paramRoot,
00163 const osg::StateSet* ss);
00164
00165 namespace effect
00166 {
00170 void mergePropertyTrees(SGPropertyNode* resultNode,
00171 const SGPropertyNode* left,
00172 const SGPropertyNode* right);
00173 }
00174 }
00175 #endif