# Visualization Library

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

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/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 v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:43.
Permission is granted to use this page to write and publish articles regarding Visualization Library.