瀏覽代碼

refinements to multitexReducer

David Rose 21 年之前
父節點
當前提交
1a6e7ff58b

+ 31 - 10
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
 //     Function: MultitexReducer::scan
 //       Access: Published
 //       Access: Published
@@ -29,19 +49,20 @@
 //
 //
 //               The second parameter represents the NodePath from
 //               The second parameter represents the NodePath from
 //               which to accumulate the state that is considered for
 //               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::
 INLINE void MultitexReducer::
 scan(const NodePath &node, const NodePath &state_from) {
 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));
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 27 - 3
panda/src/grutil/multitexReducer.cxx

@@ -30,6 +30,7 @@
 #include "colorAttrib.h"
 #include "colorAttrib.h"
 #include "colorScaleAttrib.h"
 #include "colorScaleAttrib.h"
 #include "colorBlendAttrib.h"
 #include "colorBlendAttrib.h"
+#include "textureAttrib.h"
 #include "config_grutil.h"
 #include "config_grutil.h"
 #include "config_gobj.h"
 #include "config_gobj.h"
 #include "dcast.h"
 #include "dcast.h"
@@ -83,9 +84,20 @@ clear() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void MultitexReducer::
 void MultitexReducer::
 scan(PandaNode *node, const RenderState *state, const TransformState *transform) {
 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(RenderState) next_state = state->compose(node->get_state());
   CPT(TransformState) next_transform = transform->compose(node->get_transform());
   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()) {
   if (node->is_geom_node()) {
     scan_geom_node(DCAST(GeomNode, node), next_state, next_transform);
     scan_geom_node(DCAST(GeomNode, node), next_state, next_transform);
   }
   }
@@ -271,6 +283,7 @@ flatten(GraphicsOutput *window) {
     render.set_bin("unsorted", 0);
     render.set_bin("unsorted", 0);
     render.set_depth_test(false);
     render.set_depth_test(false);
     render.set_depth_write(false);
     render.set_depth_write(false);
+    render.set_two_sided(1);
 
 
     NodePath cam = render.attach_new_node(cam_node);
     NodePath cam = render.attach_new_node(cam_node);
     dr->set_camera(cam);
     dr->set_camera(cam);
@@ -317,7 +330,18 @@ flatten(GraphicsOutput *window) {
         // disable coloring on the new fragment (the color has been
         // disable coloring on the new fragment (the color has been
         // baked into the texture).
         // 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(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.
       // 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.
         // Be sure to preserve whatever colors are on the geom.
         const RenderAttrib *ca = geom_info._geom_net_state->get_attrib(ColorAttrib::get_class_type());
         const RenderAttrib *ca = geom_info._geom_net_state->get_attrib(ColorAttrib::get_class_type());
         if (ca != (const RenderAttrib *)NULL) {
         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());
         const RenderAttrib *csa = geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_type());
         if (csa != (const RenderAttrib *)NULL) {
         if (csa != (const RenderAttrib *)NULL) {
-          geom_state->add_attrib(csa);
+          geom_state = geom_state->add_attrib(csa);
         }
         }
       }
       }
       
       

+ 2 - 1
panda/src/grutil/multitexReducer.h

@@ -59,7 +59,8 @@ PUBLISHED:
   ~MultitexReducer();
   ~MultitexReducer();
 
 
   void clear();
   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, 
   void scan(PandaNode *node, const RenderState *state, 
             const TransformState *transform);
             const TransformState *transform);
 
 

+ 14 - 1
panda/src/pgraph/colorScaleAttrib.I

@@ -59,11 +59,24 @@ is_off() const {
   return _off;
   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
 //     Function: ColorScaleAttrib::has_scale
 //       Access: Published
 //       Access: Published
 //  Description: Returns true if the ColorScaleAttrib has a
 //  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::
 INLINE bool ColorScaleAttrib::
 has_scale() const {
 has_scale() const {

+ 21 - 0
panda/src/pgraph/colorScaleAttrib.cxx

@@ -26,6 +26,24 @@
 #include "config_pgraph.h"
 #include "config_pgraph.h"
 
 
 TypeHandle ColorScaleAttrib::_type_handle;
 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
 //     Function: ColorScaleAttrib::make
@@ -95,6 +113,9 @@ output(ostream &out) const {
   }
   }
   if (has_scale()) {
   if (has_scale()) {
     out << "(" << get_scale() << ")";
     out << "(" << get_scale() << ")";
+
+  } else if (!is_off()) {
+    out << "identity";
   }
   }
 }
 }
 
 

+ 3 - 0
panda/src/pgraph/colorScaleAttrib.h

@@ -37,10 +37,12 @@ protected:
   INLINE ColorScaleAttrib(const ColorScaleAttrib &copy);
   INLINE ColorScaleAttrib(const ColorScaleAttrib &copy);
 
 
 PUBLISHED:
 PUBLISHED:
+  static CPT(RenderAttrib) make_identity();
   static CPT(RenderAttrib) make(const LVecBase4f &scale);
   static CPT(RenderAttrib) make(const LVecBase4f &scale);
   static CPT(RenderAttrib) make_off();
   static CPT(RenderAttrib) make_off();
 
 
   INLINE bool is_off() const;
   INLINE bool is_off() const;
+  INLINE bool is_identity() const;
   INLINE bool has_scale() const;
   INLINE bool has_scale() const;
   INLINE const LVecBase4f &get_scale() const;
   INLINE const LVecBase4f &get_scale() const;
   CPT(RenderAttrib) set_scale(const LVecBase4f &scale) const;
   CPT(RenderAttrib) set_scale(const LVecBase4f &scale) const;
@@ -59,6 +61,7 @@ private:
   bool _off;
   bool _off;
   bool _has_scale;
   bool _has_scale;
   LVecBase4f _scale;
   LVecBase4f _scale;
+  static CPT(RenderAttrib) _identity_attrib;
 
 
 public:
 public:
   static void register_with_read_factory();
   static void register_with_read_factory();

+ 16 - 6
panda/src/testbed/pview.cxx

@@ -108,14 +108,24 @@ event_2(CPT_Event event, void *) {
 void
 void
 event_0(CPT_Event event, void *) {
 event_0(CPT_Event event, void *) {
   // 0: run hacky test.
   // 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 
 void