From 02b2d76274adb6d080d25bb6ea7a2f7c0f5133a9 Mon Sep 17 00:00:00 2001 From: David Rose Date: Sat, 1 Mar 2008 00:05:03 +0000 Subject: [PATCH] more flatten bugs: fix color-scale support --- panda/src/pgraph/geomNode.cxx | 34 +++++++++++++++++++-- panda/src/pgraph/renderState.cxx | 51 ++++++++++++++++++++++++++++++++ panda/src/pgraph/renderState.h | 1 + 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx index 0989150f54..ba875cb022 100644 --- a/panda/src/pgraph/geomNode.cxx +++ b/panda/src/pgraph/geomNode.cxx @@ -135,7 +135,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types, entry._state = geom_attribs.collect(entry._state, attrib_types); bool any_changed = false; - + if ((attrib_types & SceneGraphReducer::TT_color) != 0) { CPT(RenderAttrib) ra = geom_attribs._color; int override = geom_attribs._color_override; @@ -160,12 +160,40 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types, if (geom_attribs._color_scale != (const RenderAttrib *)NULL) { const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, geom_attribs._color_scale); if (csa->get_scale() != LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f)) { - if (transformer.transform_colors(new_geom, csa->get_scale())) { - any_changed = true; + + // Now, if we have an "off" or "flat" color attribute, we + // simply modify the color attribute, and leave the + // vertices alone. + const RenderAttrib *ra = entry._state->get_attrib(ColorAttrib::get_class_type()); + if (ra != (const RenderAttrib *)NULL) { + const ColorAttrib *ca = DCAST(ColorAttrib, ra); + if (ca->get_color_type() == ColorAttrib::T_off) { + entry._state = entry._state->set_attrib(ColorAttrib::make_vertex()); + // ColorAttrib::T_off means the color scale becomes + // the new color. + entry._state = entry._state->set_attrib(ColorAttrib::make_flat(csa->get_scale())); + + } else if (ca->get_color_type() == ColorAttrib::T_flat) { + // ColorAttrib::T_off means the color scale modulates + // the specified color to produce a new color. + const Colorf &c1 = ca->get_color(); + const LVecBase4f &c2 = csa->get_scale(); + Colorf color(c1[0] * c2[0], c1[1] * c2[1], + c1[2] * c2[2], c1[3] * c2[3]); + entry._state = entry._state->set_attrib(ColorAttrib::make_flat(color)); + + } else { + // Otherwise, we have vertex color, and we just scale + // it normally. + if (transformer.transform_colors(new_geom, csa->get_scale())) { + any_changed = true; + } + } } } } } + if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) { if (geom_attribs._tex_matrix != (const RenderAttrib *)NULL) { // Determine which texture coordinate names are used more than diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 3662e1b480..4073786234 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -562,6 +562,57 @@ add_attrib(const RenderAttrib *attrib, int override) 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 not changed. +//////////////////////////////////////////////////////////////////// +CPT(RenderState) RenderState:: +set_attrib(const RenderAttrib *attrib) const { + RenderState *new_state = new RenderState; + back_insert_iterator result = + back_inserter(new_state->_attributes); + + Attribute new_attribute(attrib, 0); + 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, (*ai)._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 815823738f..f870da77a4 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -107,6 +107,7 @@ PUBLISHED: CPT(RenderState) invert_compose(const RenderState *other) const; CPT(RenderState) add_attrib(const RenderAttrib *attrib, int override = 0) const; + CPT(RenderState) set_attrib(const RenderAttrib *attrib) const; CPT(RenderState) remove_attrib(TypeHandle type) const; CPT(RenderState) adjust_all_priorities(int adjustment) const;