Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/ShaderNode.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #ifndef ShaderNode_INCLUDE_ONCE
00033 #define ShaderNode_INCLUDE_ONCE
00034 
00035 #include <vlGraphics/Shader.hpp>
00036 #include <vlCore/vlnamespace.hpp>
00037 #include <vector>
00038 #include <map>
00039 
00040 namespace vl
00041 {
00045   class ShaderNode: public Object
00046   {
00047     VL_INSTRUMENT_CLASS(vl::ShaderNode, Object)
00048 
00049   public:
00051     struct EnableInfo
00052     {
00053       EnableInfo(EEnable en=EN_UnknownEnable, bool on=false, EInheritance inheritance=IN_Propagate): mEnable(en), mOn(on), mInheritance(inheritance) {}
00054 
00055       EEnable mEnable;
00056       bool mOn;
00057       EInheritance mInheritance;
00058     };
00060     struct RenderStateInfo
00061     {
00062       RenderStateInfo(EInheritance inheritance=IN_Propagate, RenderState* rs=NULL, int index=-1): mInheritance(inheritance), mRenderState(rs), mIndex(index) {}
00063 
00064       EInheritance mInheritance;
00065       ref<RenderState> mRenderState;
00066       int mIndex;
00067     };
00069     struct UniformInfo
00070     {
00071       UniformInfo(Uniform* unif=NULL, EInheritance inheritance=IN_Propagate): mUniform(unif), mInheritance(inheritance) {}
00072 
00073       ref<Uniform> mUniform;
00074       EInheritance mInheritance;
00075     };
00076     // --- --- ---
00077     typedef std::map< ERenderState, RenderStateInfo > RenderStatesMap;
00078     typedef std::map< EEnable, EnableInfo > EnablesMap;
00079     typedef std::map< std::string, UniformInfo > UniformsMap;
00080 
00081   public:
00082     ShaderNode(): mParent(NULL) {}
00083 
00084     // shader-related functions
00085 
00086     void setShader(Shader* shader) { mShader = shader; }
00087 
00088     const Shader* shader() const { return mShader.get(); }
00089 
00090     Shader* shader() { return mShader.get(); }
00091 
00092     // tree-related functions
00093 
00094     void addChild(ShaderNode* node)
00095     { 
00096       VL_CHECK(node->parent() == NULL);
00097       mNodes.push_back(node);
00098       node->mParent = this;
00099     }
00100 
00101     void eraseChild(ShaderNode* node)
00102     {
00103       VL_CHECK(node->parent() == this);
00104       for(unsigned i=0; i<childrenCount(); ++i)
00105         if (child(i) == node)     
00106         {
00107           mNodes.erase(mNodes.begin()+i);
00108           node->mParent = NULL;
00109           return;
00110         }
00111     }
00112 
00113     void eraseChild(unsigned index)
00114     {
00115       VL_CHECK(index<childrenCount())
00116       mNodes[index]->mParent = NULL;
00117       mNodes.erase(mNodes.begin()+index);
00118     }
00119 
00120     void eraseChildren(unsigned start, unsigned count)
00121     {
00122       VL_CHECK(start < childrenCount())
00123       VL_CHECK(start+count-1 < childrenCount())
00124       for(unsigned i=start; i<start+count; ++i)
00125         mNodes[i]->mParent = NULL;
00126       mNodes.erase(mNodes.begin()+start, mNodes.begin()+start+count);
00127     }
00128 
00129     int findChild(const ShaderNode* node) const
00130     {
00131       for(unsigned i=0; i<childrenCount(); ++i)
00132         if(child(i) == node)
00133           return i;
00134       return -1;
00135     }
00136 
00137     size_t childrenCount() const { return mNodes.size(); }
00138 
00139     ShaderNode* child(unsigned i) { return mNodes[i].get(); }
00140 
00141     const ShaderNode* child(unsigned i) const { return mNodes[i].get(); }
00142 
00143     ShaderNode* parent() { return mParent; }
00144 
00145     const ShaderNode* parent() const { return mParent; }
00146 
00147     // inheritance-related functions
00148 
00149     void updateHierarchy()
00150     {
00151       inherit(parent());
00152       for(unsigned i=0;i <childrenCount(); ++i)
00153         child(i)->updateHierarchy();
00154     }
00155 
00156     void inherit(ShaderNode* parent)
00157     {
00158       // init
00159       mRenderStates_Final.clear();
00160       mEnables_Final.clear();
00161       mUniforms_Final.clear();
00162 
00163       // propagate
00164       for(RenderStatesMap::const_iterator rs_it = mRenderStates.begin(); rs_it != mRenderStates.end(); ++rs_it)
00165           mRenderStates_Final[rs_it->first] = rs_it->second;
00166 
00167       for(std::map< EEnable, EnableInfo>::const_iterator en_it = mEnables.begin(); en_it != mEnables.end(); ++en_it)
00168         if(en_it->second.mOn)
00169           mEnables_Final[en_it->first] = en_it->second;
00170 
00171       for(UniformsMap::const_iterator unif_it = mUniforms.begin(); unif_it != mUniforms.end(); ++unif_it)
00172           mUniforms_Final[unif_it->first] = unif_it->second;
00173 
00174       // iterate parent final values
00175 
00176       if (parent)
00177       {
00178 
00179         /* ALGORITHM:
00180          *
00181          * 1 - iterate over parent's values
00182          * 2 - if it doesn't propagate -> end
00183          * 3 - find current values
00184          *   3a - if there is not -> insert parent's -> end
00185          *   3b - if there is
00186          *      3ba - if parent's do not overrides -> end
00187          *      3bb - if child's do not overridden -> end
00188          *      3bc - else -> use parent's
00189          */
00190 
00191         // render states
00192         for(RenderStatesMap::const_iterator par_it = parent->mRenderStates_Final.begin(); par_it != parent->mRenderStates_Final.end(); ++par_it)
00193         {
00194           if (!(par_it->second.mInheritance & IN_Propagate))
00195             continue;
00196           RenderStatesMap::const_iterator cur_it = mRenderStates_Final.find(par_it->first);
00197           if (cur_it == mRenderStates_Final.end())
00198             mRenderStates_Final[par_it->first] = par_it->second;
00199           else
00200           if (!(par_it->second.mInheritance & 0x02/*IN_Overrides*/) || (cur_it->second.mInheritance & IN_Sticky))
00201             continue;
00202           else
00203             mRenderStates_Final[par_it->first] = par_it->second;
00204         }
00205 
00206         // enables
00207         for(EnablesMap::const_iterator par_it = parent->mEnables_Final.begin(); par_it != parent->mEnables_Final.end(); ++par_it)
00208         {
00209           if (!par_it->second.mOn)
00210             continue;
00211           if (!(par_it->second.mInheritance & IN_Propagate))
00212             continue;
00213           EnablesMap::const_iterator cur_it = mEnables_Final.find(par_it->first);
00214           if (cur_it == mEnables_Final.end())
00215             mEnables_Final[par_it->first] = par_it->second;
00216           else
00217           if (!(par_it->second.mInheritance & 0x02/*IN_Overrides*/) || (cur_it->second.mInheritance & IN_Sticky))
00218             continue;
00219           else
00220             mEnables_Final[par_it->first] = par_it->second;
00221         }
00222 
00223         // uniforms
00224         for(UniformsMap::const_iterator par_it = parent->mUniforms_Final.begin(); par_it != parent->mUniforms_Final.end(); ++par_it)
00225         {
00226           if (!(par_it->second.mInheritance & IN_Propagate))
00227             continue;
00228           UniformsMap::const_iterator cur_it = mUniforms_Final.find(par_it->first);
00229           if (cur_it == mUniforms_Final.end())
00230             mUniforms_Final[par_it->first] = par_it->second;
00231           else
00232           if (!(par_it->second.mInheritance & 0x02/*IN_Overrides*/) || (cur_it->second.mInheritance & IN_Sticky))
00233             continue;
00234           else
00235             mUniforms_Final[par_it->first] = par_it->second;
00236         }
00237       }
00238 
00239       // apply it to the Shader
00240 
00241       if (mShader)
00242       {
00243         mShader->eraseAllRenderStates();
00244         mShader->eraseAllUniforms();
00245         mShader->disableAll();
00246 
00247         // we can speed this up even more by removing the duplication check
00248 
00249         for(RenderStatesMap::const_iterator rs_it = mRenderStates_Final.begin(); rs_it != mRenderStates_Final.end(); ++rs_it)
00250           mShader->setRenderState(rs_it->second.mRenderState.get_writable(), rs_it->second.mIndex);
00251         for(EnablesMap::const_iterator en_it = mEnables_Final.begin(); en_it != mEnables_Final.end(); ++en_it)
00252           mShader->enable(en_it->second.mEnable);
00253         for(UniformsMap::const_iterator rs_it = mUniforms_Final.begin(); rs_it != mUniforms_Final.end(); ++rs_it)
00254           mShader->setUniform(rs_it->second.mUniform.get_writable());
00255       }
00256     }
00257 
00258     // states setters
00259 
00260     void setRenderState(EInheritance inheritance, RenderStateNonIndexed* rs)
00261     {
00262       RenderStateInfo info(inheritance, rs, -1);
00263       mRenderStates[ rs->type() ] = info;
00264     }
00265 
00266     void setRenderState(EInheritance inheritance, RenderState* rs, int index)
00267     {
00268       RenderStateInfo info(inheritance, rs, index);
00269       mRenderStates[ (ERenderState)(rs->type()+index) ] = info;
00270     }
00271 
00272     void eraseRenderState(RenderStateNonIndexed* rs)
00273     {
00274       mRenderStates.erase( rs->type() );
00275     }
00276 
00277     void eraseRenderState(RenderState* rs, int index)
00278     {
00279       VL_CHECK(index >= -1)
00280       if (index == -1)
00281         index = 0;
00282       mRenderStates.erase( (ERenderState)(rs->type()+index) );
00283     }
00284 
00285     void setEnable(EEnable en, bool on, EInheritance inheritance=IN_Propagate) 
00286     {
00287       EnableInfo info(en, on, inheritance);
00288       mEnables[en] = info;
00289     }
00290 
00291     void eraseEnable(EEnable en)
00292     {
00293       mEnables.erase(en);
00294     }
00295 
00296     void setUniform(Uniform* unif, EInheritance inheritance=IN_Propagate)
00297     {
00298       UniformInfo info(unif, inheritance);
00299       mUniforms[unif->name()] = info;
00300     }
00301 
00302     void eraseUniform(Uniform* unif)
00303     {
00304       mUniforms.erase(unif->name());
00305     }
00306 
00307     // states getters
00308 
00309     const RenderStatesMap& renderStates() const { return mRenderStates; }
00310 
00311     RenderStatesMap& renderStates() { return mRenderStates; }
00312 
00313     const EnablesMap& enables() const { return mEnables; }
00314 
00315     EnablesMap& enables() { return mEnables; }
00316 
00317     const UniformsMap& uniforms() const { return mUniforms; }
00318 
00319     UniformsMap& uniforms() { return mUniforms; }
00320 
00321   protected:
00322     std::vector< ref< ShaderNode > > mNodes;
00323     ShaderNode* mParent;
00324 
00325     RenderStatesMap mRenderStates;
00326     EnablesMap mEnables;
00327     UniformsMap mUniforms;
00328 
00329     RenderStatesMap mRenderStates_Final;
00330     EnablesMap mEnables_Final;
00331     UniformsMap mUniforms_Final;
00332 
00333     ref<Shader> mShader;
00334   };
00335 }
00336 
00337 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:41.
Permission is granted to use this page to write and publish articles regarding Visualization Library.