Visualization Library 2.1.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
ShaderNode.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef ShaderNode_INCLUDE_ONCE
33 #define ShaderNode_INCLUDE_ONCE
34 
35 #include <vlGraphics/Shader.hpp>
36 #include <vlCore/vlnamespace.hpp>
37 #include <vector>
38 #include <map>
39 
40 namespace vl
41 {
45  class ShaderNode: public Object
46  {
48 
49  public:
51  struct EnableInfo
52  {
53  EnableInfo(EEnable en=EN_UnknownEnable, bool on=false, EInheritance inheritance=IN_Propagate): mEnable(en), mOn(on), mInheritance(inheritance) {}
54 
56  bool mOn;
58  };
61  {
62  RenderStateInfo(EInheritance inheritance=IN_Propagate, RenderState* rs=NULL, int index=-1): mInheritance(inheritance), mRenderState(rs), mIndex(index) {}
63 
66  int mIndex;
67  };
69  struct UniformInfo
70  {
71  UniformInfo(Uniform* unif=NULL, EInheritance inheritance=IN_Propagate): mUniform(unif), mInheritance(inheritance) {}
72 
75  };
76  // --- --- ---
77  typedef std::map< ERenderState, RenderStateInfo > RenderStatesMap;
78  typedef std::map< EEnable, EnableInfo > EnablesMap;
79  typedef std::map< std::string, UniformInfo > UniformsMap;
80 
81  public:
83 
84  // shader-related functions
85 
87 
88  const Shader* shader() const { return mShader.get(); }
89 
90  Shader* shader() { return mShader.get(); }
91 
92  // tree-related functions
93 
94  void addChild(ShaderNode* node)
95  {
96  VL_CHECK(node->parent() == NULL);
97  mNodes.push_back(node);
98  node->mParent = this;
99  }
100 
101  void eraseChild(ShaderNode* node)
102  {
103  VL_CHECK(node->parent() == this);
104  for(unsigned i=0; i<childrenCount(); ++i)
105  if (child(i) == node)
106  {
107  mNodes.erase(mNodes.begin()+i);
108  node->mParent = NULL;
109  return;
110  }
111  }
112 
113  void eraseChild(unsigned index)
114  {
115  VL_CHECK(index<childrenCount())
116  mNodes[index]->mParent = NULL;
117  mNodes.erase(mNodes.begin()+index);
118  }
119 
120  void eraseChildren(unsigned start, unsigned count)
121  {
122  VL_CHECK(start < childrenCount())
123  VL_CHECK(start+count-1 < childrenCount())
124  for(unsigned i=start; i<start+count; ++i)
125  mNodes[i]->mParent = NULL;
126  mNodes.erase(mNodes.begin()+start, mNodes.begin()+start+count);
127  }
128 
129  int findChild(const ShaderNode* node) const
130  {
131  for(unsigned i=0; i<childrenCount(); ++i)
132  if(child(i) == node)
133  return i;
134  return -1;
135  }
136 
137  size_t childrenCount() const { return mNodes.size(); }
138 
139  ShaderNode* child(unsigned i) { return mNodes[i].get(); }
140 
141  const ShaderNode* child(unsigned i) const { return mNodes[i].get(); }
142 
143  ShaderNode* parent() { return mParent; }
144 
145  const ShaderNode* parent() const { return mParent; }
146 
147  // inheritance-related functions
148 
150  {
151  inherit(parent());
152  for(unsigned i=0;i <childrenCount(); ++i)
153  child(i)->updateHierarchy();
154  }
155 
157  {
158  // init
159  mRenderStates_Final.clear();
160  mEnables_Final.clear();
161  mUniforms_Final.clear();
162 
163  // propagate
164  for(RenderStatesMap::const_iterator rs_it = mRenderStates.begin(); rs_it != mRenderStates.end(); ++rs_it)
165  mRenderStates_Final[rs_it->first] = rs_it->second;
166 
167  for(std::map< EEnable, EnableInfo>::const_iterator en_it = mEnables.begin(); en_it != mEnables.end(); ++en_it)
168  if(en_it->second.mOn)
169  mEnables_Final[en_it->first] = en_it->second;
170 
171  for(UniformsMap::const_iterator unif_it = mUniforms.begin(); unif_it != mUniforms.end(); ++unif_it)
172  mUniforms_Final[unif_it->first] = unif_it->second;
173 
174  // iterate parent final values
175 
176  if (parent)
177  {
178 
179  /* ALGORITHM:
180  *
181  * 1 - iterate over parent's values
182  * 2 - if it doesn't propagate -> end
183  * 3 - find current values
184  * 3a - if there is not -> insert parent's -> end
185  * 3b - if there is
186  * 3ba - if parent's do not overrides -> end
187  * 3bb - if child's do not overridden -> end
188  * 3bc - else -> use parent's
189  */
190 
191  // render states
192  for(RenderStatesMap::const_iterator par_it = parent->mRenderStates_Final.begin(); par_it != parent->mRenderStates_Final.end(); ++par_it)
193  {
194  if (!(par_it->second.mInheritance & IN_Propagate))
195  continue;
196  RenderStatesMap::const_iterator cur_it = mRenderStates_Final.find(par_it->first);
197  if (cur_it == mRenderStates_Final.end())
198  mRenderStates_Final[par_it->first] = par_it->second;
199  else
200  if (!(par_it->second.mInheritance & 0x02/*IN_Overrides*/) || (cur_it->second.mInheritance & IN_Sticky))
201  continue;
202  else
203  mRenderStates_Final[par_it->first] = par_it->second;
204  }
205 
206  // enables
207  for(EnablesMap::const_iterator par_it = parent->mEnables_Final.begin(); par_it != parent->mEnables_Final.end(); ++par_it)
208  {
209  if (!par_it->second.mOn)
210  continue;
211  if (!(par_it->second.mInheritance & IN_Propagate))
212  continue;
213  EnablesMap::const_iterator cur_it = mEnables_Final.find(par_it->first);
214  if (cur_it == mEnables_Final.end())
215  mEnables_Final[par_it->first] = par_it->second;
216  else
217  if (!(par_it->second.mInheritance & 0x02/*IN_Overrides*/) || (cur_it->second.mInheritance & IN_Sticky))
218  continue;
219  else
220  mEnables_Final[par_it->first] = par_it->second;
221  }
222 
223  // uniforms
224  for(UniformsMap::const_iterator par_it = parent->mUniforms_Final.begin(); par_it != parent->mUniforms_Final.end(); ++par_it)
225  {
226  if (!(par_it->second.mInheritance & IN_Propagate))
227  continue;
228  UniformsMap::const_iterator cur_it = mUniforms_Final.find(par_it->first);
229  if (cur_it == mUniforms_Final.end())
230  mUniforms_Final[par_it->first] = par_it->second;
231  else
232  if (!(par_it->second.mInheritance & 0x02/*IN_Overrides*/) || (cur_it->second.mInheritance & IN_Sticky))
233  continue;
234  else
235  mUniforms_Final[par_it->first] = par_it->second;
236  }
237  }
238 
239  // apply it to the Shader
240 
241  if (mShader)
242  {
245  mShader->disableAll();
246 
247  // we can speed this up even more by removing the duplication check
248 
249  for(RenderStatesMap::const_iterator rs_it = mRenderStates_Final.begin(); rs_it != mRenderStates_Final.end(); ++rs_it)
250  mShader->setRenderState(rs_it->second.mRenderState.get_writable(), rs_it->second.mIndex);
251  for(EnablesMap::const_iterator en_it = mEnables_Final.begin(); en_it != mEnables_Final.end(); ++en_it)
252  mShader->enable(en_it->second.mEnable);
253  for(UniformsMap::const_iterator rs_it = mUniforms_Final.begin(); rs_it != mUniforms_Final.end(); ++rs_it)
254  mShader->setUniform(rs_it->second.mUniform.get_writable());
255  }
256  }
257 
258  // states setters
259 
261  {
262  RenderStateInfo info(inheritance, rs, -1);
263  mRenderStates[ rs->type() ] = info;
264  }
265 
266  void setRenderState(EInheritance inheritance, RenderState* rs, int index)
267  {
268  RenderStateInfo info(inheritance, rs, index);
269  mRenderStates[ (ERenderState)(rs->type()+index) ] = info;
270  }
271 
273  {
274  mRenderStates.erase( rs->type() );
275  }
276 
277  void eraseRenderState(RenderState* rs, int index)
278  {
279  VL_CHECK(index >= -1)
280  if (index == -1)
281  index = 0;
282  mRenderStates.erase( (ERenderState)(rs->type()+index) );
283  }
284 
285  void setEnable(EEnable en, bool on, EInheritance inheritance=IN_Propagate)
286  {
287  EnableInfo info(en, on, inheritance);
288  mEnables[en] = info;
289  }
290 
292  {
293  mEnables.erase(en);
294  }
295 
296  void setUniform(Uniform* unif, EInheritance inheritance=IN_Propagate)
297  {
298  UniformInfo info(unif, inheritance);
299  mUniforms[unif->name()] = info;
300  }
301 
302  void eraseUniform(Uniform* unif)
303  {
304  mUniforms.erase(unif->name());
305  }
306 
307  // states getters
308 
309  const RenderStatesMap& renderStates() const { return mRenderStates; }
310 
311  RenderStatesMap& renderStates() { return mRenderStates; }
312 
313  const EnablesMap& enables() const { return mEnables; }
314 
315  EnablesMap& enables() { return mEnables; }
316 
317  const UniformsMap& uniforms() const { return mUniforms; }
318 
319  UniformsMap& uniforms() { return mUniforms; }
320 
321  protected:
322  std::vector< ref< ShaderNode > > mNodes;
324 
325  RenderStatesMap mRenderStates;
326  EnablesMap mEnables;
327  UniformsMap mUniforms;
328 
329  RenderStatesMap mRenderStates_Final;
330  EnablesMap mEnables_Final;
331  UniformsMap mUniforms_Final;
332 
334  };
335 }
336 
337 #endif
EInheritance
Wraps an OpenGL Shading Language uniform to be associated to a GLSLProgram (see vl::GLSLProgram docum...
Definition: Uniform.hpp:59
const Shader * shader() const
Definition: ShaderNode.hpp:88
const EnablesMap & enables() const
Definition: ShaderNode.hpp:313
const T * get() const
Definition: Object.hpp:128
ERenderState
void eraseAllUniforms()
Equivalent to gocUniformSet()->eraseAllUniforms(...)
Definition: Shader.hpp:2214
void eraseRenderState(RenderState *rs, int index)
Definition: ShaderNode.hpp:277
void eraseChildren(unsigned start, unsigned count)
Definition: ShaderNode.hpp:120
RenderStatesMap & renderStates()
Definition: ShaderNode.hpp:311
void inherit(ShaderNode *parent)
Definition: ShaderNode.hpp:156
const ShaderNode * child(unsigned i) const
Definition: ShaderNode.hpp:141
int findChild(const ShaderNode *node) const
Definition: ShaderNode.hpp:129
std::vector< ref< ShaderNode > > mNodes
Definition: ShaderNode.hpp:322
Shader * shader()
Definition: ShaderNode.hpp:90
std::map< ERenderState, RenderStateInfo > RenderStatesMap
Definition: ShaderNode.hpp:77
void disableAll()
Definition: Shader.hpp:2166
ShaderNode * parent()
Definition: ShaderNode.hpp:143
The ShaderNode class is used to conveniently manage complex hierarchies of Shader[s].
Definition: ShaderNode.hpp:45
RenderStatesMap mRenderStates
Definition: ShaderNode.hpp:325
ref< Shader > mShader
Definition: ShaderNode.hpp:333
#define VL_INSTRUMENT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:122
const RenderStatesMap & renderStates() const
Definition: ShaderNode.hpp:309
void eraseChild(unsigned index)
Definition: ShaderNode.hpp:113
ShaderNode * child(unsigned i)
Definition: ShaderNode.hpp:139
Visualization Library main namespace.
Propagates to children; does not override children settings; can be overridden.
ShaderNode&#39;s representation of a RenderState.
Definition: ShaderNode.hpp:60
Base class for most of the OpenGL render state wrapper classes.
Definition: RenderState.hpp:50
std::map< std::string, UniformInfo > UniformsMap
Definition: ShaderNode.hpp:79
void setRenderState(RenderStateNonIndexed *renderstate)
Definition: Shader.hpp:2172
size_t childrenCount() const
Definition: ShaderNode.hpp:137
UniformInfo(Uniform *unif=NULL, EInheritance inheritance=IN_Propagate)
Definition: ShaderNode.hpp:71
std::map< EEnable, EnableInfo > EnablesMap
Definition: ShaderNode.hpp:78
ShaderNode&#39;s representation of an enable.
Definition: ShaderNode.hpp:51
const std::string & name() const
Returns the name of the uniform variable.
Definition: Uniform.hpp:86
EnablesMap mEnables
Definition: ShaderNode.hpp:326
The base class for all the reference counted objects.
Definition: Object.hpp:158
Base class for those render states which have only one binding point (the vast majority).
Definition: RenderState.hpp:84
void eraseEnable(EEnable en)
Definition: ShaderNode.hpp:291
void eraseUniform(Uniform *unif)
Definition: ShaderNode.hpp:302
void addChild(ShaderNode *node)
Definition: ShaderNode.hpp:94
void eraseChild(ShaderNode *node)
Definition: ShaderNode.hpp:101
UniformsMap mUniforms_Final
Definition: ShaderNode.hpp:331
UniformsMap mUniforms
Definition: ShaderNode.hpp:327
ShaderNode&#39;s representation of a Uniform.
Definition: ShaderNode.hpp:69
void eraseAllRenderStates()
Definition: Shader.hpp:2191
ref< RenderState > mRenderState
Definition: ShaderNode.hpp:65
const UniformsMap & uniforms() const
Definition: ShaderNode.hpp:317
#define NULL
Definition: OpenGLDefs.hpp:81
Manages most of the OpenGL rendering states responsible of the final aspect of the rendered objects...
Definition: Shader.hpp:1830
const ShaderNode * parent() const
Definition: ShaderNode.hpp:145
Does not propagates to children (thus cannot override children settings); cannot be overridden...
EEnable
Constant that enable/disable a specific OpenGL feature, see also Shader, Shader::enable(), Shader::disable(), Shader::isEnabled()
EnableInfo(EEnable en=EN_UnknownEnable, bool on=false, EInheritance inheritance=IN_Propagate)
Definition: ShaderNode.hpp:53
void updateHierarchy()
Definition: ShaderNode.hpp:149
void setShader(Shader *shader)
Definition: ShaderNode.hpp:86
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
UniformsMap & uniforms()
Definition: ShaderNode.hpp:319
virtual ERenderState type() const
Definition: RenderState.hpp:59
void setRenderState(EInheritance inheritance, RenderStateNonIndexed *rs)
Definition: ShaderNode.hpp:260
RenderStatesMap mRenderStates_Final
Definition: ShaderNode.hpp:329
void setRenderState(EInheritance inheritance, RenderState *rs, int index)
Definition: ShaderNode.hpp:266
For internal use only.
void setUniform(Uniform *uniform)
Equivalent to gocUniformSet()->setUniform(...)
Definition: Shader.hpp:2202
EnablesMap mEnables_Final
Definition: ShaderNode.hpp:330
#define VL_CHECK(expr)
Definition: checks.hpp:73
Visualization Library&#39;s enums in the &#39;vl&#39; namespace.
void enable(EEnable capability)
Definition: Shader.hpp:2158
void setUniform(Uniform *unif, EInheritance inheritance=IN_Propagate)
Definition: ShaderNode.hpp:296
void setEnable(EEnable en, bool on, EInheritance inheritance=IN_Propagate)
Definition: ShaderNode.hpp:285
void eraseRenderState(RenderStateNonIndexed *rs)
Definition: ShaderNode.hpp:272
EnablesMap & enables()
Definition: ShaderNode.hpp:315
ShaderNode * mParent
Definition: ShaderNode.hpp:323
RenderStateInfo(EInheritance inheritance=IN_Propagate, RenderState *rs=NULL, int index=-1)
Definition: ShaderNode.hpp:62