diff --git a/panda/src/pgraph/colorScaleAttrib.cxx b/panda/src/pgraph/colorScaleAttrib.cxx index d5829461c6..70e5154d51 100644 --- a/panda/src/pgraph/colorScaleAttrib.cxx +++ b/panda/src/pgraph/colorScaleAttrib.cxx @@ -101,6 +101,41 @@ issue(GraphicsStateGuardianBase *gsg) const { gsg->issue_color_scale(this); } +//////////////////////////////////////////////////////////////////// +// Function: ColorScaleAttrib::lower_attrib_can_override +// Access: Public, Virtual +// Description: Intended to be overridden by derived RenderAttrib +// types to specify how two consecutive RenderAttrib +// objects of the same type interact. +// +// This should return false if a RenderAttrib on a +// higher node will compose into a RenderAttrib on a +// lower node that has a higher override value, or false +// if the lower RenderAttrib will completely replace the +// state. +// +// The default behavior is false: normally, a +// RenderAttrib in the graph cannot completely override +// a RenderAttrib above it, regardless of its override +// value--instead, the two attribs are composed. But +// for some kinds of RenderAttribs, it is useful to +// allow this kind of override. +// +// This method only handles the one special case of a +// lower RenderAttrib with a higher override value. If +// the higher RenderAttrib has a higher override value, +// it always completely overrides. And if both +// RenderAttribs have the same override value, they are +// always composed. +//////////////////////////////////////////////////////////////////// +bool ColorScaleAttrib:: +lower_attrib_can_override() const { + // A ColorScaleAttrib doesn't compose through an override. This + // allows us to meaningfully set an override on a lower node, which + // prevents any color scales from coming in from above. + return true; +} + //////////////////////////////////////////////////////////////////// // Function: ColorScaleAttrib::output // Access: Public, Virtual diff --git a/panda/src/pgraph/colorScaleAttrib.h b/panda/src/pgraph/colorScaleAttrib.h index b86e22ae4d..24bc9e3c56 100644 --- a/panda/src/pgraph/colorScaleAttrib.h +++ b/panda/src/pgraph/colorScaleAttrib.h @@ -49,6 +49,7 @@ PUBLISHED: public: virtual void issue(GraphicsStateGuardianBase *gsg) const; + virtual bool lower_attrib_can_override() const; virtual void output(ostream &out) const; protected: diff --git a/panda/src/pgraph/renderAttrib.cxx b/panda/src/pgraph/renderAttrib.cxx index ff08b43d56..630f9d5ca6 100644 --- a/panda/src/pgraph/renderAttrib.cxx +++ b/panda/src/pgraph/renderAttrib.cxx @@ -105,6 +105,38 @@ void RenderAttrib:: issue(GraphicsStateGuardianBase *) const { } +//////////////////////////////////////////////////////////////////// +// Function: RenderAttrib::lower_attrib_can_override +// Access: Public, Virtual +// Description: Intended to be overridden by derived RenderAttrib +// types to specify how two consecutive RenderAttrib +// objects of the same type interact. +// +// This should return false if a RenderAttrib on a +// higher node will compose into a RenderAttrib on a +// lower node that has a higher override value, or false +// if the lower RenderAttrib will completely replace the +// state. +// +// The default behavior is false: normally, a +// RenderAttrib in the graph cannot completely override +// a RenderAttrib above it, regardless of its override +// value--instead, the two attribs are composed. But +// for some kinds of RenderAttribs, it is useful to +// allow this kind of override. +// +// This method only handles the one special case of a +// lower RenderAttrib with a higher override value. If +// the higher RenderAttrib has a higher override value, +// it always completely overrides. And if both +// RenderAttribs have the same override value, they are +// always composed. +//////////////////////////////////////////////////////////////////// +bool RenderAttrib:: +lower_attrib_can_override() const { + return false; +} + //////////////////////////////////////////////////////////////////// // Function: RenderAttrib::output // Access: Published, Virtual diff --git a/panda/src/pgraph/renderAttrib.h b/panda/src/pgraph/renderAttrib.h index c4781086b7..9f8712c53d 100644 --- a/panda/src/pgraph/renderAttrib.h +++ b/panda/src/pgraph/renderAttrib.h @@ -68,6 +68,7 @@ public: INLINE CPT(RenderAttrib) invert_compose(const RenderAttrib *other) const; INLINE CPT(RenderAttrib) make_default() const; virtual void issue(GraphicsStateGuardianBase *gsg) const; + virtual bool lower_attrib_can_override() const; INLINE bool always_reissue() const; diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 92759e9583..f6d20db9ff 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -1190,9 +1190,19 @@ do_compose(const RenderState *other) const { const Attribute &a = (*ai); const Attribute &b = (*bi); if (b._override < a._override) { - // A overrides. + // A, the higher RenderAttrib, overrides. *result = *ai; + } else if (a._override < b._override && + a._attrib->lower_attrib_can_override()) { + // B, the lower RenderAttrib, overrides. This is a special + // case; normally, a lower RenderAttrib does not override a + // higher one, even if it has a higher override value. But + // certain kinds of RenderAttribs redefine + // lower_attrib_can_override() to return true, allowing this + // override. + *result = *bi; + } else { // Either they have the same override value, or B is higher. // In either case, the result is the composition of the two,