diff --git a/include/osg/BlendEquationi b/include/osg/BlendEquationi index 8ab85f6e0..2d77d0b28 100644 --- a/include/osg/BlendEquationi +++ b/include/osg/BlendEquationi @@ -33,7 +33,7 @@ class OSG_EXPORT BlendEquationi : public BlendEquation BlendEquationi(unsigned int buf, Equation equationRGB, Equation equationAlpha): BlendEquation(equationRGB, equationAlpha), _index(buf) {} - + /** Copy constructor using CopyOp to manage deep vs shallow copy. */ BlendEquationi(const BlendEquationi& cm,const CopyOp& copyop=CopyOp::SHALLOW_COPY): @@ -58,7 +58,7 @@ class OSG_EXPORT BlendEquationi : public BlendEquation virtual unsigned int getMember() const { return _index; } /** Set the renderbuffer index of the BlendEquationi. */ - void setIndex(unsigned int buf) { _index = buf; } + void setIndex(unsigned int buf); /** Get the renderbuffer index of the BlendEquationi. */ unsigned int getIndex() const { return _index; } diff --git a/include/osg/BlendFunci b/include/osg/BlendFunci index a1ed108ed..3de8f3ef1 100644 --- a/include/osg/BlendFunci +++ b/include/osg/BlendFunci @@ -57,7 +57,7 @@ class OSG_EXPORT BlendFunci : public BlendFunc virtual unsigned int getMember() const { return _index; } /** Set the renderbuffer index of the BlendFunci. */ - void setIndex(unsigned int buf) { _index = buf; } + void setIndex(unsigned int buf); /** Get the renderbuffer index of the BlendFunci. */ unsigned int getIndex() const { return _index; } diff --git a/include/osg/BufferIndexBinding b/include/osg/BufferIndexBinding index a75532db5..bc564b7b5 100644 --- a/include/osg/BufferIndexBinding +++ b/include/osg/BufferIndexBinding @@ -51,16 +51,22 @@ class OSG_EXPORT BufferIndexBinding : public StateAttribute GLenum getTarget() const { return _target; } + /** Set the renderbuffer index of the BlendEquationi. */ + void setIndex(unsigned int index); + /** Get the index target. */ GLuint getIndex() const { return _index; } + /** Set the buffer object that will be bound to the index target. */ void setBufferObject(BufferObject *bo) { _bufferObject = bo; } + /** Get the buffer object to be bound. */ const BufferObject* getBufferObject() const { return _bufferObject.get(); } BufferObject* getBufferObject(){ return _bufferObject.get(); } + /** Set the starting offset into the buffer object for data for the indexed target. Note: the required alignment on the offset may be quite large (e.g., 256 bytes on NVidia 8600M). This @@ -68,16 +74,18 @@ class OSG_EXPORT BufferIndexBinding : public StateAttribute */ void setOffset(GLintptr offset) { _offset = offset; } GLintptr getOffset() const { return _offset; } + /** Set the size of data for the indexed target. */ void setSize(GLsizeiptr size) { _size = size; } GLsizeiptr getSize() const { return _size; } + virtual void apply(State& state) const; protected: virtual ~BufferIndexBinding(); const GLenum _target; - const GLuint _index; + GLuint _index; ref_ptr _bufferObject; GLintptr _offset; GLsizeiptr _size; diff --git a/include/osg/ColorMaski b/include/osg/ColorMaski index 451330ce6..f26bd12ae 100644 --- a/include/osg/ColorMaski +++ b/include/osg/ColorMaski @@ -53,7 +53,7 @@ class OSG_EXPORT ColorMaski : public ColorMask virtual unsigned int getMember() const { return _index; } /** Set the renderbuffer index of the ColorMaski. */ - void setIndex(unsigned int buf) { _index = buf; } + void setIndex(unsigned int buf); /** Get the renderbuffer index of the ColorMaski. */ unsigned int getIndex() const { return _index; } diff --git a/include/osg/StateAttribute b/include/osg/StateAttribute index 8dba14257..09bf5f60e 100644 --- a/include/osg/StateAttribute +++ b/include/osg/StateAttribute @@ -372,12 +372,26 @@ class OSG_EXPORT StateAttribute : public Object ParentList _parents; friend class osg::StateSet; + /** Helper class that make is easy to handle changes in a member value.*/ + struct ReassignToParents + { + /** Constructor caches and then removes attribute for all of it's parents.*/ + ReassignToParents(osg::StateAttribute* att); + + /** Destructor then reassigns the attribute to all of the parents.*/ + ~ReassignToParents(); + + ref_ptr attribute; + ParentList parents; + }; + + ref_ptr _shaderComponent; ref_ptr _updateCallback; ref_ptr _eventCallback; }; -} +} #endif diff --git a/src/osg/BlendEquationi.cpp b/src/osg/BlendEquationi.cpp index 7bedb8aa4..c8613783a 100644 --- a/src/osg/BlendEquationi.cpp +++ b/src/osg/BlendEquationi.cpp @@ -26,6 +26,15 @@ BlendEquationi::~BlendEquationi() { } +void BlendEquationi::setIndex(unsigned int buf) +{ + if (_index==buf) return; + + ReassignToParents needToReassingToParentsWhenMemberValueChanges(this); + + _index = buf; +} + void BlendEquationi::apply(State& state) const { const GLExtensions* extensions = state.get(); diff --git a/src/osg/BlendFunci.cpp b/src/osg/BlendFunci.cpp index 481e96ddd..0405e258d 100644 --- a/src/osg/BlendFunci.cpp +++ b/src/osg/BlendFunci.cpp @@ -26,6 +26,15 @@ BlendFunci::~BlendFunci() { } +void BlendFunci::setIndex(unsigned int buf) +{ + if (_index==buf) return; + + ReassignToParents needToReassingToParentsWhenMemberValueChanges(this); + + _index = buf; +} + void BlendFunci::apply(State& state) const { const GLExtensions* extensions = state.get(); diff --git a/src/osg/BufferIndexBinding.cpp b/src/osg/BufferIndexBinding.cpp index e08f8b787..739025fc0 100644 --- a/src/osg/BufferIndexBinding.cpp +++ b/src/osg/BufferIndexBinding.cpp @@ -48,6 +48,15 @@ BufferIndexBinding::~BufferIndexBinding() { } +void BufferIndexBinding::setIndex(unsigned int index) +{ + if (_index==index) return; + + ReassignToParents needToReassingToParentsWhenMemberValueChanges(this); + + _index = index; +} + void BufferIndexBinding::apply(State& state) const { if (_bufferObject.valid()) diff --git a/src/osg/ClipPlane.cpp b/src/osg/ClipPlane.cpp index daf7c7a93..3a3fd8567 100644 --- a/src/osg/ClipPlane.cpp +++ b/src/osg/ClipPlane.cpp @@ -31,41 +31,9 @@ void ClipPlane::setClipPlaneNum(unsigned int num) { if (_clipPlaneNum==num) return; - if (_parents.empty()) - { - _clipPlaneNum = num; - return; - } + ReassignToParents needToReassingToParentsWhenMemberValueChanges(this); - // take a reference to this clip plane to prevent it from going out of scope - // when we remove it temporarily from its parents. - osg::ref_ptr clipPlaneRef = this; - - // copy the parents as they _parents list will be changed by the subsequent removeAttributes. - ParentList parents = _parents; - - // remove this attribute from its parents as its position is being changed - // and would no longer be valid. - ParentList::iterator itr; - for(itr = parents.begin(); - itr != parents.end(); - ++itr) - { - osg::StateSet* stateset = *itr; - stateset->removeAttribute(this); - } - - // assign the clip plane number _clipPlaneNum = num; - - // add this attribute back into its original parents with its new position - for(itr = parents.begin(); - itr != parents.end(); - ++itr) - { - osg::StateSet* stateset = *itr; - stateset->setAttribute(this); - } } unsigned int ClipPlane::getClipPlaneNum() const diff --git a/src/osg/ColorMaski.cpp b/src/osg/ColorMaski.cpp index 1a4ab8a52..1cae24a92 100644 --- a/src/osg/ColorMaski.cpp +++ b/src/osg/ColorMaski.cpp @@ -25,6 +25,15 @@ ColorMaski::~ColorMaski() { } +void ColorMaski::setIndex(unsigned int buf) +{ + if (_index==buf) return; + + ReassignToParents needToReassingToParentsWhenMemberValueChanges(this); + + _index = buf; +} + void ColorMaski::apply(State& state) const { const GLExtensions* extensions = state.get(); diff --git a/src/osg/Hint.cpp b/src/osg/Hint.cpp index 9de9c8d0e..0a1b46fe0 100644 --- a/src/osg/Hint.cpp +++ b/src/osg/Hint.cpp @@ -27,40 +27,8 @@ void Hint::setTarget(GLenum target) { if (_target==target) return; - if (_parents.empty()) - { - _target = target; - return; - } + ReassignToParents needToReassingToParentsWhenMemberValueChanges(this); - // take a reference to this clip plane to prevent it from going out of scope - // when we remove it temporarily from its parents. - osg::ref_ptr hintRef = this; - - // copy the parents as they _parents list will be changed by the subsequent removeAttributes. - ParentList parents = _parents; - - // remove this attribute from its parents as its position is being changed - // and would no longer be valid. - ParentList::iterator itr; - for(itr = parents.begin(); - itr != parents.end(); - ++itr) - { - osg::StateSet* stateset = *itr; - stateset->removeAttribute(this); - } - - // assign the hint target _target = target; - - // add this attribute back into its original parents with its new position - for(itr = parents.begin(); - itr != parents.end(); - ++itr) - { - osg::StateSet* stateset = *itr; - stateset->setAttribute(this); - } } diff --git a/src/osg/Light.cpp b/src/osg/Light.cpp index 29ff236c2..f4cf9ee89 100644 --- a/src/osg/Light.cpp +++ b/src/osg/Light.cpp @@ -62,41 +62,9 @@ void Light::setLightNum(int num) { if (_lightnum==num) return; - if (_parents.empty()) - { - _lightnum = num; - return; - } + ReassignToParents needToReassingToParentsWhenMemberValueChanges(this); - // take a reference to this clip plane to prevent it from going out of scope - // when we remove it temporarily from its parents. - osg::ref_ptr lightRef = this; - - // copy the parents as they _parents list will be changed by the subsequent removeAttributes. - ParentList parents = _parents; - - // remove this attribute from its parents as its position is being changed - // and would no longer be valid. - ParentList::iterator itr; - for(itr = parents.begin(); - itr != parents.end(); - ++itr) - { - osg::StateSet* stateset = *itr; - stateset->removeAttribute(this); - } - - // assign the hint target _lightnum = num; - - // add this attribute back into its original parents with its new position - for(itr = parents.begin(); - itr != parents.end(); - ++itr) - { - osg::StateSet* stateset = *itr; - stateset->setAttribute(this); - } } void Light::captureLightState() diff --git a/src/osg/StateAttribute.cpp b/src/osg/StateAttribute.cpp index 158a07a00..86cb9b9d8 100644 --- a/src/osg/StateAttribute.cpp +++ b/src/osg/StateAttribute.cpp @@ -91,3 +91,41 @@ void StateAttribute::setEventCallback(StateAttributeCallback* ec) } } } + +StateAttribute::ReassignToParents::ReassignToParents(osg::StateAttribute* attr) +{ + if (!attr->isTextureAttribute() && !attr->getParents().empty()) + { + // take a reference to this clip plane to prevent it from going out of scope + // when we remove it temporarily from its parents. + attribute = attr; + + // copy the parents as they _parents list will be changed by the subsequent removeAttributes. + parents = attr->getParents(); + + // remove this attribute from its parents as its position is being changed + // and would no longer be valid. + for(ParentList::iterator itr = parents.begin(); + itr != parents.end(); + ++itr) + { + osg::StateSet* stateset = *itr; + stateset->removeAttribute(attr); + + OSG_NOTICE<<" Removed from parent "<setAttribute(attribute.get()); + OSG_NOTICE<<" Added back to parent "<