]> git.mxchange.org Git - simgear.git/blob - simgear/scene/material/Effect.hxx
Random buildings - initial commit.
[simgear.git] / simgear / scene / material / Effect.hxx
1 // Copyright (C) 2008 - 2009  Tim Moore timoore@redhat.com
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16
17 #ifndef SIMGEAR_EFFECT_HXX
18 #define SIMGEAR_EFFECT_HXX 1
19
20 #include <vector>
21 #include <string>
22 #include <boost/tr1/unordered_map.hpp>
23
24 #include <boost/functional/hash.hpp>
25
26 #include <osg/Object>
27 #include <osg/observer_ptr>
28 #include <osgDB/ReaderWriter>
29
30 #include <simgear/props/props.hxx>
31 #include <simgear/scene/util/UpdateOnceCallback.hxx>
32
33 namespace osg
34 {
35 class Drawable;
36 class StateSet;
37 class RenderInfo;
38 }
39
40 namespace osgUtil
41 {
42 class CullVisitor;
43 }
44
45 namespace simgear
46 {
47 class Technique;
48 class Effect;
49 class SGReaderWriterOptions;
50
51 /**
52  * Object to be initialized at some point after an effect -- and its
53  * containing effect geode -- are hooked into the scene graph. Some
54  * things, like manipulations of the global property tree, are are
55  * only safe in the update process.
56  */
57
58 class InitializeWhenAdded
59 {
60 public:
61     InitializeWhenAdded() : _initialized(false) {};
62     virtual ~InitializeWhenAdded() {};
63     void initOnAdd(Effect* effect, SGPropertyNode* propRoot)
64     {
65         if (!_initialized) {
66             initOnAddImpl(effect, propRoot);
67             _initialized = true;
68         }
69     }
70     bool getInitialized() const { return _initialized; }
71 private:
72     virtual void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) = 0;
73     bool _initialized;
74 };
75
76 class Effect : public osg::Object
77 {
78 public:
79     META_Object(simgear,Effect)
80     Effect();
81     Effect(const Effect& rhs,
82            const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
83     osg::StateSet* getDefaultStateSet();
84
85     enum Buffer
86     {
87         DEPTH_BUFFER,
88         NORMAL_BUFFER,
89         DIFFUSE_BUFFER,
90         SPEC_EMIS_BUFFER,
91         LIGHTING_BUFFER,
92         MIDDLE_BLOOM_BUFFER,
93         BLOOM_BUFFER,
94         AO_BUFFER,
95         SHADOW_BUFFER
96     };
97
98     // Define what needs to be generated for this effect
99     enum Generator
100     {
101         NORMAL,
102         TANGENT,
103         BINORMAL
104     };
105     void setGenerator(Generator what, int where) { generator[what] = where; }
106     int getGenerator(Generator what) const;  // Returns -1 if generator should not be used
107     std::map<Generator, int> generator;  // What is generated into which attribute location
108
109     std::vector<osg::ref_ptr<Technique> > techniques;
110     SGPropertyNode_ptr root;
111     // Pointer to the parameters node, if it exists
112     SGPropertyNode_ptr parametersProp;
113     Technique* chooseTechnique(osg::RenderInfo* renderInfo);
114     virtual void resizeGLObjectBuffers(unsigned int maxSize);
115     virtual void releaseGLObjects(osg::State* state = 0) const;
116     /**
117      * Build the techniques from the effect properties.
118      */
119     bool realizeTechniques(const SGReaderWriterOptions* options = 0);
120     /**
121      * Updaters that should be derefed when the effect is
122      * deleted. Updaters arrange to be run by listening on properties
123      * or something.
124      */
125     struct Updater : public virtual SGReferenced
126     {
127         virtual ~Updater() {}
128     };
129     void addUpdater(Updater* data) { _extraData.push_back(data); }
130     // Callback that is added to the effect geode to initialize the
131     // effect.
132     friend struct InitializeCallback;
133     struct InitializeCallback : public UpdateOnceCallback
134     {
135         void doUpdate(osg::Node* node, osg::NodeVisitor* nv);
136     };
137 protected:
138     std::vector<SGSharedPtr<Updater> > _extraData;
139     ~Effect();
140     // Support for a cache of effects that inherit from this one, so
141     // Effect objects with the same parameters and techniques can be
142     // shared.
143     struct Key
144     {
145         Key() {}
146         Key(SGPropertyNode* unmerged_, const osgDB::FilePathList& paths_)
147             : unmerged(unmerged_), paths(paths_)
148         {
149         }
150         Key& operator=(const Key& rhs)
151         {
152             unmerged = rhs.unmerged;
153             paths = rhs.paths;
154             return *this;
155         }
156         SGPropertyNode_ptr unmerged;
157         osgDB::FilePathList paths;
158         struct EqualTo
159         {
160             bool operator()(const Key& lhs, const Key& rhs) const;
161         };
162     };
163     typedef std::tr1::unordered_map<Key, osg::observer_ptr<Effect>,
164                                     boost::hash<Key>, Key::EqualTo> Cache;
165     Cache* getCache()
166     {
167         if (!_cache)
168             _cache = new Cache;
169         return _cache;
170     }
171     Cache* _cache;
172     friend size_t hash_value(const Key& key);
173     friend Effect* makeEffect(SGPropertyNode* prop, bool realizeTechniques,
174                               const SGReaderWriterOptions* options);
175     bool _isRealized;
176 };
177 // Automatic support for boost hash function
178 size_t hash_value(const Effect::Key&);
179
180
181 Effect* makeEffect(const std::string& name,
182                    bool realizeTechniques,
183                    const SGReaderWriterOptions* options = 0);
184
185 Effect* makeEffect(SGPropertyNode* prop,
186                    bool realizeTechniques,
187                    const SGReaderWriterOptions* options = 0);
188
189 bool makeParametersFromStateSet(SGPropertyNode* paramRoot,
190                                 const osg::StateSet* ss);
191
192 namespace effect
193 {
194 /**
195  * The function that implements effect property tree inheritance.
196  */
197 void mergePropertyTrees(SGPropertyNode* resultNode,
198                         const SGPropertyNode* left,
199                         const SGPropertyNode* right);
200 }
201 }
202 #endif