]> git.mxchange.org Git - simgear.git/blob - simgear/scene/material/Effect.hxx
Fix #1783: repeated error message on console
[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 class DeferredPropertyListener {
58 public:
59     virtual void activate(SGPropertyNode* propRoot) {};
60     virtual ~DeferredPropertyListener() {};
61 };
62
63 class Effect : public osg::Object
64 {
65 public:
66     META_Object(simgear,Effect)
67     Effect();
68     Effect(const Effect& rhs,
69            const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
70     osg::StateSet* getDefaultStateSet();
71
72     // Define what needs to be generated for this effect
73     enum Generator
74     {
75         NORMAL,
76         TANGENT,
77         BINORMAL
78     };
79     void setGenerator(Generator what, int where) { generator[what] = where; }
80     int getGenerator(Generator what) const;  // Returns -1 if generator should not be used
81     std::map<Generator, int> generator;  // What is generated into which attribute location
82
83     std::vector<osg::ref_ptr<Technique> > techniques;
84     SGPropertyNode_ptr root;
85     // Pointer to the parameters node, if it exists
86     SGPropertyNode_ptr parametersProp;
87     Technique* chooseTechnique(osg::RenderInfo* renderInfo);
88     virtual void resizeGLObjectBuffers(unsigned int maxSize);
89     virtual void releaseGLObjects(osg::State* state = 0) const;
90     /**
91      * Build the techniques from the effect properties.
92      */
93     bool realizeTechniques(const SGReaderWriterOptions* options = 0);
94     void addDeferredPropertyListener(DeferredPropertyListener* listener);
95     // Callback that is added to the effect geode to initialize the
96     // effect.
97     friend struct InitializeCallback;
98     struct InitializeCallback : public UpdateOnceCallback
99     {
100         void doUpdate(osg::Node* node, osg::NodeVisitor* nv);
101     };
102
103     std::string getName(){return _name;}
104     void setName(std::string name){_name = name;}
105 protected:
106     ~Effect();
107     // Support for a cache of effects that inherit from this one, so
108     // Effect objects with the same parameters and techniques can be
109     // shared.
110     struct Key
111     {
112         Key() {}
113         Key(SGPropertyNode* unmerged_, const osgDB::FilePathList& paths_)
114             : unmerged(unmerged_), paths(paths_)
115         {
116         }
117         Key& operator=(const Key& rhs)
118         {
119             unmerged = rhs.unmerged;
120             paths = rhs.paths;
121             return *this;
122         }
123         SGPropertyNode_ptr unmerged;
124         osgDB::FilePathList paths;
125         struct EqualTo
126         {
127             bool operator()(const Key& lhs, const Key& rhs) const;
128         };
129     };
130     typedef std::tr1::unordered_map<Key, osg::observer_ptr<Effect>,
131                                     boost::hash<Key>, Key::EqualTo> Cache;
132     Cache* getCache()
133     {
134         if (!_cache)
135             _cache = new Cache;
136         return _cache;
137     }
138     Cache* _cache;
139     friend size_t hash_value(const Key& key);
140     friend Effect* makeEffect(SGPropertyNode* prop, bool realizeTechniques,
141                               const SGReaderWriterOptions* options);
142     bool _isRealized;
143     std::string _name;
144 };
145 // Automatic support for boost hash function
146 size_t hash_value(const Effect::Key&);
147
148
149 Effect* makeEffect(const std::string& name,
150                    bool realizeTechniques,
151                    const SGReaderWriterOptions* options);
152
153 Effect* makeEffect(SGPropertyNode* prop,
154                    bool realizeTechniques,
155                    const SGReaderWriterOptions* options);
156
157 bool makeParametersFromStateSet(SGPropertyNode* paramRoot,
158                                 const osg::StateSet* ss);
159
160 void clearEffectCache();
161
162 namespace effect
163 {
164 /**
165  * The function that implements effect property tree inheritance.
166  */
167 void mergePropertyTrees(SGPropertyNode* resultNode,
168                         const SGPropertyNode* left,
169                         const SGPropertyNode* right);
170 }
171 }
172 #endif