From 1a6e7ff58b1357c0dbc6267688736ebe8d702a71 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 10 Dec 2004 22:38:21 +0000 Subject: [PATCH] refinements to multitexReducer --- panda/src/grutil/multitexReducer.I | 41 ++++++++++++++++++++------- panda/src/grutil/multitexReducer.cxx | 30 ++++++++++++++++++-- panda/src/grutil/multitexReducer.h | 3 +- panda/src/pgraph/colorScaleAttrib.I | 15 +++++++++- panda/src/pgraph/colorScaleAttrib.cxx | 21 ++++++++++++++ panda/src/pgraph/colorScaleAttrib.h | 3 ++ panda/src/testbed/pview.cxx | 22 ++++++++++---- 7 files changed, 114 insertions(+), 21 deletions(-) diff --git a/panda/src/grutil/multitexReducer.I b/panda/src/grutil/multitexReducer.I index dc0d7861bc..b0568baeb5 100644 --- a/panda/src/grutil/multitexReducer.I +++ b/panda/src/grutil/multitexReducer.I @@ -17,6 +17,26 @@ //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// Function: MultitexReducer::scan +// Access: Published +// Description: Starts scanning the hierarchy beginning at the +// indicated node. Any GeomNodes discovered in the +// hierarchy with multitexture will be added to internal +// structures in the MultitexReducer so that a future +// call to flatten() will operate on all of these at +// once. +// +// This version of this method does not accumulate state +// from the parents of the indicated node; thus, only +// multitexture effects that have been applied at node +// and below will be considered. +//////////////////////////////////////////////////////////////////// +INLINE void MultitexReducer:: +scan(const NodePath &node) { + scan(node.node(), RenderState::make_empty(), TransformState::make_identity()); +} + //////////////////////////////////////////////////////////////////// // Function: MultitexReducer::scan // Access: Published @@ -29,19 +49,20 @@ // // The second parameter represents the NodePath from // which to accumulate the state that is considered for -// the multitexture. The default is to accumulate all -// the state from the root of the graph, but you may -// specify some other node here in order to not consider -// nodes above that as contributing to the state to be -// flattened. This is particularly useful if you have -// some texture stage which is applied globally to a -// scene (for instance, a caustics effect), which you -// don't want to be considered for flattening by the -// MultitexReducer. +// the multitexture. Pass an empty NodePath to +// accumulate all the state from the root of the graph, +// or you may specify some other node here in order to +// not consider nodes above that as contributing to the +// state to be flattened. This is particularly useful +// if you have some texture stage which is applied +// globally to a scene (for instance, a caustics +// effect), which you don't want to be considered for +// flattening by the MultitexReducer. //////////////////////////////////////////////////////////////////// INLINE void MultitexReducer:: scan(const NodePath &node, const NodePath &state_from) { - scan(node.node(), node.get_state(state_from), node.get_transform(state_from)); + scan(node.node(), node.get_parent().get_state(state_from), + node.get_parent().get_transform(state_from)); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/grutil/multitexReducer.cxx b/panda/src/grutil/multitexReducer.cxx index 0af07fb1f6..ecd46ab4b2 100644 --- a/panda/src/grutil/multitexReducer.cxx +++ b/panda/src/grutil/multitexReducer.cxx @@ -30,6 +30,7 @@ #include "colorAttrib.h" #include "colorScaleAttrib.h" #include "colorBlendAttrib.h" +#include "textureAttrib.h" #include "config_grutil.h" #include "config_gobj.h" #include "dcast.h" @@ -83,9 +84,20 @@ clear() { //////////////////////////////////////////////////////////////////// void MultitexReducer:: scan(PandaNode *node, const RenderState *state, const TransformState *transform) { + if (grutil_cat.is_debug()) { + grutil_cat.debug() + << "scan(" << *node << ", " << *state << ", " << *transform << ")\n"; + } + CPT(RenderState) next_state = state->compose(node->get_state()); CPT(TransformState) next_transform = transform->compose(node->get_transform()); + // We must turn off any textures we come across in the scan() + // operation, since the flattened texture will be applied to the + // Geoms after the flatten() operation, and we don't want to still + // have a multitexture specified. + node->set_state(node->get_state()->remove_attrib(TextureAttrib::get_class_type())); + if (node->is_geom_node()) { scan_geom_node(DCAST(GeomNode, node), next_state, next_transform); } @@ -271,6 +283,7 @@ flatten(GraphicsOutput *window) { render.set_bin("unsorted", 0); render.set_depth_test(false); render.set_depth_write(false); + render.set_two_sided(1); NodePath cam = render.attach_new_node(cam_node); dr->set_camera(cam); @@ -317,7 +330,18 @@ flatten(GraphicsOutput *window) { // disable coloring on the new fragment (the color has been // baked into the texture). geom_state = geom_state->add_attrib(ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 1.0f))); - geom_state = geom_state->add_attrib(ColorScaleAttrib::make_off()); + + // And we invent a ColorScaleAttrib to undo the effect of any + // color scale we're getting from above. This is not the same + // thing as a ColorScaleAttrib::make_off(), since that would + // prohibit any future changes to the color scale. + const RenderAttrib *attrib = + geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_type()); + + if (attrib != (const RenderAttrib *)NULL) { + geom_state = geom_state->add_attrib + (attrib->invert_compose(ColorScaleAttrib::make_identity())); + } } // Determine what tex matrix should be on the Geom. @@ -739,11 +763,11 @@ transfer_geom(GeomNode *geom_node, const TexCoordName *texcoord_name, // Be sure to preserve whatever colors are on the geom. const RenderAttrib *ca = geom_info._geom_net_state->get_attrib(ColorAttrib::get_class_type()); if (ca != (const RenderAttrib *)NULL) { - geom_state->add_attrib(ca); + geom_state = geom_state->add_attrib(ca); } const RenderAttrib *csa = geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_type()); if (csa != (const RenderAttrib *)NULL) { - geom_state->add_attrib(csa); + geom_state = geom_state->add_attrib(csa); } } diff --git a/panda/src/grutil/multitexReducer.h b/panda/src/grutil/multitexReducer.h index 0ada164f1d..1bd4fc3422 100644 --- a/panda/src/grutil/multitexReducer.h +++ b/panda/src/grutil/multitexReducer.h @@ -59,7 +59,8 @@ PUBLISHED: ~MultitexReducer(); void clear(); - INLINE void scan(const NodePath &node, const NodePath &state_from = NodePath()); + INLINE void scan(const NodePath &node); + INLINE void scan(const NodePath &node, const NodePath &state_from); void scan(PandaNode *node, const RenderState *state, const TransformState *transform); diff --git a/panda/src/pgraph/colorScaleAttrib.I b/panda/src/pgraph/colorScaleAttrib.I index cec71a9f6a..0f67e8e393 100644 --- a/panda/src/pgraph/colorScaleAttrib.I +++ b/panda/src/pgraph/colorScaleAttrib.I @@ -59,11 +59,24 @@ is_off() const { return _off; } +//////////////////////////////////////////////////////////////////// +// Function: ColorScaleAttrib::is_identity +// Access: Published +// Description: Returns true if the ColorScaleAttrib is an identity +// attrib, false if it is either an off attrib or it has +// a scale. +//////////////////////////////////////////////////////////////////// +INLINE bool ColorScaleAttrib:: +is_identity() const { + return !_off && !_has_scale; +} + //////////////////////////////////////////////////////////////////// // Function: ColorScaleAttrib::has_scale // Access: Published // Description: Returns true if the ColorScaleAttrib has a -// non-identity scale, false otherwise. +// non-identity scale, false otherwise (in which case it +// might be an off attrib or an identity attrib). //////////////////////////////////////////////////////////////////// INLINE bool ColorScaleAttrib:: has_scale() const { diff --git a/panda/src/pgraph/colorScaleAttrib.cxx b/panda/src/pgraph/colorScaleAttrib.cxx index 8e5a307f12..a1f3cfb30c 100644 --- a/panda/src/pgraph/colorScaleAttrib.cxx +++ b/panda/src/pgraph/colorScaleAttrib.cxx @@ -26,6 +26,24 @@ #include "config_pgraph.h" TypeHandle ColorScaleAttrib::_type_handle; +CPT(RenderAttrib) ColorScaleAttrib::_identity_attrib; + +//////////////////////////////////////////////////////////////////// +// Function: ColorScaleAttrib::make_identity +// Access: Published, Static +// Description: Constructs an identity scale attrib. +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ColorScaleAttrib:: +make_identity() { + // We make identity a special case and store a pointer forever once + // we find it the first time. + if (_identity_attrib == (ColorScaleAttrib *)NULL) { + ColorScaleAttrib *attrib = new ColorScaleAttrib(false, LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f));; + _identity_attrib = return_new(attrib); + } + + return _identity_attrib; +} //////////////////////////////////////////////////////////////////// // Function: ColorScaleAttrib::make @@ -95,6 +113,9 @@ output(ostream &out) const { } if (has_scale()) { out << "(" << get_scale() << ")"; + + } else if (!is_off()) { + out << "identity"; } } diff --git a/panda/src/pgraph/colorScaleAttrib.h b/panda/src/pgraph/colorScaleAttrib.h index d450ebcf86..75cb2dea09 100644 --- a/panda/src/pgraph/colorScaleAttrib.h +++ b/panda/src/pgraph/colorScaleAttrib.h @@ -37,10 +37,12 @@ protected: INLINE ColorScaleAttrib(const ColorScaleAttrib ©); PUBLISHED: + static CPT(RenderAttrib) make_identity(); static CPT(RenderAttrib) make(const LVecBase4f &scale); static CPT(RenderAttrib) make_off(); INLINE bool is_off() const; + INLINE bool is_identity() const; INLINE bool has_scale() const; INLINE const LVecBase4f &get_scale() const; CPT(RenderAttrib) set_scale(const LVecBase4f &scale) const; @@ -59,6 +61,7 @@ private: bool _off; bool _has_scale; LVecBase4f _scale; + static CPT(RenderAttrib) _identity_attrib; public: static void register_with_read_factory(); diff --git a/panda/src/testbed/pview.cxx b/panda/src/testbed/pview.cxx index 52a65cd500..235cb8fc6e 100644 --- a/panda/src/testbed/pview.cxx +++ b/panda/src/testbed/pview.cxx @@ -108,14 +108,24 @@ event_2(CPT_Event event, void *) { void event_0(CPT_Event event, void *) { // 0: run hacky test. - MultitexReducer mr; - mr.set_use_geom(true); + static bool first = true; - mr.scan(framework.get_models()); + if (first) { + cerr << "applying scale\n"; + framework.get_models().set_color_scale(0.7, 0.7, 0.1, 1.0); + first = false; - WindowFramework *wf = framework.get_window(0); - GraphicsWindow *win = wf->get_graphics_window(); - mr.flatten(win); + } else { + cerr << "flattening\n"; + MultitexReducer mr; + mr.set_use_geom(true); + + mr.scan(framework.get_models()); + + WindowFramework *wf = framework.get_window(0); + GraphicsWindow *win = wf->get_graphics_window(); + mr.flatten(win); + } } void