diff --git a/panda/src/pgraph/pandaNode.cxx b/panda/src/pgraph/pandaNode.cxx index f957983bdc..3e012db88f 100644 --- a/panda/src/pgraph/pandaNode.cxx +++ b/panda/src/pgraph/pandaNode.cxx @@ -1055,7 +1055,7 @@ set_attrib(const RenderAttrib *attrib, int override) { OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { CDStageWriter cdata(_cycler, pipeline_stage, current_thread); - CPT(RenderState) new_state = cdata->_state->add_attrib(attrib, override); + CPT(RenderState) new_state = cdata->_state->set_attrib(attrib, override); if (cdata->_state != new_state) { cdata->_state = new_state; cdata->set_fancy_bit(FB_state, true); diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 4073786234..35b358dd02 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -613,6 +613,57 @@ set_attrib(const RenderAttrib *attrib) const { return return_new(new_state); } +//////////////////////////////////////////////////////////////////// +// Function: RenderState::set_attrib +// Access: Published +// Description: Returns a new RenderState object that represents the +// same as the source state, with the new RenderAttrib +// added. If there is already a RenderAttrib with the +// same type, it is replaced unconditionally. The +// override is also replaced unconditionally. +//////////////////////////////////////////////////////////////////// +CPT(RenderState) RenderState:: +set_attrib(const RenderAttrib *attrib, int override) const { + RenderState *new_state = new RenderState; + back_insert_iterator result = + back_inserter(new_state->_attributes); + + Attribute new_attribute(attrib, override); + Attributes::const_iterator ai = _attributes.begin(); + + while (ai != _attributes.end() && (*ai) < new_attribute) { + *result = *ai; + ++ai; + ++result; + } + + if (ai != _attributes.end() && !(new_attribute < (*ai))) { + // At this point we know: !((*ai) < new_attribute) && + // !(new_attribute < (*ai)) which means (*ai) == new_attribute, so + // there is another attribute of the same type already in the + // state. + + (*result) = Attribute(attrib, override); + ++ai; + ++result; + + } else { + // There is not another attribute of the same type already in the + // state. + *result = new_attribute; + ++result; + } + + + while (ai != _attributes.end()) { + *result = *ai; + ++ai; + ++result; + } + + return return_new(new_state); +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::remove_attrib // Access: Published diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index f870da77a4..e61c401f4e 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -108,6 +108,7 @@ PUBLISHED: CPT(RenderState) add_attrib(const RenderAttrib *attrib, int override = 0) const; CPT(RenderState) set_attrib(const RenderAttrib *attrib) const; + CPT(RenderState) set_attrib(const RenderAttrib *attrib, int override) const; CPT(RenderState) remove_attrib(TypeHandle type) const; CPT(RenderState) adjust_all_priorities(int adjustment) const;