State 95 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  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
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSG_STATE
  14. #define OSG_STATE 1
  15. #include <osg/Export>
  16. #include <osg/GLExtensions>
  17. #include <osg/StateSet>
  18. #include <osg/Matrix>
  19. #include <osg/Uniform>
  20. #include <osg/BufferObject>
  21. #include <osg/Observer>
  22. #include <osg/Timer>
  23. #include <osg/VertexArrayState>
  24. #include <osg/ShaderComposer>
  25. #include <osg/FrameStamp>
  26. #include <osg/DisplaySettings>
  27. #include <osg/Polytope>
  28. #include <osg/Viewport>
  29. #include <osg/AttributeDispatchers>
  30. #include <osg/GraphicsCostEstimator>
  31. #include <iosfwd>
  32. #include <vector>
  33. #include <map>
  34. #include <set>
  35. #include <string>
  36. #ifndef GL_TEXTURE0
  37. #define GL_TEXTURE0 0x84C0
  38. #endif
  39. namespace osg {
  40. /** macro for use with osg::StateAttribute::apply methods for detecting and
  41. * reporting OpenGL error messages.*/
  42. #define OSG_GL_DEBUG(message) \
  43. if (state.getFineGrainedErrorDetection()) \
  44. { \
  45. GLenum errorNo = glGetError(); \
  46. if (errorNo!=GL_NO_ERROR) \
  47. { \
  48. osg::notify(WARN)<<"Warning: detected OpenGL error '"<<gluErrorString(errorNo)<<" "<<message<<endl; \
  49. }\
  50. }
  51. // forward declare GraphicsContext, View and State
  52. class GraphicsContext;
  53. /** Encapsulates the current applied OpenGL modes, attributes and vertex arrays settings,
  54. * implements lazy state updating and provides accessors for querying the current state.
  55. * The venerable Red Book says that "OpenGL is a state machine", and this class
  56. * represents the OpenGL state in OSG. Furthermore, \c State also has other
  57. * important features:
  58. * - It works as a stack of states (see \c pushStateSet() and
  59. * \c popStateSet()). Manipulating this stack of OpenGL states manually is
  60. * seldom needed, since OSG does this in the most common situations.
  61. * - It implements lazy state updating. This means that, if one requests a
  62. * state change and that particular state is already in the requested state,
  63. * no OpenGL call will be made. This ensures that the OpenGL pipeline is not
  64. * stalled by unnecessary state changes.
  65. * - It allows to query the current OpenGL state without calls to \c glGet*(),
  66. * which typically stall the graphics pipeline (see, for instance,
  67. * \c captureCurrentState() and \c getModelViewMatrix()).
  68. */
  69. class OSG_EXPORT State : public Referenced
  70. {
  71. public :
  72. State();
  73. /** Set the graphics context associated with that owns this State object.*/
  74. void setGraphicsContext(GraphicsContext* context) { _graphicsContext = context; }
  75. /** Get the graphics context associated with that owns this State object.*/
  76. GraphicsContext* getGraphicsContext() { return _graphicsContext; }
  77. /** Get the const graphics context associated with that owns this State object.*/
  78. const GraphicsContext* getGraphicsContext() const { return _graphicsContext; }
  79. /** Set the current OpenGL context uniqueID.
  80. * The ContextID is used by classes like osg::StateAttribute's and osg::Drawable's to
  81. * help manage separate OpenGL objects, such as display lists, vertex buffer objects
  82. * and texture object for each graphics context. The ContextID simply acts as an index
  83. * into arrays that these classes maintain for the purpose of storing GL object handles.
  84. *
  85. * Note, osgViewer::GraphicsWindow will automatically set up the ContextID for you,
  86. * so you will rearely need to set this yourself.
  87. *
  88. * The exception is when creating your own graphics context, where you should set
  89. * the ContextID uniquely for each graphics context.
  90. *
  91. * Typical settings for ContextID are 0,1,2,3... up to the maximum
  92. * number of graphics contexts you have set up. By default contextID is 0.
  93. */
  94. inline void setContextID(unsigned int contextID) { _contextID=contextID; }
  95. /** Get the current OpenGL context unique ID.*/
  96. inline unsigned int getContextID() const { return _contextID; }
  97. // ExtensionMap contains GL Extentsions objects used by StateAttribue to call OpenGL extensions/advanced features
  98. typedef std::map<const std::type_info*, osg::ref_ptr<osg::Referenced> > ExtensionMap;
  99. ExtensionMap _extensionMap;
  100. /** Get a specific GL extensions object or GraphicsObjectManager, initialize if not already present.
  101. * Note, must only be called from a the graphics context thread associated with this osg::State. */
  102. template<typename T>
  103. T* get()
  104. {
  105. const std::type_info* id(&typeid(T));
  106. osg::ref_ptr<osg::Referenced>& ptr = _extensionMap[id];
  107. if (!ptr)
  108. {
  109. ptr = new T(_contextID);
  110. }
  111. return static_cast<T*>(ptr.get());
  112. }
  113. /** Get a specific GL extensions object or GraphicsObjectManager if it already exists in the extension map.
  114. * Note, safe to call outwith a the graphics context thread associated with this osg::State.
  115. * Returns NULL if the desired extension object has not been created yet.*/
  116. template<typename T>
  117. const T* get() const
  118. {
  119. const std::type_info* id(&typeid(T));
  120. ExtensionMap::const_iterator itr = _extensionMap.find(id);
  121. if (itr==_extensionMap.end()) return 0;
  122. else return itr->second.get();
  123. }
  124. /** Set a specific GL extensions object pr GraphicsObjectManager. */
  125. template<typename T>
  126. void set(T* ptr)
  127. {
  128. const std::type_info* id(&typeid(T));
  129. _extensionMap[id] = ptr;
  130. }
  131. /* deprecated.*/
  132. void setShaderCompositionEnabled(bool flag) { _shaderCompositionEnabled = flag; }
  133. /* deprecated.*/
  134. bool getShaderCompositionEnabled() const { return _shaderCompositionEnabled; }
  135. /** deprecated.*/
  136. void setShaderComposer(ShaderComposer* sc) { _shaderComposer = sc; }
  137. /** deprecated.*/
  138. ShaderComposer* getShaderComposer() { return _shaderComposer.get(); }
  139. /** deprecated.*/
  140. const ShaderComposer* getShaderComposer() const { return _shaderComposer.get(); }
  141. /** Get the unform list in which to inject any uniforms that StateAttribute::apply(State&) methods provide.*/
  142. StateSet::UniformList& getCurrentShaderCompositionUniformList() { return _currentShaderCompositionUniformList; }
  143. /** Convenience method for StateAttribute::apply(State&) methods to pass on their uniforms to osg::State so it can apply them at the appropriate point.*/
  144. void applyShaderCompositionUniform(const osg::Uniform* uniform, StateAttribute::OverrideValue value=StateAttribute::ON)
  145. {
  146. StateSet::RefUniformPair& up = _currentShaderCompositionUniformList[uniform->getName()];
  147. up.first = const_cast<Uniform*>(uniform);
  148. up.second = value;
  149. }
  150. /** Push stateset onto state stack.*/
  151. void pushStateSet(const StateSet* dstate);
  152. /** Pop stateset off state stack.*/
  153. void popStateSet();
  154. /** pop all statesets off state stack, ensuring it is empty ready for the next frame.
  155. * Note, to return OpenGL to default state, one should do any state.popAllStatSets(); state.apply().*/
  156. void popAllStateSets();
  157. /** Insert stateset onto state stack.*/
  158. void insertStateSet(unsigned int pos,const StateSet* dstate);
  159. /** Pop stateset off state stack.*/
  160. void removeStateSet(unsigned int pos);
  161. /** Get the number of StateSet's on the StateSet stack.*/
  162. unsigned int getStateSetStackSize() { return static_cast<unsigned int>(_stateStateStack.size()); }
  163. /** Pop StateSet's for the StateSet stack till its size equals the specified size.*/
  164. void popStateSetStackToSize(unsigned int size) { while (_stateStateStack.size()>size) popStateSet(); }
  165. typedef std::vector<const StateSet*> StateSetStack;
  166. /** Get the StateSet stack.*/
  167. StateSetStack& getStateSetStack() { return _stateStateStack; }
  168. /** Copy the modes and attributes which capture the current state.*/
  169. void captureCurrentState(StateSet& stateset) const;
  170. /** Release all OpenGL objects associated cached by this osg::State object.*/
  171. void releaseGLObjects();
  172. /** reset the state object to an empty stack.*/
  173. void reset();
  174. inline const Viewport* getCurrentViewport() const
  175. {
  176. return static_cast<const Viewport*>(getLastAppliedAttribute(osg::StateAttribute::VIEWPORT));
  177. }
  178. void setInitialViewMatrix(const osg::RefMatrix* matrix);
  179. inline const osg::Matrix& getInitialViewMatrix() const { return *_initialViewMatrix; }
  180. inline const osg::Matrix& getInitialInverseViewMatrix() const { return _initialInverseViewMatrix; }
  181. void applyProjectionMatrix(const osg::RefMatrix* matrix);
  182. inline const osg::Matrix& getProjectionMatrix() const { return *_projection; }
  183. void applyModelViewMatrix(const osg::RefMatrix* matrix);
  184. void applyModelViewMatrix(const osg::Matrix&);
  185. const osg::Matrix& getModelViewMatrix() const { return *_modelView; }
  186. void setUseModelViewAndProjectionUniforms(bool flag) { _useModelViewAndProjectionUniforms = flag; }
  187. bool getUseModelViewAndProjectionUniforms() const { return _useModelViewAndProjectionUniforms; }
  188. void updateModelViewAndProjectionMatrixUniforms();
  189. void applyModelViewAndProjectionUniformsIfRequired();
  190. osg::Uniform* getModelViewMatrixUniform() { return _modelViewMatrixUniform.get(); }
  191. osg::Uniform* getProjectionMatrixUniform() { return _projectionMatrixUniform.get(); }
  192. osg::Uniform* getModelViewProjectionMatrixUniform() { return _modelViewProjectionMatrixUniform.get(); }
  193. osg::Uniform* getNormalMatrixUniform() { return _normalMatrixUniform.get(); }
  194. Polytope getViewFrustum() const;
  195. void setUseVertexAttributeAliasing(bool flag);
  196. bool getUseVertexAttributeAliasing() const { return _useVertexAttributeAliasing ; }
  197. typedef std::vector<VertexAttribAlias> VertexAttribAliasList;
  198. /** Reset the vertex attribute aliasing to osg's default. This method needs to be called before render anything unless you really know what you're doing !*/
  199. void resetVertexAttributeAlias(bool compactAliasing=true, unsigned int numTextureUnits=8);
  200. /** Set the vertex attribute aliasing for "vertex". This method needs to be called before render anything unless you really know what you're doing !*/
  201. void setVertexAlias(const VertexAttribAlias& alias) { _vertexAlias = alias; }
  202. const VertexAttribAlias& getVertexAlias() { return _vertexAlias; }
  203. /** Set the vertex attribute aliasing for "normal". This method needs to be called before render anything unless you really know what you're doing !*/
  204. void setNormalAlias(const VertexAttribAlias& alias) { _normalAlias = alias; }
  205. const VertexAttribAlias& getNormalAlias() { return _normalAlias; }
  206. /** Set the vertex attribute aliasing for "color". This method needs to be called before render anything unless you really know what you're doing !*/
  207. void setColorAlias(const VertexAttribAlias& alias) { _colorAlias = alias; }
  208. const VertexAttribAlias& getColorAlias() { return _colorAlias; }
  209. /** Set the vertex attribute aliasing for "secondary color". This method needs to be called before render anything unless you really know what you're doing !*/
  210. void setSecondaryColorAlias(const VertexAttribAlias& alias) { _secondaryColorAlias = alias; }
  211. const VertexAttribAlias& getSecondaryColorAlias() { return _secondaryColorAlias; }
  212. /** Set the vertex attribute aliasing for "fog coord". This method needs to be called before render anything unless you really know what you're doing !*/
  213. void setFogCoordAlias(const VertexAttribAlias& alias) { _fogCoordAlias = alias; }
  214. const VertexAttribAlias& getFogCoordAlias() { return _fogCoordAlias; }
  215. /** Set the vertex attribute aliasing list for texture coordinates. This method needs to be called before render anything unless you really know what you're doing !*/
  216. void setTexCoordAliasList(const VertexAttribAliasList& aliasList) { _texCoordAliasList = aliasList; }
  217. const VertexAttribAliasList& getTexCoordAliasList() { return _texCoordAliasList; }
  218. /** Set the vertex attribute binding list. This method needs to be called before render anything unless you really know what you're doing !*/
  219. void setAttributeBindingList(const Program::AttribBindingList& attribBindingList) { _attributeBindingList = attribBindingList; }
  220. const Program::AttribBindingList& getAttributeBindingList() { return _attributeBindingList; }
  221. bool convertVertexShaderSourceToOsgBuiltIns(std::string& source) const;
  222. /** Apply stateset.*/
  223. void apply(const StateSet* dstate);
  224. /** Updates the OpenGL state so that it matches the \c StateSet at the
  225. * top of the stack of <tt>StateSet</tt>s maintained internally by a
  226. * \c State.
  227. */
  228. void apply();
  229. /** Apply any shader composed state.*/
  230. void applyShaderComposition();
  231. void glDrawBuffer(GLenum buffer);
  232. GLenum getDrawBuffer() const { return _drawBuffer; }
  233. void glReadBuffer(GLenum buffer);
  234. GLenum getReadBuffer() const { return _readBuffer; }
  235. /** Set whether a particular OpenGL mode is valid in the current graphics context.
  236. * Use to disable OpenGL modes that are not supported by current graphics drivers/context.*/
  237. inline void setModeValidity(StateAttribute::GLMode mode,bool valid)
  238. {
  239. ModeStack& ms = _modeMap[mode];
  240. ms.valid = valid;
  241. }
  242. /** Get whether a particular OpenGL mode is valid in the current graphics context.
  243. * Use to disable OpenGL modes that are not supported by current graphics drivers/context.*/
  244. inline bool getModeValidity(StateAttribute::GLMode mode)
  245. {
  246. ModeStack& ms = _modeMap[mode];
  247. return ms.valid;
  248. }
  249. inline void setGlobalDefaultModeValue(StateAttribute::GLMode mode,bool enabled)
  250. {
  251. ModeStack& ms = _modeMap[mode];
  252. ms.global_default_value = enabled;
  253. }
  254. inline bool getGlobalDefaultModeValue(StateAttribute::GLMode mode)
  255. {
  256. return _modeMap[mode].global_default_value;
  257. }
  258. inline bool getLastAppliedModeValue(StateAttribute::GLMode mode)
  259. {
  260. return _modeMap[mode].last_applied_value;
  261. }
  262. /** Proxy helper class for applyig a model in a local scope, with the preivous value being resotred automatically on leaving the scope that proxy was created.*/
  263. struct ApplyModeProxy
  264. {
  265. inline ApplyModeProxy(osg::State& state, GLenum mode, bool value):_state(state), _mode(mode)
  266. {
  267. _previous_value = _state.getLastAppliedModeValue(mode);
  268. _need_to_apply_value = (_previous_value!=value);
  269. if (_need_to_apply_value) _state.applyMode(_mode, value);
  270. }
  271. inline ~ApplyModeProxy()
  272. {
  273. if (_need_to_apply_value) _state.applyMode(_mode, _previous_value);
  274. }
  275. osg::State& _state;
  276. GLenum _mode;
  277. bool _previous_value;
  278. bool _need_to_apply_value;
  279. };
  280. struct ApplyTextureModeProxy
  281. {
  282. inline ApplyTextureModeProxy(osg::State& state, unsigned int unit, GLenum mode, bool value):_state(state), _unit(unit), _mode(mode)
  283. {
  284. _previous_value = _state.getLastAppliedTextureModeValue(_unit, _mode);
  285. _need_to_apply_value = (_previous_value!=value);
  286. if (_need_to_apply_value) _state.applyTextureMode(_unit, _mode, value);
  287. }
  288. inline ~ApplyTextureModeProxy()
  289. {
  290. if (_need_to_apply_value) _state.applyTextureMode(_unit, _mode, _previous_value);
  291. }
  292. osg::State& _state;
  293. unsigned int _unit;
  294. GLenum _mode;
  295. bool _previous_value;
  296. bool _need_to_apply_value;
  297. };
  298. /** Apply an OpenGL mode if required. This is a wrapper around
  299. * \c glEnable() and \c glDisable(), that just actually calls these
  300. * functions if the \c enabled flag is different than the current
  301. * state.
  302. * @return \c true if the state was actually changed. \c false
  303. * otherwise. Notice that a \c false return does not indicate
  304. * an error, it just means that the mode was already set to the
  305. * same value as the \c enabled parameter.
  306. */
  307. inline bool applyMode(StateAttribute::GLMode mode,bool enabled)
  308. {
  309. ModeStack& ms = _modeMap[mode];
  310. ms.changed = true;
  311. return applyMode(mode,enabled,ms);
  312. }
  313. inline void setGlobalDefaultTextureModeValue(unsigned int unit, StateAttribute::GLMode mode,bool enabled)
  314. {
  315. ModeMap& modeMap = getOrCreateTextureModeMap(unit);
  316. ModeStack& ms = modeMap[mode];
  317. ms.global_default_value = enabled;
  318. }
  319. inline bool getGlobalDefaultTextureModeValue(unsigned int unit, StateAttribute::GLMode mode)
  320. {
  321. ModeMap& modeMap = getOrCreateTextureModeMap(unit);
  322. ModeStack& ms = modeMap[mode];
  323. return ms.global_default_value;
  324. }
  325. inline bool applyTextureMode(unsigned int unit, StateAttribute::GLMode mode,bool enabled)
  326. {
  327. ModeMap& modeMap = getOrCreateTextureModeMap(unit);
  328. ModeStack& ms = modeMap[mode];
  329. ms.changed = true;
  330. return applyModeOnTexUnit(unit,mode,enabled,ms);
  331. }
  332. inline bool getLastAppliedTextureModeValue(unsigned int unit, StateAttribute::GLMode mode)
  333. {
  334. ModeMap& modeMap = getOrCreateTextureModeMap(unit);
  335. ModeStack& ms = modeMap[mode];
  336. return ms.last_applied_value;
  337. }
  338. inline void setGlobalDefaultAttribute(const StateAttribute* attribute)
  339. {
  340. AttributeStack& as = _attributeMap[attribute->getTypeMemberPair()];
  341. as.global_default_attribute = attribute;
  342. }
  343. inline const StateAttribute* getGlobalDefaultAttribute(StateAttribute::Type type, unsigned int member=0)
  344. {
  345. AttributeStack& as = _attributeMap[StateAttribute::TypeMemberPair(type,member)];
  346. return as.global_default_attribute.get();
  347. }
  348. /** Apply an attribute if required. */
  349. inline bool applyAttribute(const StateAttribute* attribute)
  350. {
  351. AttributeStack& as = _attributeMap[attribute->getTypeMemberPair()];
  352. as.changed = true;
  353. return applyAttribute(attribute,as);
  354. }
  355. inline void setGlobalDefaultTextureAttribute(unsigned int unit, const StateAttribute* attribute)
  356. {
  357. AttributeMap& attributeMap = getOrCreateTextureAttributeMap(unit);
  358. AttributeStack& as = attributeMap[attribute->getTypeMemberPair()];
  359. as.global_default_attribute = attribute;
  360. }
  361. inline const StateAttribute* getGlobalDefaultTextureAttribute(unsigned int unit, StateAttribute::Type type, unsigned int member = 0)
  362. {
  363. AttributeMap& attributeMap = getOrCreateTextureAttributeMap(unit);
  364. AttributeStack& as = attributeMap[StateAttribute::TypeMemberPair(type,member)];
  365. return as.global_default_attribute.get();
  366. }
  367. inline bool applyTextureAttribute(unsigned int unit, const StateAttribute* attribute)
  368. {
  369. AttributeMap& attributeMap = getOrCreateTextureAttributeMap(unit);
  370. AttributeStack& as = attributeMap[attribute->getTypeMemberPair()];
  371. as.changed = true;
  372. return applyAttributeOnTexUnit(unit,attribute,as);
  373. }
  374. /** Mode has been set externally, update state to reflect this setting.*/
  375. void haveAppliedMode(StateAttribute::GLMode mode,StateAttribute::GLModeValue value);
  376. /** Mode has been set externally, therefore dirty the associated mode in osg::State
  377. * so it is applied on next call to osg::State::apply(..)*/
  378. void haveAppliedMode(StateAttribute::GLMode mode);
  379. /** Attribute has been applied externally, update state to reflect this setting.*/
  380. void haveAppliedAttribute(const StateAttribute* attribute);
  381. /** Attribute has been applied externally,
  382. * and therefore this attribute type has been dirtied
  383. * and will need to be re-applied on next osg::State.apply(..).
  384. * note, if you have an osg::StateAttribute which you have applied externally
  385. * then use the have_applied(attribute) method as this will cause the osg::State to
  386. * track the current state more accurately and enable lazy state updating such
  387. * that only changed state will be applied.*/
  388. void haveAppliedAttribute(StateAttribute::Type type, unsigned int member=0);
  389. /** Get whether the current specified mode is enabled (true) or disabled (false).*/
  390. bool getLastAppliedMode(StateAttribute::GLMode mode) const;
  391. /** Get the current specified attribute, return NULL if one has not yet been applied.*/
  392. const StateAttribute* getLastAppliedAttribute(StateAttribute::Type type, unsigned int member=0) const;
  393. /** texture Mode has been set externally, update state to reflect this setting.*/
  394. void haveAppliedTextureMode(unsigned int unit, StateAttribute::GLMode mode,StateAttribute::GLModeValue value);
  395. /** texture Mode has been set externally, therefore dirty the associated mode in osg::State
  396. * so it is applied on next call to osg::State::apply(..)*/
  397. void haveAppliedTextureMode(unsigned int unit, StateAttribute::GLMode mode);
  398. /** texture Attribute has been applied externally, update state to reflect this setting.*/
  399. void haveAppliedTextureAttribute(unsigned int unit, const StateAttribute* attribute);
  400. /** texture Attribute has been applied externally,
  401. * and therefore this attribute type has been dirtied
  402. * and will need to be re-applied on next osg::State.apply(..).
  403. * note, if you have an osg::StateAttribute which you have applied externally
  404. * then use the have_applied(attribute) method as this will the osg::State to
  405. * track the current state more accurately and enable lazy state updating such
  406. * that only changed state will be applied.*/
  407. void haveAppliedTextureAttribute(unsigned int unit, StateAttribute::Type type, unsigned int member=0);
  408. /** Get whether the current specified texture mode is enabled (true) or disabled (false).*/
  409. bool getLastAppliedTextureMode(unsigned int unit, StateAttribute::GLMode mode) const;
  410. /** Get the current specified texture attribute, return NULL if one has not yet been applied.*/
  411. const StateAttribute* getLastAppliedTextureAttribute(unsigned int unit, StateAttribute::Type type, unsigned int member=0) const;
  412. /** Dirty the modes previously applied in osg::State.*/
  413. void dirtyAllModes();
  414. /** Dirty the modes attributes previously applied in osg::State.*/
  415. void dirtyAllAttributes();
  416. /** Proxy helper class for applyig a VertexArrayState in a local scope, with the preivous value being resotred automatically on leaving the scope that proxy was created.*/
  417. struct SetCurrentVertexArrayStateProxy
  418. {
  419. SetCurrentVertexArrayStateProxy(osg::State& state, VertexArrayState* vas):_state(state) { _state.setCurrentVertexArrayState(vas); }
  420. ~SetCurrentVertexArrayStateProxy() { _state.setCurrentToGlobalVertexArrayState(); }
  421. osg::State& _state;
  422. };
  423. /** Set the CurrentVetexArrayState object that take which vertex arrays are bound.*/
  424. void setCurrentVertexArrayState(VertexArrayState* vas) { _vas = vas; }
  425. /** Get the CurrentVetexArrayState object that take which vertex arrays are bound.*/
  426. VertexArrayState* getCurrentVertexArrayState() const { return _vas; }
  427. /** Set the getCurrentVertexArrayState to the GlobalVertexArrayState.*/
  428. void setCurrentToGlobalVertexArrayState() { _vas = _globalVertexArrayState.get(); }
  429. /** Reset the CurrentVertexArrayState/VertexArrayObject if it's value matches the specificied vas - use when deleting a vas.*/
  430. void resetCurrentVertexArrayStateOnMatch(VertexArrayState* vas)
  431. {
  432. if (vas->getVertexArrayObject()== _currentVAO) _currentVAO = 0;
  433. if (_vas==vas) _vas = _globalVertexArrayState.get();
  434. }
  435. /** disable the vertex, normal, color, tex coords, secondary color, fog coord and index arrays.*/
  436. void disableAllVertexArrays();
  437. void lazyDisablingOfVertexAttributes() { _vas->lazyDisablingOfVertexAttributes(); }
  438. void applyDisablingOfVertexAttributes() { _vas->applyDisablingOfVertexAttributes(*this); }
  439. void setCurrentVertexBufferObject(osg::GLBufferObject* vbo) { _vas->setCurrentVertexBufferObject(vbo); }
  440. const GLBufferObject* getCurrentVertexBufferObject() { return _vas->getCurrentVertexBufferObject(); }
  441. void bindVertexBufferObject(osg::GLBufferObject* vbo) { _vas->bindVertexBufferObject(vbo); }
  442. void unbindVertexBufferObject() { _vas->unbindVertexBufferObject(); }
  443. void setCurrentElementBufferObject(osg::GLBufferObject* ebo) { _vas->setCurrentElementBufferObject(ebo); }
  444. const GLBufferObject* getCurrentElementBufferObject() { return _vas->getCurrentElementBufferObject(); }
  445. void bindElementBufferObject(osg::GLBufferObject* ebo) { _vas->bindElementBufferObject(ebo); }
  446. void unbindElementBufferObject() { _vas->unbindElementBufferObject(); }
  447. void setCurrentPixelBufferObject(osg::GLBufferObject* pbo) { _currentPBO = pbo; }
  448. const GLBufferObject* getCurrentPixelBufferObject() const { return _currentPBO; }
  449. inline void bindPixelBufferObject(osg::GLBufferObject* pbo)
  450. {
  451. if (pbo)
  452. {
  453. if (pbo == _currentPBO) return;
  454. if (pbo->isDirty()) pbo->compileBuffer();
  455. else pbo->bindBuffer();
  456. _currentPBO = pbo;
  457. }
  458. else
  459. {
  460. unbindPixelBufferObject();
  461. }
  462. }
  463. inline void unbindPixelBufferObject()
  464. {
  465. if (!_currentPBO) return;
  466. _glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,0);
  467. _currentPBO = 0;
  468. }
  469. inline void bindDrawIndirectBufferObject(osg::GLBufferObject* ibo)
  470. {
  471. if (ibo->isDirty())
  472. {
  473. ibo->compileBuffer();
  474. _currentDIBO = ibo;
  475. }
  476. else if (ibo != _currentDIBO)
  477. {
  478. ibo->bindBuffer();
  479. _currentDIBO = ibo;
  480. }
  481. }
  482. inline void unbindDrawIndirectBufferObject()
  483. {
  484. if (!_currentDIBO) return;
  485. _glBindBuffer(GL_DRAW_INDIRECT_BUFFER,0);
  486. _currentDIBO = 0;
  487. }
  488. void setCurrentVertexArrayObject(GLuint vao) { _currentVAO = vao; }
  489. GLuint getCurrentVertexArrayObject() const { return _currentVAO; }
  490. inline void bindVertexArrayObject(const VertexArrayState* vas) { bindVertexArrayObject(vas->getVertexArrayObject()); }
  491. inline void bindVertexArrayObject(GLuint vao) { if (_currentVAO!=vao) { _glExtensions->glBindVertexArray(vao); _currentVAO = vao; } }
  492. inline void unbindVertexArrayObject() { if (_currentVAO!=0) { _glExtensions->glBindVertexArray(0); _currentVAO = 0; } }
  493. typedef std::vector<GLushort> IndicesGLushort;
  494. IndicesGLushort _quadIndicesGLushort[4];
  495. typedef std::vector<GLuint> IndicesGLuint;
  496. IndicesGLuint _quadIndicesGLuint[4];
  497. void drawQuads(GLint first, GLsizei count, GLsizei primCount=0);
  498. inline void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
  499. {
  500. if (primcount>=1 && _glDrawArraysInstanced!=0) _glDrawArraysInstanced(mode, first, count, primcount);
  501. else glDrawArrays(mode, first, count);
  502. }
  503. inline void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount )
  504. {
  505. if (primcount>=1 && _glDrawElementsInstanced!=0) _glDrawElementsInstanced(mode, count, type, indices, primcount);
  506. else glDrawElements(mode, count, type, indices);
  507. }
  508. inline void Vertex(float x, float y, float z, float w=1.0f)
  509. {
  510. #if defined(OSG_GL_VERTEX_FUNCS_AVAILABLE) && !defined(OSG_GLES1_AVAILABLE)
  511. if (_useVertexAttributeAliasing) _glVertexAttrib4f( _vertexAlias._location, x,y,z,w);
  512. else glVertex4f(x,y,z,w);
  513. #else
  514. _glVertexAttrib4f( _vertexAlias._location, x,y,z,w);
  515. #endif
  516. }
  517. inline void Color(float r, float g, float b, float a=1.0f)
  518. {
  519. #ifdef OSG_GL_VERTEX_FUNCS_AVAILABLE
  520. if (_useVertexAttributeAliasing) _glVertexAttrib4f( _colorAlias._location, r,g,b,a);
  521. else glColor4f(r,g,b,a);
  522. #else
  523. _glVertexAttrib4f( _colorAlias._location, r,g,b,a);
  524. #endif
  525. }
  526. void Normal(float x, float y, float z)
  527. {
  528. #ifdef OSG_GL_VERTEX_FUNCS_AVAILABLE
  529. if (_useVertexAttributeAliasing) _glVertexAttrib4f( _normalAlias._location, x,y,z,0.0);
  530. else glNormal3f(x,y,z);
  531. #else
  532. _glVertexAttrib4f( _normalAlias._location, x,y,z,0.0);
  533. #endif
  534. }
  535. void TexCoord(float x, float y=0.0f, float z=0.0f, float w=1.0f)
  536. {
  537. #if !defined(OSG_GLES1_AVAILABLE)
  538. #ifdef OSG_GL_VERTEX_FUNCS_AVAILABLE
  539. if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[0]._location, x,y,z,w);
  540. else glTexCoord4f(x,y,z,w);
  541. #else
  542. _glVertexAttrib4f( _texCoordAliasList[0]._location, x,y,z,w);
  543. #endif
  544. #endif
  545. }
  546. void MultiTexCoord(unsigned int unit, float x, float y=0.0f, float z=0.0f, float w=1.0f)
  547. {
  548. #if !defined(OSG_GLES1_AVAILABLE)
  549. #ifdef OSG_GL_VERTEX_FUNCS_AVAILABLE
  550. if (_useVertexAttributeAliasing) _glVertexAttrib4f( _texCoordAliasList[unit]._location, x,y,z,w);
  551. else _glMultiTexCoord4f(GL_TEXTURE0+unit,x,y,z,w);
  552. #else
  553. _glVertexAttrib4f( _texCoordAliasList[unit]._location, x,y,z,w);
  554. #endif
  555. #endif
  556. }
  557. void VerteAttrib(unsigned int location, float x, float y=0.0f, float z=0.0f, float w=0.0f)
  558. {
  559. _glVertexAttrib4f( location, x,y,z,w);
  560. }
  561. /** Wrapper around glInterleavedArrays(..).
  562. * also resets the internal array points and modes within osg::State to keep the other
  563. * vertex array operations consistent. */
  564. void setInterleavedArrays( GLenum format, GLsizei stride, const GLvoid* pointer) { _vas->setInterleavedArrays( *this, format, stride, pointer); }
  565. /** Set the vertex pointer using an osg::Array, and manage any VBO that are required.*/
  566. inline void setVertexPointer(const Array* array) { _vas->setVertexArray(*this, array); }
  567. inline void setVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_FALSE) { _vas->setVertexArray( *this, size, type, stride, ptr, normalized); }
  568. inline void disableVertexPointer() { _vas->disableVertexArray(*this); }
  569. inline void setNormalPointer(const Array* array) { _vas->setNormalArray(*this, array); }
  570. inline void setNormalPointer( GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_FALSE ) { _vas->setNormalArray( *this, type, stride, ptr, normalized); }
  571. inline void disableNormalPointer() { _vas->disableNormalArray(*this); }
  572. inline void setColorPointer(const Array* array) { _vas->setColorArray(*this, array); }
  573. inline void setColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_TRUE ) { _vas->setColorArray(*this, size, type, stride, ptr, normalized); }
  574. inline void disableColorPointer() { _vas->disableColorArray(*this); }
  575. inline bool isSecondaryColorSupported() const { return _isSecondaryColorSupported; }
  576. inline void setSecondaryColorPointer(const Array* array) { _vas->setSecondaryColorArray(*this, array); }
  577. inline void disableSecondaryColorPointer() { _vas->disableSecondaryColorArray(*this); }
  578. inline bool isFogCoordSupported() const { return _isFogCoordSupported; }
  579. inline void setFogCoordPointer(const Array* array) { _vas->setFogCoordArray(*this, array); }
  580. inline void disableFogCoordPointer() { _vas->disableFogCoordArray(*this); }
  581. inline void setTexCoordPointer(unsigned int unit, const Array* array) { _vas->setTexCoordArray(*this, unit, array); }
  582. inline void setTexCoordPointer( unsigned int unit, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr, GLboolean normalized=GL_FALSE ) { _vas->setTexCoordArray(*this, unit, size, type, stride, ptr, normalized); }
  583. inline void disableTexCoordPointer( unsigned int unit ) { _vas->disableTexCoordArray(*this, unit); }
  584. inline void disableTexCoordPointersAboveAndIncluding( unsigned int unit ) { _vas->disableTexCoordArrayAboveAndIncluding(*this, unit); }
  585. /// For GL>=2.0 uses GL_MAX_TEXTURE_COORDS, for GL<2 uses GL_MAX_TEXTURE_UNITS
  586. inline GLint getMaxTextureCoords() const { return _glMaxTextureCoords; }
  587. /// For GL>=2.0 uses GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, for GL<2 uses GL_MAX_TEXTURE_UNITS
  588. inline GLint getMaxTextureUnits() const { return _glMaxTextureUnits; }
  589. /** Set the current texture unit, return true if selected,
  590. * false if selection failed such as when multi texturing is not supported.
  591. * note, only updates values that change.*/
  592. inline bool setActiveTextureUnit( unsigned int unit );
  593. /** Get the current texture unit.*/
  594. unsigned int getActiveTextureUnit() const { return _currentActiveTextureUnit; }
  595. /** Set the current tex coord array texture unit, return true if selected,
  596. * false if selection failed such as when multi texturing is not supported.
  597. * note, only updates values that change.*/
  598. bool setClientActiveTextureUnit( unsigned int unit );
  599. /** Get the current tex coord array texture unit.*/
  600. unsigned int getClientActiveTextureUnit() const;
  601. inline void setVertexAttribPointer(unsigned int unit, const Array* array) { _vas->setVertexAttribArray(*this, unit, array); }
  602. inline void setVertexAttribLPointer(unsigned int unit, const Array* array) { _vas->setVertexAttribArray(*this, unit, array); }
  603. inline void setVertexAttribIPointer(unsigned int unit, const Array* array) { _vas->setVertexAttribArray(*this, unit, array); }
  604. inline void disableVertexAttribPointer( unsigned int index ) { _vas->disableVertexAttribArray(*this, index); }
  605. inline void disableVertexAttribPointersAboveAndIncluding( unsigned int index ) { _vas->disableVertexAttribArray(*this, index); }
  606. /** dirty the vertex, normal, color, tex coords, secondary color, fog coord and index arrays.*/
  607. void dirtyAllVertexArrays();
  608. inline bool isVertexBufferObjectSupported() const { return _isVertexBufferObjectSupported; }
  609. inline bool useVertexBufferObject(bool useVBO) const { return _forceVertexBufferObject || (_isVertexBufferObjectSupported && useVBO); }
  610. inline bool isVertexArrayObjectSupported() const { return _isVertexArrayObjectSupported; }
  611. inline bool useVertexArrayObject(bool useVAO) const { return _forceVertexArrayObject || (_isVertexArrayObjectSupported && useVAO); }
  612. inline void setLastAppliedProgramObject(const Program::PerContextProgram* program)
  613. {
  614. if (_lastAppliedProgramObject!=program)
  615. {
  616. _lastAppliedProgramObject = program;
  617. }
  618. }
  619. inline const Program::PerContextProgram* getLastAppliedProgramObject() const { return _lastAppliedProgramObject; }
  620. inline GLint getUniformLocation( unsigned int uniformNameID ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getUniformLocation(uniformNameID) : -1; }
  621. /**
  622. * Alternative version of getUniformLocation( unsigned int uniformNameID )
  623. * retrofited into OSG for backward compatibility with osgCal,
  624. * after uniform ids were refactored from std::strings to GLints in OSG version 2.9.10.
  625. *
  626. * Drawbacks: This method is not particularly fast. It has to access mutexed static
  627. * map of uniform ids. So don't overuse it or your app performance will suffer.
  628. */
  629. inline GLint getUniformLocation( const std::string & uniformName ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getUniformLocation(uniformName) : -1; }
  630. inline GLint getAttribLocation( const std::string& name ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getAttribLocation(name) : -1; }
  631. typedef std::pair<const StateAttribute*,StateAttribute::OverrideValue> AttributePair;
  632. typedef std::vector<AttributePair> AttributeVec;
  633. AttributeVec& getAttributeVec( const osg::StateAttribute* attribute )
  634. {
  635. AttributeStack& as = _attributeMap[ attribute->getTypeMemberPair() ];
  636. return as.attributeVec;
  637. }
  638. /** Set the frame stamp for the current frame.*/
  639. inline void setFrameStamp(FrameStamp* fs) { _frameStamp = fs; }
  640. /** Get the frame stamp for the current frame.*/
  641. inline FrameStamp* getFrameStamp() { return _frameStamp.get(); }
  642. /** Get the const frame stamp for the current frame.*/
  643. inline const FrameStamp* getFrameStamp() const { return _frameStamp.get(); }
  644. /** Set the DisplaySettings. Note, nothing is applied, the visual settings are just
  645. * used in the State object to pass the current visual settings to Drawables
  646. * during rendering. */
  647. inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; }
  648. /** Get the const DisplaySettings */
  649. inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); }
  650. /** Get the DisplaySettings that is current active DisplaySettings to be used by osg::State, - if DisplaySettings is not directly assigned then fallback to DisplaySettings::instance(). */
  651. inline DisplaySettings* getActiveDisplaySettings() { return _displaySettings.valid() ? _displaySettings.get() : osg::DisplaySettings::instance().get(); }
  652. /** Get the const DisplaySettings that is current active DisplaySettings to be used by osg::State, - if DisplaySettings is not directly assigned then fallback to DisplaySettings::instance(). */
  653. inline const DisplaySettings* getActiveDisplaySettings() const { return _displaySettings.valid() ? _displaySettings.get() : osg::DisplaySettings::instance().get(); }
  654. /** Set flag for early termination of the draw traversal.*/
  655. void setAbortRenderingPtr(bool* abortPtr) { _abortRenderingPtr = abortPtr; }
  656. /** Get flag for early termination of the draw traversal,
  657. * if true steps should be taken to complete rendering early.*/
  658. bool getAbortRendering() const { return _abortRenderingPtr!=0?(*_abortRenderingPtr):false; }
  659. struct DynamicObjectRenderingCompletedCallback : public osg::Referenced
  660. {
  661. virtual void completed(osg::State*) = 0;
  662. };
  663. /** Set the callback to be called when the dynamic object count hits 0.*/
  664. void setDynamicObjectRenderingCompletedCallback(DynamicObjectRenderingCompletedCallback* cb){ _completeDynamicObjectRenderingCallback = cb; }
  665. /** Get the callback to be called when the dynamic object count hits 0.*/
  666. DynamicObjectRenderingCompletedCallback* getDynamicObjectRenderingCompletedCallback() { return _completeDynamicObjectRenderingCallback.get(); }
  667. /** Set the number of dynamic objects that will be rendered in this graphics context this frame.*/
  668. void setDynamicObjectCount(unsigned int count, bool callCallbackOnZero = false)
  669. {
  670. if (_dynamicObjectCount != count)
  671. {
  672. _dynamicObjectCount = count;
  673. if (_dynamicObjectCount==0 && callCallbackOnZero && _completeDynamicObjectRenderingCallback.valid())
  674. {
  675. _completeDynamicObjectRenderingCallback->completed(this);
  676. }
  677. }
  678. }
  679. /** Get the number of dynamic objects that will be rendered in this graphics context this frame.*/
  680. unsigned int getDynamicObjectCount() const { return _dynamicObjectCount; }
  681. /** Decrement the number of dynamic objects left to render this frame, and once the count goes to zero call the
  682. * DynamicObjectRenderingCompletedCallback to inform of completion.*/
  683. inline void decrementDynamicObjectCount()
  684. {
  685. --_dynamicObjectCount;
  686. if (_dynamicObjectCount==0 && _completeDynamicObjectRenderingCallback.valid())
  687. {
  688. _completeDynamicObjectRenderingCallback->completed(this);
  689. }
  690. }
  691. void setMaxTexturePoolSize(unsigned int size);
  692. unsigned int getMaxTexturePoolSize() const { return _maxTexturePoolSize; }
  693. void setMaxBufferObjectPoolSize(unsigned int size);
  694. unsigned int getMaxBufferObjectPoolSize() const { return _maxBufferObjectPoolSize; }
  695. enum CheckForGLErrors
  696. {
  697. /** NEVER_CHECK_GL_ERRORS hints that OpenGL need not be checked for, this
  698. is the fastest option since checking for errors does incur a small overhead.*/
  699. NEVER_CHECK_GL_ERRORS,
  700. /** ONCE_PER_FRAME means that OpenGL errors will be checked for once per
  701. frame, the overhead is still small, but at least OpenGL errors that are occurring
  702. will be caught, the reporting isn't fine grained enough for debugging purposes.*/
  703. ONCE_PER_FRAME,
  704. /** ONCE_PER_ATTRIBUTE means that OpenGL errors will be checked for after
  705. every attribute is applied, allow errors to be directly associated with
  706. particular operations which makes debugging much easier.*/
  707. ONCE_PER_ATTRIBUTE
  708. };
  709. /** Set whether and how often OpenGL errors should be checked for.*/
  710. void setCheckForGLErrors(CheckForGLErrors check) { _checkGLErrors = check; }
  711. /** Get whether and how often OpenGL errors should be checked for.*/
  712. CheckForGLErrors getCheckForGLErrors() const { return _checkGLErrors; }
  713. bool checkGLErrors(const char* str1=0, const char* str2=0) const;
  714. bool checkGLErrors(StateAttribute::GLMode mode) const;
  715. bool checkGLErrors(const StateAttribute* attribute) const;
  716. /** print out the internal details of osg::State - useful for debugging.*/
  717. void print(std::ostream& fout) const;
  718. /** Initialize extension used by osg::State.*/
  719. void initializeExtensionProcs();
  720. /** Get the helper class for dispatching osg::Arrays as OpenGL attribute data.*/
  721. inline AttributeDispatchers& getAttributeDispatchers() { return _arrayDispatchers; }
  722. /** Set the helper class that provides applications with estimate on how much different graphics operations will cost.*/
  723. inline void setGraphicsCostEstimator(GraphicsCostEstimator* gce) { _graphicsCostEstimator = gce; }
  724. /** Get the helper class that provides applications with estimate on how much different graphics operations will cost.*/
  725. inline GraphicsCostEstimator* getGraphicsCostEstimator() { return _graphicsCostEstimator.get(); }
  726. /** Get the cont helper class that provides applications with estimate on how much different graphics operations will cost.*/
  727. inline const GraphicsCostEstimator* getGraphicsCostEstimator() const { return _graphicsCostEstimator.get(); }
  728. /** Support for synchronizing the system time and the timestamp
  729. * counter available with ARB_timer_query. Note that State
  730. * doesn't update these values itself.
  731. */
  732. Timer_t getStartTick() const { return _startTick; }
  733. void setStartTick(Timer_t tick) { _startTick = tick; }
  734. Timer_t getGpuTick() const { return _gpuTick; }
  735. double getGpuTime() const
  736. {
  737. return osg::Timer::instance()->delta_s(_startTick, _gpuTick);
  738. }
  739. GLuint64 getGpuTimestamp() const { return _gpuTimestamp; }
  740. void setGpuTimestamp(Timer_t tick, GLuint64 timestamp)
  741. {
  742. _gpuTick = tick;
  743. _gpuTimestamp = timestamp;
  744. }
  745. int getTimestampBits() const { return _timestampBits; }
  746. void setTimestampBits(int bits) { _timestampBits = bits; }
  747. /** called by the GraphicsContext just before GraphicsContext::swapBuffersImplementation().*/
  748. virtual void frameCompleted();
  749. struct ModeStack
  750. {
  751. typedef std::vector<StateAttribute::GLModeValue> ValueVec;
  752. ModeStack()
  753. {
  754. valid = true;
  755. changed = false;
  756. last_applied_value = false;
  757. global_default_value = false;
  758. }
  759. void print(std::ostream& fout) const;
  760. bool valid;
  761. bool changed;
  762. bool last_applied_value;
  763. bool global_default_value;
  764. ValueVec valueVec;
  765. };
  766. struct AttributeStack
  767. {
  768. AttributeStack()
  769. {
  770. changed = false;
  771. last_applied_attribute = 0L;
  772. last_applied_shadercomponent = 0L;
  773. global_default_attribute = 0L;
  774. }
  775. void print(std::ostream& fout) const;
  776. /** apply an attribute if required, passing in attribute and appropriate attribute stack */
  777. bool changed;
  778. const StateAttribute* last_applied_attribute;
  779. const ShaderComponent* last_applied_shadercomponent;
  780. ref_ptr<const StateAttribute> global_default_attribute;
  781. AttributeVec attributeVec;
  782. };
  783. struct UniformStack
  784. {
  785. typedef std::pair<const Uniform*,StateAttribute::OverrideValue> UniformPair;
  786. typedef std::vector<UniformPair> UniformVec;
  787. UniformStack() {}
  788. void print(std::ostream& fout) const;
  789. UniformVec uniformVec;
  790. };
  791. struct DefineStack
  792. {
  793. typedef std::vector<StateSet::DefinePair> DefineVec;
  794. DefineStack():
  795. changed(false) {}
  796. void print(std::ostream& fout) const;
  797. bool changed;
  798. DefineVec defineVec;
  799. };
  800. struct DefineMap
  801. {
  802. DefineMap():
  803. changed(false) {}
  804. typedef std::map<std::string, DefineStack> DefineStackMap;
  805. DefineStackMap map;
  806. bool changed;
  807. StateSet::DefineList currentDefines;
  808. bool updateCurrentDefines();
  809. };
  810. typedef std::map<StateAttribute::GLMode,ModeStack> ModeMap;
  811. typedef std::vector<ModeMap> TextureModeMapList;
  812. typedef std::map<StateAttribute::TypeMemberPair,AttributeStack> AttributeMap;
  813. typedef std::vector<AttributeMap> TextureAttributeMapList;
  814. typedef std::map<std::string, UniformStack> UniformMap;
  815. typedef std::vector< ref_ptr<const Matrix> > MatrixStack;
  816. inline const ModeMap& getModeMap() const {return _modeMap;}
  817. inline const AttributeMap& getAttributeMap() const {return _attributeMap;}
  818. inline const UniformMap& getUniformMap() const {return _uniformMap;}
  819. inline DefineMap& getDefineMap() {return _defineMap;}
  820. inline const DefineMap& getDefineMap() const {return _defineMap;}
  821. inline const TextureModeMapList& getTextureModeMapList() const {return _textureModeMapList;}
  822. inline const TextureAttributeMapList& getTextureAttributeMapList() const {return _textureAttributeMapList;}
  823. std::string getDefineString(const osg::ShaderDefines& shaderDefines);
  824. bool supportsShaderRequirements(const osg::ShaderDefines& shaderRequirements);
  825. bool supportsShaderRequirement(const std::string& shaderRequirement);
  826. protected:
  827. virtual ~State();
  828. GraphicsContext* _graphicsContext;
  829. unsigned int _contextID;
  830. osg::ref_ptr<VertexArrayState> _globalVertexArrayState;
  831. VertexArrayState* _vas;
  832. bool _shaderCompositionEnabled;
  833. bool _shaderCompositionDirty;
  834. osg::ref_ptr<ShaderComposer> _shaderComposer;
  835. osg::Program* _currentShaderCompositionProgram;
  836. StateSet::UniformList _currentShaderCompositionUniformList;
  837. ref_ptr<FrameStamp> _frameStamp;
  838. GLenum _drawBuffer;
  839. GLenum _readBuffer;
  840. ref_ptr<const RefMatrix> _identity;
  841. ref_ptr<const RefMatrix> _initialViewMatrix;
  842. ref_ptr<const RefMatrix> _projection;
  843. ref_ptr<const RefMatrix> _modelView;
  844. ref_ptr<RefMatrix> _modelViewCache;
  845. bool _useModelViewAndProjectionUniforms;
  846. ref_ptr<Uniform> _modelViewMatrixUniform;
  847. ref_ptr<Uniform> _projectionMatrixUniform;
  848. ref_ptr<Uniform> _modelViewProjectionMatrixUniform;
  849. ref_ptr<Uniform> _normalMatrixUniform;
  850. Matrix _initialInverseViewMatrix;
  851. ref_ptr<DisplaySettings> _displaySettings;
  852. bool* _abortRenderingPtr;
  853. CheckForGLErrors _checkGLErrors;
  854. bool _useVertexAttributeAliasing;
  855. VertexAttribAlias _vertexAlias;
  856. VertexAttribAlias _normalAlias;
  857. VertexAttribAlias _colorAlias;
  858. VertexAttribAlias _secondaryColorAlias;
  859. VertexAttribAlias _fogCoordAlias;
  860. VertexAttribAliasList _texCoordAliasList;
  861. Program::AttribBindingList _attributeBindingList;
  862. void setUpVertexAttribAlias(VertexAttribAlias& alias, GLuint location, const std::string glName, const std::string osgName, const std::string& declaration);
  863. /** Apply an OpenGL mode if required, passing in mode, enable flag and
  864. * appropriate mode stack. This is a wrapper around \c glEnable() and
  865. * \c glDisable(), that just actually calls these functions if the
  866. * \c enabled flag is different than the current state.
  867. * @return \c true if the state was actually changed. \c false
  868. * otherwise. Notice that a \c false return does not indicate
  869. * an error, it just means that the mode was already set to the
  870. * same value as the \c enabled parameter.
  871. */
  872. inline bool applyMode(StateAttribute::GLMode mode,bool enabled,ModeStack& ms)
  873. {
  874. if (ms.valid && ms.last_applied_value != enabled)
  875. {
  876. ms.last_applied_value = enabled;
  877. if (enabled) glEnable(mode);
  878. else glDisable(mode);
  879. if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(mode);
  880. return true;
  881. }
  882. else
  883. return false;
  884. }
  885. inline bool applyModeOnTexUnit(unsigned int unit,StateAttribute::GLMode mode,bool enabled,ModeStack& ms)
  886. {
  887. if (ms.valid && ms.last_applied_value != enabled)
  888. {
  889. if (setActiveTextureUnit(unit))
  890. {
  891. ms.last_applied_value = enabled;
  892. if (enabled) glEnable(mode);
  893. else glDisable(mode);
  894. if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(mode);
  895. return true;
  896. }
  897. else
  898. return false;
  899. }
  900. else
  901. return false;
  902. }
  903. /** apply an attribute if required, passing in attribute and appropriate attribute stack */
  904. inline bool applyAttribute(const StateAttribute* attribute,AttributeStack& as)
  905. {
  906. if (as.last_applied_attribute != attribute)
  907. {
  908. if (!as.global_default_attribute.valid()) as.global_default_attribute = attribute->cloneType()->asStateAttribute();
  909. as.last_applied_attribute = attribute;
  910. attribute->apply(*this);
  911. const ShaderComponent* sc = attribute->getShaderComponent();
  912. if (as.last_applied_shadercomponent != sc)
  913. {
  914. as.last_applied_shadercomponent = sc;
  915. _shaderCompositionDirty = true;
  916. }
  917. if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(attribute);
  918. return true;
  919. }
  920. else
  921. return false;
  922. }
  923. inline bool applyAttributeOnTexUnit(unsigned int unit,const StateAttribute* attribute,AttributeStack& as)
  924. {
  925. if (as.last_applied_attribute != attribute)
  926. {
  927. if (setActiveTextureUnit(unit))
  928. {
  929. if (!as.global_default_attribute.valid()) as.global_default_attribute = attribute->cloneType()->asStateAttribute();
  930. as.last_applied_attribute = attribute;
  931. attribute->apply(*this);
  932. const ShaderComponent* sc = attribute->getShaderComponent();
  933. if (as.last_applied_shadercomponent != sc)
  934. {
  935. as.last_applied_shadercomponent = sc;
  936. _shaderCompositionDirty = true;
  937. }
  938. if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(attribute);
  939. return true;
  940. }
  941. else
  942. return false;
  943. }
  944. else
  945. return false;
  946. }
  947. inline bool applyGlobalDefaultAttribute(AttributeStack& as)
  948. {
  949. if (as.last_applied_attribute != as.global_default_attribute.get())
  950. {
  951. as.last_applied_attribute = as.global_default_attribute.get();
  952. if (as.global_default_attribute.valid())
  953. {
  954. as.global_default_attribute->apply(*this);
  955. const ShaderComponent* sc = as.global_default_attribute->getShaderComponent();
  956. if (as.last_applied_shadercomponent != sc)
  957. {
  958. as.last_applied_shadercomponent = sc;
  959. _shaderCompositionDirty = true;
  960. }
  961. if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(as.global_default_attribute.get());
  962. }
  963. return true;
  964. }
  965. else
  966. return false;
  967. }
  968. inline bool applyGlobalDefaultAttributeOnTexUnit(unsigned int unit,AttributeStack& as)
  969. {
  970. if (as.last_applied_attribute != as.global_default_attribute.get())
  971. {
  972. if (setActiveTextureUnit(unit))
  973. {
  974. as.last_applied_attribute = as.global_default_attribute.get();
  975. if (as.global_default_attribute.valid())
  976. {
  977. as.global_default_attribute->apply(*this);
  978. const ShaderComponent* sc = as.global_default_attribute->getShaderComponent();
  979. if (as.last_applied_shadercomponent != sc)
  980. {
  981. as.last_applied_shadercomponent = sc;
  982. _shaderCompositionDirty = true;
  983. }
  984. if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(as.global_default_attribute.get());
  985. }
  986. return true;
  987. }
  988. else
  989. return false;
  990. }
  991. else
  992. return false;
  993. }
  994. ModeMap _modeMap;
  995. AttributeMap _attributeMap;
  996. UniformMap _uniformMap;
  997. DefineMap _defineMap;
  998. TextureModeMapList _textureModeMapList;
  999. TextureAttributeMapList _textureAttributeMapList;
  1000. const Program::PerContextProgram* _lastAppliedProgramObject;
  1001. StateSetStack _stateStateStack;
  1002. unsigned int _maxTexturePoolSize;
  1003. unsigned int _maxBufferObjectPoolSize;
  1004. unsigned int _currentActiveTextureUnit;
  1005. unsigned int _currentClientActiveTextureUnit;
  1006. GLBufferObject* _currentPBO;
  1007. GLBufferObject* _currentDIBO;
  1008. GLuint _currentVAO;
  1009. inline ModeMap& getOrCreateTextureModeMap(unsigned int unit)
  1010. {
  1011. if (unit>=_textureModeMapList.size()) _textureModeMapList.resize(unit+1);
  1012. return _textureModeMapList[unit];
  1013. }
  1014. inline AttributeMap& getOrCreateTextureAttributeMap(unsigned int unit)
  1015. {
  1016. if (unit>=_textureAttributeMapList.size()) _textureAttributeMapList.resize(unit+1);
  1017. return _textureAttributeMapList[unit];
  1018. }
  1019. inline void pushModeList(ModeMap& modeMap,const StateSet::ModeList& modeList);
  1020. inline void pushAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList);
  1021. inline void pushUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList);
  1022. inline void pushDefineList(DefineMap& defineMap,const StateSet::DefineList& defineList);
  1023. inline void popModeList(ModeMap& modeMap,const StateSet::ModeList& modeList);
  1024. inline void popAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList);
  1025. inline void popUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList);
  1026. inline void popDefineList(DefineMap& uniformMap,const StateSet::DefineList& defineList);
  1027. inline void applyModeList(ModeMap& modeMap,const StateSet::ModeList& modeList);
  1028. inline void applyAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList);
  1029. inline void applyUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList);
  1030. inline void applyDefineList(DefineMap& uniformMap,const StateSet::DefineList& defineList);
  1031. inline void applyModeMap(ModeMap& modeMap);
  1032. inline void applyAttributeMap(AttributeMap& attributeMap);
  1033. inline void applyUniformMap(UniformMap& uniformMap);
  1034. inline void applyModeListOnTexUnit(unsigned int unit,ModeMap& modeMap,const StateSet::ModeList& modeList);
  1035. inline void applyAttributeListOnTexUnit(unsigned int unit,AttributeMap& attributeMap,const StateSet::AttributeList& attributeList);
  1036. inline void applyModeMapOnTexUnit(unsigned int unit,ModeMap& modeMap);
  1037. inline void applyAttributeMapOnTexUnit(unsigned int unit,AttributeMap& attributeMap);
  1038. void haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode,StateAttribute::GLModeValue value);
  1039. void haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode);
  1040. void haveAppliedAttribute(AttributeMap& attributeMap,const StateAttribute* attribute);
  1041. void haveAppliedAttribute(AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member);
  1042. bool getLastAppliedMode(const ModeMap& modeMap,StateAttribute::GLMode mode) const;
  1043. const StateAttribute* getLastAppliedAttribute(const AttributeMap& attributeMap,StateAttribute::Type type, unsigned int member) const;
  1044. void loadModelViewMatrix();
  1045. bool _isSecondaryColorSupported;
  1046. bool _isFogCoordSupported;
  1047. bool _isVertexBufferObjectSupported;
  1048. bool _isVertexArrayObjectSupported;
  1049. bool _forceVertexBufferObject;
  1050. bool _forceVertexArrayObject;
  1051. typedef void (GL_APIENTRY * ActiveTextureProc) (GLenum texture);
  1052. typedef void (GL_APIENTRY * FogCoordPointerProc) (GLenum type, GLsizei stride, const GLvoid *pointer);
  1053. typedef void (GL_APIENTRY * SecondaryColorPointerProc) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
  1054. typedef void (GL_APIENTRY * MultiTexCoord4fProc) (GLenum target, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
  1055. typedef void (GL_APIENTRY * VertexAttrib4fProc)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
  1056. typedef void (GL_APIENTRY * VertexAttrib4fvProc)(GLuint index, const GLfloat *v);
  1057. typedef void (GL_APIENTRY * VertexAttribPointerProc) (unsigned int, GLint, GLenum, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
  1058. typedef void (GL_APIENTRY * VertexAttribIPointerProc) (unsigned int, GLint, GLenum, GLsizei stride, const GLvoid *pointer);
  1059. typedef void (GL_APIENTRY * VertexAttribLPointerProc) (unsigned int, GLint, GLenum, GLsizei stride, const GLvoid *pointer);
  1060. typedef void (GL_APIENTRY * EnableVertexAttribProc) (unsigned int);
  1061. typedef void (GL_APIENTRY * DisableVertexAttribProc) (unsigned int);
  1062. typedef void (GL_APIENTRY * BindBufferProc) (GLenum target, GLuint buffer);
  1063. typedef void (GL_APIENTRY * DrawArraysInstancedProc)( GLenum mode, GLint first, GLsizei count, GLsizei primcount );
  1064. typedef void (GL_APIENTRY * DrawElementsInstancedProc)( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount );
  1065. bool _extensionProcsInitialized;
  1066. GLint _glMaxTextureCoords;
  1067. GLint _glMaxTextureUnits;
  1068. ActiveTextureProc _glClientActiveTexture;
  1069. ActiveTextureProc _glActiveTexture;
  1070. MultiTexCoord4fProc _glMultiTexCoord4f;
  1071. VertexAttrib4fProc _glVertexAttrib4f;
  1072. VertexAttrib4fvProc _glVertexAttrib4fv;
  1073. FogCoordPointerProc _glFogCoordPointer;
  1074. SecondaryColorPointerProc _glSecondaryColorPointer;
  1075. VertexAttribPointerProc _glVertexAttribPointer;
  1076. VertexAttribIPointerProc _glVertexAttribIPointer;
  1077. VertexAttribLPointerProc _glVertexAttribLPointer;
  1078. EnableVertexAttribProc _glEnableVertexAttribArray;
  1079. DisableVertexAttribProc _glDisableVertexAttribArray;
  1080. BindBufferProc _glBindBuffer;
  1081. DrawArraysInstancedProc _glDrawArraysInstanced;
  1082. DrawElementsInstancedProc _glDrawElementsInstanced;
  1083. osg::ref_ptr<GLExtensions> _glExtensions;
  1084. unsigned int _dynamicObjectCount;
  1085. osg::ref_ptr<DynamicObjectRenderingCompletedCallback> _completeDynamicObjectRenderingCallback;
  1086. AttributeDispatchers _arrayDispatchers;
  1087. osg::ref_ptr<GraphicsCostEstimator> _graphicsCostEstimator;
  1088. Timer_t _startTick;
  1089. Timer_t _gpuTick;
  1090. GLuint64 _gpuTimestamp;
  1091. int _timestampBits;
  1092. };
  1093. inline void State::pushModeList(ModeMap& modeMap,const StateSet::ModeList& modeList)
  1094. {
  1095. for(StateSet::ModeList::const_iterator mitr=modeList.begin();
  1096. mitr!=modeList.end();
  1097. ++mitr)
  1098. {
  1099. // get the mode stack for incoming GLmode {mitr->first}.
  1100. ModeStack& ms = modeMap[mitr->first];
  1101. if (ms.valueVec.empty())
  1102. {
  1103. // first pair so simply push incoming pair to back.
  1104. ms.valueVec.push_back(mitr->second);
  1105. }
  1106. else if ((ms.valueVec.back() & StateAttribute::OVERRIDE) && !(mitr->second & StateAttribute::PROTECTED)) // check the existing override flag
  1107. {
  1108. // push existing back since override keeps the previous value.
  1109. ms.valueVec.push_back(ms.valueVec.back());
  1110. }
  1111. else
  1112. {
  1113. // no override on so simply push incoming pair to back.
  1114. ms.valueVec.push_back(mitr->second);
  1115. }
  1116. ms.changed = true;
  1117. }
  1118. }
  1119. inline void State::pushAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList)
  1120. {
  1121. for(StateSet::AttributeList::const_iterator aitr=attributeList.begin();
  1122. aitr!=attributeList.end();
  1123. ++aitr)
  1124. {
  1125. // get the attribute stack for incoming type {aitr->first}.
  1126. AttributeStack& as = attributeMap[aitr->first];
  1127. if (as.attributeVec.empty())
  1128. {
  1129. // first pair so simply push incoming pair to back.
  1130. as.attributeVec.push_back(
  1131. AttributePair(aitr->second.first.get(),aitr->second.second));
  1132. }
  1133. else if ((as.attributeVec.back().second & StateAttribute::OVERRIDE) && !(aitr->second.second & StateAttribute::PROTECTED)) // check the existing override flag
  1134. {
  1135. // push existing back since override keeps the previous value.
  1136. as.attributeVec.push_back(as.attributeVec.back());
  1137. }
  1138. else
  1139. {
  1140. // no override on so simply push incoming pair to back.
  1141. as.attributeVec.push_back(
  1142. AttributePair(aitr->second.first.get(),aitr->second.second));
  1143. }
  1144. as.changed = true;
  1145. }
  1146. }
  1147. inline void State::pushUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)
  1148. {
  1149. for(StateSet::UniformList::const_iterator aitr=uniformList.begin();
  1150. aitr!=uniformList.end();
  1151. ++aitr)
  1152. {
  1153. // get the attribute stack for incoming type {aitr->first}.
  1154. UniformStack& us = uniformMap[aitr->first];
  1155. if (us.uniformVec.empty())
  1156. {
  1157. // first pair so simply push incoming pair to back.
  1158. us.uniformVec.push_back(
  1159. UniformStack::UniformPair(aitr->second.first.get(),aitr->second.second));
  1160. }
  1161. else if ((us.uniformVec.back().second & StateAttribute::OVERRIDE) && !(aitr->second.second & StateAttribute::PROTECTED)) // check the existing override flag
  1162. {
  1163. // push existing back since override keeps the previous value.
  1164. us.uniformVec.push_back(us.uniformVec.back());
  1165. }
  1166. else
  1167. {
  1168. // no override on so simply push incoming pair to back.
  1169. us.uniformVec.push_back(
  1170. UniformStack::UniformPair(aitr->second.first.get(),aitr->second.second));
  1171. }
  1172. }
  1173. }
  1174. inline void State::pushDefineList(DefineMap& defineMap,const StateSet::DefineList& defineList)
  1175. {
  1176. for(StateSet::DefineList::const_iterator aitr=defineList.begin();
  1177. aitr!=defineList.end();
  1178. ++aitr)
  1179. {
  1180. // get the attribute stack for incoming type {aitr->first}.
  1181. DefineStack& ds = defineMap.map[aitr->first];
  1182. DefineStack::DefineVec& dv = ds.defineVec;
  1183. if (dv.empty())
  1184. {
  1185. // first pair so simply push incoming pair to back.
  1186. dv.push_back(StateSet::DefinePair(aitr->second.first,aitr->second.second));
  1187. ds.changed = true;
  1188. defineMap.changed = true;
  1189. }
  1190. else if ((ds.defineVec.back().second & StateAttribute::OVERRIDE) && !(aitr->second.second & StateAttribute::PROTECTED)) // check the existing override flag
  1191. {
  1192. // push existing back since override keeps the previous value.
  1193. ds.defineVec.push_back(ds.defineVec.back());
  1194. }
  1195. else
  1196. {
  1197. // no override on so simply push incoming pair to back.
  1198. dv.push_back(StateSet::DefinePair(aitr->second.first,aitr->second.second));
  1199. // if the back of the stack has changed since the last then mark it as changed.
  1200. bool changed = (dv[dv.size()-2] != dv.back());
  1201. if (changed)
  1202. {
  1203. ds.changed = true;
  1204. defineMap.changed = true;
  1205. }
  1206. }
  1207. }
  1208. }
  1209. inline void State::popModeList(ModeMap& modeMap,const StateSet::ModeList& modeList)
  1210. {
  1211. for(StateSet::ModeList::const_iterator mitr=modeList.begin();
  1212. mitr!=modeList.end();
  1213. ++mitr)
  1214. {
  1215. // get the mode stack for incoming GLmode {mitr->first}.
  1216. ModeStack& ms = modeMap[mitr->first];
  1217. if (!ms.valueVec.empty())
  1218. {
  1219. ms.valueVec.pop_back();
  1220. }
  1221. ms.changed = true;
  1222. }
  1223. }
  1224. inline void State::popAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList)
  1225. {
  1226. for(StateSet::AttributeList::const_iterator aitr=attributeList.begin();
  1227. aitr!=attributeList.end();
  1228. ++aitr)
  1229. {
  1230. // get the attribute stack for incoming type {aitr->first}.
  1231. AttributeStack& as = attributeMap[aitr->first];
  1232. if (!as.attributeVec.empty())
  1233. {
  1234. as.attributeVec.pop_back();
  1235. }
  1236. as.changed = true;
  1237. }
  1238. }
  1239. inline void State::popUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)
  1240. {
  1241. for(StateSet::UniformList::const_iterator aitr=uniformList.begin();
  1242. aitr!=uniformList.end();
  1243. ++aitr)
  1244. {
  1245. // get the attribute stack for incoming type {aitr->first}.
  1246. UniformStack& us = uniformMap[aitr->first];
  1247. if (!us.uniformVec.empty())
  1248. {
  1249. us.uniformVec.pop_back();
  1250. }
  1251. }
  1252. }
  1253. inline void State::popDefineList(DefineMap& defineMap,const StateSet::DefineList& defineList)
  1254. {
  1255. for(StateSet::DefineList::const_iterator aitr=defineList.begin();
  1256. aitr!=defineList.end();
  1257. ++aitr)
  1258. {
  1259. // get the attribute stack for incoming type {aitr->first}.
  1260. DefineStack& ds = defineMap.map[aitr->first];
  1261. DefineStack::DefineVec& dv = ds.defineVec;
  1262. if (!dv.empty())
  1263. {
  1264. // if the stack has less than 2 entries or new back vs old back are different then mark the DefineStack as changed
  1265. if ((dv.size() < 2) || (dv[dv.size()-2] != dv.back()))
  1266. {
  1267. ds.changed = true;
  1268. defineMap.changed = true;
  1269. }
  1270. dv.pop_back();
  1271. }
  1272. }
  1273. }
  1274. inline void State::applyModeList(ModeMap& modeMap,const StateSet::ModeList& modeList)
  1275. {
  1276. StateSet::ModeList::const_iterator ds_mitr = modeList.begin();
  1277. ModeMap::iterator this_mitr=modeMap.begin();
  1278. while (this_mitr!=modeMap.end() && ds_mitr!=modeList.end())
  1279. {
  1280. if (this_mitr->first<ds_mitr->first)
  1281. {
  1282. // note GLMode = this_mitr->first
  1283. ModeStack& ms = this_mitr->second;
  1284. if (ms.changed)
  1285. {
  1286. ms.changed = false;
  1287. if (!ms.valueVec.empty())
  1288. {
  1289. bool new_value = ms.valueVec.back() & StateAttribute::ON;
  1290. applyMode(this_mitr->first,new_value,ms);
  1291. }
  1292. else
  1293. {
  1294. // assume default of disabled.
  1295. applyMode(this_mitr->first,ms.global_default_value,ms);
  1296. }
  1297. }
  1298. ++this_mitr;
  1299. }
  1300. else if (ds_mitr->first<this_mitr->first)
  1301. {
  1302. // ds_mitr->first is a new mode, therefore
  1303. // need to insert a new mode entry for ds_mistr->first.
  1304. ModeStack& ms = modeMap[ds_mitr->first];
  1305. bool new_value = ds_mitr->second & StateAttribute::ON;
  1306. applyMode(ds_mitr->first,new_value,ms);
  1307. // will need to disable this mode on next apply so set it to changed.
  1308. ms.changed = true;
  1309. ++ds_mitr;
  1310. }
  1311. else
  1312. {
  1313. // this_mitr & ds_mitr refer to the same mode, check the override
  1314. // if any otherwise just apply the incoming mode.
  1315. ModeStack& ms = this_mitr->second;
  1316. if (!ms.valueVec.empty() && (ms.valueVec.back() & StateAttribute::OVERRIDE) && !(ds_mitr->second & StateAttribute::PROTECTED))
  1317. {
  1318. // override is on, just treat as a normal apply on modes.
  1319. if (ms.changed)
  1320. {
  1321. ms.changed = false;
  1322. bool new_value = ms.valueVec.back() & StateAttribute::ON;
  1323. applyMode(this_mitr->first,new_value,ms);
  1324. }
  1325. }
  1326. else
  1327. {
  1328. // no override on or no previous entry, therefore consider incoming mode.
  1329. bool new_value = ds_mitr->second & StateAttribute::ON;
  1330. if (applyMode(ds_mitr->first,new_value,ms))
  1331. {
  1332. ms.changed = true;
  1333. }
  1334. }
  1335. ++this_mitr;
  1336. ++ds_mitr;
  1337. }
  1338. }
  1339. // iterator over the remaining state modes to apply any previous changes.
  1340. for(;
  1341. this_mitr!=modeMap.end();
  1342. ++this_mitr)
  1343. {
  1344. // note GLMode = this_mitr->first
  1345. ModeStack& ms = this_mitr->second;
  1346. if (ms.changed)
  1347. {
  1348. ms.changed = false;
  1349. if (!ms.valueVec.empty())
  1350. {
  1351. bool new_value = ms.valueVec.back() & StateAttribute::ON;
  1352. applyMode(this_mitr->first,new_value,ms);
  1353. }
  1354. else
  1355. {
  1356. // assume default of disabled.
  1357. applyMode(this_mitr->first,ms.global_default_value,ms);
  1358. }
  1359. }
  1360. }
  1361. // iterator over the remaining incoming modes to apply any new mode.
  1362. for(;
  1363. ds_mitr!=modeList.end();
  1364. ++ds_mitr)
  1365. {
  1366. ModeStack& ms = modeMap[ds_mitr->first];
  1367. bool new_value = ds_mitr->second & StateAttribute::ON;
  1368. applyMode(ds_mitr->first,new_value,ms);
  1369. // will need to disable this mode on next apply so set it to changed.
  1370. ms.changed = true;
  1371. }
  1372. }
  1373. inline void State::applyModeListOnTexUnit(unsigned int unit,ModeMap& modeMap,const StateSet::ModeList& modeList)
  1374. {
  1375. StateSet::ModeList::const_iterator ds_mitr = modeList.begin();
  1376. ModeMap::iterator this_mitr=modeMap.begin();
  1377. while (this_mitr!=modeMap.end() && ds_mitr!=modeList.end())
  1378. {
  1379. if (this_mitr->first<ds_mitr->first)
  1380. {
  1381. // note GLMode = this_mitr->first
  1382. ModeStack& ms = this_mitr->second;
  1383. if (ms.changed)
  1384. {
  1385. ms.changed = false;
  1386. if (!ms.valueVec.empty())
  1387. {
  1388. bool new_value = ms.valueVec.back() & StateAttribute::ON;
  1389. applyModeOnTexUnit(unit,this_mitr->first,new_value,ms);
  1390. }
  1391. else
  1392. {
  1393. // assume default of disabled.
  1394. applyModeOnTexUnit(unit,this_mitr->first,ms.global_default_value,ms);
  1395. }
  1396. }
  1397. ++this_mitr;
  1398. }
  1399. else if (ds_mitr->first<this_mitr->first)
  1400. {
  1401. // ds_mitr->first is a new mode, therefore
  1402. // need to insert a new mode entry for ds_mistr->first.
  1403. ModeStack& ms = modeMap[ds_mitr->first];
  1404. bool new_value = ds_mitr->second & StateAttribute::ON;
  1405. applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms);
  1406. // will need to disable this mode on next apply so set it to changed.
  1407. ms.changed = true;
  1408. ++ds_mitr;
  1409. }
  1410. else
  1411. {
  1412. // this_mitr & ds_mitr refer to the same mode, check the override
  1413. // if any otherwise just apply the incoming mode.
  1414. ModeStack& ms = this_mitr->second;
  1415. if (!ms.valueVec.empty() && (ms.valueVec.back() & StateAttribute::OVERRIDE) && !(ds_mitr->second & StateAttribute::PROTECTED))
  1416. {
  1417. // override is on, just treat as a normal apply on modes.
  1418. if (ms.changed)
  1419. {
  1420. ms.changed = false;
  1421. bool new_value = ms.valueVec.back() & StateAttribute::ON;
  1422. applyModeOnTexUnit(unit,this_mitr->first,new_value,ms);
  1423. }
  1424. }
  1425. else
  1426. {
  1427. // no override on or no previous entry, therefore consider incoming mode.
  1428. bool new_value = ds_mitr->second & StateAttribute::ON;
  1429. if (applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms))
  1430. {
  1431. ms.changed = true;
  1432. }
  1433. }
  1434. ++this_mitr;
  1435. ++ds_mitr;
  1436. }
  1437. }
  1438. // iterator over the remaining state modes to apply any previous changes.
  1439. for(;
  1440. this_mitr!=modeMap.end();
  1441. ++this_mitr)
  1442. {
  1443. // note GLMode = this_mitr->first
  1444. ModeStack& ms = this_mitr->second;
  1445. if (ms.changed)
  1446. {
  1447. ms.changed = false;
  1448. if (!ms.valueVec.empty())
  1449. {
  1450. bool new_value = ms.valueVec.back() & StateAttribute::ON;
  1451. applyModeOnTexUnit(unit,this_mitr->first,new_value,ms);
  1452. }
  1453. else
  1454. {
  1455. // assume default of disabled.
  1456. applyModeOnTexUnit(unit,this_mitr->first,ms.global_default_value,ms);
  1457. }
  1458. }
  1459. }
  1460. // iterator over the remaining incoming modes to apply any new mode.
  1461. for(;
  1462. ds_mitr!=modeList.end();
  1463. ++ds_mitr)
  1464. {
  1465. ModeStack& ms = modeMap[ds_mitr->first];
  1466. bool new_value = ds_mitr->second & StateAttribute::ON;
  1467. applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms);
  1468. // will need to disable this mode on next apply so set it to changed.
  1469. ms.changed = true;
  1470. }
  1471. }
  1472. inline void State::applyAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList)
  1473. {
  1474. StateSet::AttributeList::const_iterator ds_aitr=attributeList.begin();
  1475. AttributeMap::iterator this_aitr=attributeMap.begin();
  1476. while (this_aitr!=attributeMap.end() && ds_aitr!=attributeList.end())
  1477. {
  1478. if (this_aitr->first<ds_aitr->first)
  1479. {
  1480. // note attribute type = this_aitr->first
  1481. AttributeStack& as = this_aitr->second;
  1482. if (as.changed)
  1483. {
  1484. as.changed = false;
  1485. if (!as.attributeVec.empty())
  1486. {
  1487. const StateAttribute* new_attr = as.attributeVec.back().first;
  1488. applyAttribute(new_attr,as);
  1489. }
  1490. else
  1491. {
  1492. applyGlobalDefaultAttribute(as);
  1493. }
  1494. }
  1495. ++this_aitr;
  1496. }
  1497. else if (ds_aitr->first<this_aitr->first)
  1498. {
  1499. // ds_aitr->first is a new attribute, therefore
  1500. // need to insert a new attribute entry for ds_aitr->first.
  1501. AttributeStack& as = attributeMap[ds_aitr->first];
  1502. const StateAttribute* new_attr = ds_aitr->second.first.get();
  1503. applyAttribute(new_attr,as);
  1504. as.changed = true;
  1505. ++ds_aitr;
  1506. }
  1507. else
  1508. {
  1509. // this_mitr & ds_mitr refer to the same attribute, check the override
  1510. // if any otherwise just apply the incoming attribute
  1511. AttributeStack& as = this_aitr->second;
  1512. if (!as.attributeVec.empty() && (as.attributeVec.back().second & StateAttribute::OVERRIDE) && !(ds_aitr->second.second & StateAttribute::PROTECTED))
  1513. {
  1514. // override is on, just treat as a normal apply on attribute.
  1515. if (as.changed)
  1516. {
  1517. as.changed = false;
  1518. const StateAttribute* new_attr = as.attributeVec.back().first;
  1519. applyAttribute(new_attr,as);
  1520. }
  1521. }
  1522. else
  1523. {
  1524. // no override on or no previous entry, therefore consider incoming attribute.
  1525. const StateAttribute* new_attr = ds_aitr->second.first.get();
  1526. if (applyAttribute(new_attr,as))
  1527. {
  1528. as.changed = true;
  1529. }
  1530. }
  1531. ++this_aitr;
  1532. ++ds_aitr;
  1533. }
  1534. }
  1535. // iterator over the remaining state attributes to apply any previous changes.
  1536. for(;
  1537. this_aitr!=attributeMap.end();
  1538. ++this_aitr)
  1539. {
  1540. // note attribute type = this_aitr->first
  1541. AttributeStack& as = this_aitr->second;
  1542. if (as.changed)
  1543. {
  1544. as.changed = false;
  1545. if (!as.attributeVec.empty())
  1546. {
  1547. const StateAttribute* new_attr = as.attributeVec.back().first;
  1548. applyAttribute(new_attr,as);
  1549. }
  1550. else
  1551. {
  1552. applyGlobalDefaultAttribute(as);
  1553. }
  1554. }
  1555. }
  1556. // iterator over the remaining incoming attribute to apply any new attribute.
  1557. for(;
  1558. ds_aitr!=attributeList.end();
  1559. ++ds_aitr)
  1560. {
  1561. // ds_aitr->first is a new attribute, therefore
  1562. // need to insert a new attribute entry for ds_aitr->first.
  1563. AttributeStack& as = attributeMap[ds_aitr->first];
  1564. const StateAttribute* new_attr = ds_aitr->second.first.get();
  1565. applyAttribute(new_attr,as);
  1566. // will need to update this attribute on next apply so set it to changed.
  1567. as.changed = true;
  1568. }
  1569. }
  1570. inline void State::applyAttributeListOnTexUnit(unsigned int unit,AttributeMap& attributeMap,const StateSet::AttributeList& attributeList)
  1571. {
  1572. StateSet::AttributeList::const_iterator ds_aitr=attributeList.begin();
  1573. AttributeMap::iterator this_aitr=attributeMap.begin();
  1574. while (this_aitr!=attributeMap.end() && ds_aitr!=attributeList.end())
  1575. {
  1576. if (this_aitr->first<ds_aitr->first)
  1577. {
  1578. // note attribute type = this_aitr->first
  1579. AttributeStack& as = this_aitr->second;
  1580. if (as.changed)
  1581. {
  1582. as.changed = false;
  1583. if (!as.attributeVec.empty())
  1584. {
  1585. const StateAttribute* new_attr = as.attributeVec.back().first;
  1586. applyAttributeOnTexUnit(unit,new_attr,as);
  1587. }
  1588. else
  1589. {
  1590. applyGlobalDefaultAttributeOnTexUnit(unit,as);
  1591. }
  1592. }
  1593. ++this_aitr;
  1594. }
  1595. else if (ds_aitr->first<this_aitr->first)
  1596. {
  1597. // ds_aitr->first is a new attribute, therefore
  1598. // need to insert a new attribute entry for ds_aitr->first.
  1599. AttributeStack& as = attributeMap[ds_aitr->first];
  1600. const StateAttribute* new_attr = ds_aitr->second.first.get();
  1601. applyAttributeOnTexUnit(unit,new_attr,as);
  1602. as.changed = true;
  1603. ++ds_aitr;
  1604. }
  1605. else
  1606. {
  1607. // this_mitr & ds_mitr refer to the same attribute, check the override
  1608. // if any otherwise just apply the incoming attribute
  1609. AttributeStack& as = this_aitr->second;
  1610. if (!as.attributeVec.empty() && (as.attributeVec.back().second & StateAttribute::OVERRIDE) && !(ds_aitr->second.second & StateAttribute::PROTECTED))
  1611. {
  1612. // override is on, just treat as a normal apply on attribute.
  1613. if (as.changed)
  1614. {
  1615. as.changed = false;
  1616. const StateAttribute* new_attr = as.attributeVec.back().first;
  1617. applyAttributeOnTexUnit(unit,new_attr,as);
  1618. }
  1619. }
  1620. else
  1621. {
  1622. // no override on or no previous entry, therefore consider incoming attribute.
  1623. const StateAttribute* new_attr = ds_aitr->second.first.get();
  1624. if (applyAttributeOnTexUnit(unit,new_attr,as))
  1625. {
  1626. as.changed = true;
  1627. }
  1628. }
  1629. ++this_aitr;
  1630. ++ds_aitr;
  1631. }
  1632. }
  1633. // iterator over the remaining state attributes to apply any previous changes.
  1634. for(;
  1635. this_aitr!=attributeMap.end();
  1636. ++this_aitr)
  1637. {
  1638. // note attribute type = this_aitr->first
  1639. AttributeStack& as = this_aitr->second;
  1640. if (as.changed)
  1641. {
  1642. as.changed = false;
  1643. if (!as.attributeVec.empty())
  1644. {
  1645. const StateAttribute* new_attr = as.attributeVec.back().first;
  1646. applyAttributeOnTexUnit(unit,new_attr,as);
  1647. }
  1648. else
  1649. {
  1650. applyGlobalDefaultAttributeOnTexUnit(unit,as);
  1651. }
  1652. }
  1653. }
  1654. // iterator over the remaining incoming attribute to apply any new attribute.
  1655. for(;
  1656. ds_aitr!=attributeList.end();
  1657. ++ds_aitr)
  1658. {
  1659. // ds_aitr->first is a new attribute, therefore
  1660. // need to insert a new attribute entry for ds_aitr->first.
  1661. AttributeStack& as = attributeMap[ds_aitr->first];
  1662. const StateAttribute* new_attr = ds_aitr->second.first.get();
  1663. applyAttributeOnTexUnit(unit,new_attr,as);
  1664. // will need to update this attribute on next apply so set it to changed.
  1665. as.changed = true;
  1666. }
  1667. }
  1668. inline void State::applyUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)
  1669. {
  1670. if (!_lastAppliedProgramObject) return;
  1671. StateSet::UniformList::const_iterator ds_aitr=uniformList.begin();
  1672. UniformMap::iterator this_aitr=uniformMap.begin();
  1673. while (this_aitr!=uniformMap.end() && ds_aitr!=uniformList.end())
  1674. {
  1675. if (this_aitr->first<ds_aitr->first)
  1676. {
  1677. // note attribute type = this_aitr->first
  1678. UniformStack& as = this_aitr->second;
  1679. if (!as.uniformVec.empty())
  1680. {
  1681. _lastAppliedProgramObject->apply(*as.uniformVec.back().first);
  1682. }
  1683. ++this_aitr;
  1684. }
  1685. else if (ds_aitr->first<this_aitr->first)
  1686. {
  1687. _lastAppliedProgramObject->apply(*(ds_aitr->second.first.get()));
  1688. ++ds_aitr;
  1689. }
  1690. else
  1691. {
  1692. // this_mitr & ds_mitr refer to the same attribute, check the override
  1693. // if any otherwise just apply the incoming attribute
  1694. UniformStack& as = this_aitr->second;
  1695. if (!as.uniformVec.empty() && (as.uniformVec.back().second & StateAttribute::OVERRIDE) && !(ds_aitr->second.second & StateAttribute::PROTECTED))
  1696. {
  1697. // override is on, just treat as a normal apply on uniform.
  1698. _lastAppliedProgramObject->apply(*as.uniformVec.back().first);
  1699. }
  1700. else
  1701. {
  1702. // no override on or no previous entry, therefore consider incoming attribute.
  1703. _lastAppliedProgramObject->apply(*(ds_aitr->second.first.get()));
  1704. }
  1705. ++this_aitr;
  1706. ++ds_aitr;
  1707. }
  1708. }
  1709. // iterator over the remaining state attributes to apply any previous changes.
  1710. for(;
  1711. this_aitr!=uniformMap.end();
  1712. ++this_aitr)
  1713. {
  1714. // note attribute type = this_aitr->first
  1715. UniformStack& as = this_aitr->second;
  1716. if (!as.uniformVec.empty())
  1717. {
  1718. _lastAppliedProgramObject->apply(*as.uniformVec.back().first);
  1719. }
  1720. }
  1721. // iterator over the remaining incoming attribute to apply any new attribute.
  1722. for(;
  1723. ds_aitr!=uniformList.end();
  1724. ++ds_aitr)
  1725. {
  1726. _lastAppliedProgramObject->apply(*(ds_aitr->second.first.get()));
  1727. }
  1728. }
  1729. inline void State::applyDefineList(DefineMap& defineMap, const StateSet::DefineList& defineList)
  1730. {
  1731. StateSet::DefineList::const_iterator dl_itr = defineList.begin();
  1732. DefineMap::DefineStackMap::iterator dm_itr = defineMap.map.begin();
  1733. defineMap.changed = false;
  1734. defineMap.currentDefines.clear();
  1735. while (dm_itr!=defineMap.map.end() && dl_itr!=defineList.end())
  1736. {
  1737. if (dm_itr->first<dl_itr->first)
  1738. {
  1739. DefineStack& ds = dm_itr->second;
  1740. DefineStack::DefineVec& dv = ds.defineVec;
  1741. if (!dv.empty() && (dv.back().second & StateAttribute::ON)!=0) defineMap.currentDefines[dm_itr->first] = dv.back();
  1742. ++dm_itr;
  1743. }
  1744. else if (dl_itr->first<dm_itr->first)
  1745. {
  1746. if ((dl_itr->second.second & StateAttribute::ON)!=0) defineMap.currentDefines[dl_itr->first] = dl_itr->second;
  1747. ++dl_itr;
  1748. }
  1749. else
  1750. {
  1751. // this_mitr & ds_mitr refer to the same mode, check the override
  1752. // if any otherwise just apply the incoming mode.
  1753. DefineStack& ds = dm_itr->second;
  1754. DefineStack::DefineVec& dv = ds.defineVec;
  1755. if (!dv.empty() && (dv.back().second & StateAttribute::OVERRIDE)!=0 && !(dl_itr->second.second & StateAttribute::PROTECTED))
  1756. {
  1757. // override is on, just treat as a normal apply on modes.
  1758. if ((dv.back().second & StateAttribute::ON)!=0) defineMap.currentDefines[dm_itr->first] = dv.back();
  1759. }
  1760. else
  1761. {
  1762. // no override on or no previous entry, therefore consider incoming mode.
  1763. if ((dl_itr->second.second & StateAttribute::ON)!=0) defineMap.currentDefines[dl_itr->first] = dl_itr->second;
  1764. }
  1765. ++dm_itr;
  1766. ++dl_itr;
  1767. }
  1768. }
  1769. // iterator over the remaining state modes to apply any previous changes.
  1770. for(;
  1771. dm_itr!=defineMap.map.end();
  1772. ++dm_itr)
  1773. {
  1774. // note GLMode = this_mitr->first
  1775. DefineStack& ds = dm_itr->second;
  1776. DefineStack::DefineVec& dv = ds.defineVec;
  1777. if (!dv.empty() && (dv.back().second & StateAttribute::ON)!=0) defineMap.currentDefines[dm_itr->first] = dv.back();
  1778. }
  1779. // iterator over the remaining incoming modes to apply any new mode.
  1780. for(;
  1781. dl_itr!=defineList.end();
  1782. ++dl_itr)
  1783. {
  1784. if ((dl_itr->second.second & StateAttribute::ON)!=0) defineMap.currentDefines[dl_itr->first] = dl_itr->second;
  1785. }
  1786. }
  1787. inline void State::applyModeMap(ModeMap& modeMap)
  1788. {
  1789. for(ModeMap::iterator mitr=modeMap.begin();
  1790. mitr!=modeMap.end();
  1791. ++mitr)
  1792. {
  1793. // note GLMode = mitr->first
  1794. ModeStack& ms = mitr->second;
  1795. if (ms.changed)
  1796. {
  1797. ms.changed = false;
  1798. if (!ms.valueVec.empty())
  1799. {
  1800. bool new_value = ms.valueVec.back() & StateAttribute::ON;
  1801. applyMode(mitr->first,new_value,ms);
  1802. }
  1803. else
  1804. {
  1805. // assume default of disabled.
  1806. applyMode(mitr->first,ms.global_default_value,ms);
  1807. }
  1808. }
  1809. }
  1810. }
  1811. inline void State::applyModeMapOnTexUnit(unsigned int unit,ModeMap& modeMap)
  1812. {
  1813. for(ModeMap::iterator mitr=modeMap.begin();
  1814. mitr!=modeMap.end();
  1815. ++mitr)
  1816. {
  1817. // note GLMode = mitr->first
  1818. ModeStack& ms = mitr->second;
  1819. if (ms.changed)
  1820. {
  1821. ms.changed = false;
  1822. if (!ms.valueVec.empty())
  1823. {
  1824. bool new_value = ms.valueVec.back() & StateAttribute::ON;
  1825. applyModeOnTexUnit(unit,mitr->first,new_value,ms);
  1826. }
  1827. else
  1828. {
  1829. // assume default of disabled.
  1830. applyModeOnTexUnit(unit,mitr->first,ms.global_default_value,ms);
  1831. }
  1832. }
  1833. }
  1834. }
  1835. inline void State::applyAttributeMap(AttributeMap& attributeMap)
  1836. {
  1837. for(AttributeMap::iterator aitr=attributeMap.begin();
  1838. aitr!=attributeMap.end();
  1839. ++aitr)
  1840. {
  1841. AttributeStack& as = aitr->second;
  1842. if (as.changed)
  1843. {
  1844. as.changed = false;
  1845. if (!as.attributeVec.empty())
  1846. {
  1847. const StateAttribute* new_attr = as.attributeVec.back().first;
  1848. applyAttribute(new_attr,as);
  1849. }
  1850. else
  1851. {
  1852. applyGlobalDefaultAttribute(as);
  1853. }
  1854. }
  1855. }
  1856. }
  1857. inline void State::applyAttributeMapOnTexUnit(unsigned int unit,AttributeMap& attributeMap)
  1858. {
  1859. for(AttributeMap::iterator aitr=attributeMap.begin();
  1860. aitr!=attributeMap.end();
  1861. ++aitr)
  1862. {
  1863. AttributeStack& as = aitr->second;
  1864. if (as.changed)
  1865. {
  1866. as.changed = false;
  1867. if (!as.attributeVec.empty())
  1868. {
  1869. const StateAttribute* new_attr = as.attributeVec.back().first;
  1870. applyAttributeOnTexUnit(unit,new_attr,as);
  1871. }
  1872. else
  1873. {
  1874. applyGlobalDefaultAttributeOnTexUnit(unit,as);
  1875. }
  1876. }
  1877. }
  1878. }
  1879. inline void State::applyUniformMap(UniformMap& uniformMap)
  1880. {
  1881. if (!_lastAppliedProgramObject) return;
  1882. for(UniformMap::iterator aitr=uniformMap.begin();
  1883. aitr!=uniformMap.end();
  1884. ++aitr)
  1885. {
  1886. UniformStack& as = aitr->second;
  1887. if (!as.uniformVec.empty())
  1888. {
  1889. _lastAppliedProgramObject->apply(*as.uniformVec.back().first);
  1890. }
  1891. }
  1892. }
  1893. inline bool State::setActiveTextureUnit( unsigned int unit )
  1894. {
  1895. if (unit!=_currentActiveTextureUnit)
  1896. {
  1897. if (_glActiveTexture && unit < (unsigned int)(maximum(_glMaxTextureCoords,_glMaxTextureUnits)) )
  1898. {
  1899. _glActiveTexture(GL_TEXTURE0+unit);
  1900. _currentActiveTextureUnit = unit;
  1901. }
  1902. else
  1903. {
  1904. return unit==0;
  1905. }
  1906. }
  1907. return true;
  1908. }
  1909. // forward declare speciailization of State::get() method
  1910. template<> inline GLExtensions* State::get<GLExtensions>() { return _glExtensions.get(); }
  1911. template<> inline const GLExtensions* State::get<GLExtensions>() const { return _glExtensions.get(); }
  1912. template<> inline void State::set<GLExtensions>(GLExtensions* ptr) { _glExtensions = ptr; }
  1913. }
  1914. #endif