Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://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