Bladeren bron

fix pgraph fog

David Rose 24 jaren geleden
bovenliggende
commit
986e2b5cc2

+ 1 - 7
panda/src/glgsg/glGraphicsStateGuardian.cxx

@@ -2515,14 +2515,8 @@ apply_fog(qpFog *fog) {
   call_glFogMode(get_fog_mode_type((Fog::Mode)fmode));
 
   if (fmode == qpFog::M_linear) {
-    // Linear fog may be world-relative or camera-relative.  The fog
-    // object knows how to decode its parameters into camera-relative
-    // properties.
     float onset, opaque;
-    fog->compute_linear_range(onset, opaque, 
-                              qpNodePath(),
-                              // _current_camera,
-                              _coordinate_system);
+    fog->get_linear_range(onset, opaque);
     call_glFogStart(onset);
     call_glFogEnd(opaque);
 

+ 2 - 1
panda/src/pgraph/cullTraverserData.cxx

@@ -69,7 +69,8 @@ apply_transform_and_state(qpCullTraverser *trav) {
     }
   }
 
-  _state = _state->compose(node()->get_state());
+  const RenderState *node_state = node()->get_state();
+  _state = _state->compose(node_state);
 
   const RenderEffects *node_effects = node()->get_effects();
   const BillboardEffect *billboard = node_effects->get_billboard();

+ 11 - 0
panda/src/pgraph/qpcullTraverser.cxx

@@ -20,6 +20,7 @@
 #include "cullTraverserData.h"
 #include "transformState.h"
 #include "renderState.h"
+#include "fogAttrib.h"
 #include "cullHandler.h"
 #include "dcast.h"
 #include "qpgeomNode.h"
@@ -91,6 +92,16 @@ traverse(CullTraverserData &data) {
     data.apply_transform_and_state(this);
 
     PandaNode *node = data.node();
+
+    const FogAttrib *fog = node->get_state()->get_fog();
+    if (fog != (const FogAttrib *)NULL && fog->get_fog() != (qpFog *)NULL) {
+      // If we just introduced a FogAttrib here, call adjust_to_camera()
+      // now.  This maybe isn't the perfect time to call it, but it's
+      // good enough; and at this time we have all the information we
+      // need for it.
+      fog->get_fog()->adjust_to_camera(_camera_transform);
+    }
+
     if (node->has_cull_callback()) {
       if (!node->cull_callback(this, data)) {
         return;

+ 4 - 2
panda/src/pgraph/qpfog.I

@@ -96,10 +96,12 @@ set_color(const Colorf &color) {
 //               M_linear, if it is not already set.
 ////////////////////////////////////////////////////////////////////
 INLINE void qpFog::
-set_linear_range(float onset, float opaque, CoordinateSystem cs) {
-  LVector3f forward = LVector3f::forward(cs);
+set_linear_range(float onset, float opaque) {
+  LVector3f forward = LVector3f::forward();
   _linear_onset_point = onset * forward;
   _linear_opaque_point = opaque * forward;
+  _transformed_onset = onset;
+  _transformed_opaque = opaque;
   _mode = M_linear;
 }
 

+ 37 - 23
panda/src/pgraph/qpfog.cxx

@@ -22,6 +22,7 @@
 
 #include "mathNumbers.h"
 #include "qpnodePath.h"
+#include "transformState.h"
 #include "bamReader.h"
 #include "bamWriter.h"
 #include "datagram.h"
@@ -64,6 +65,8 @@ qpFog(const string &name) :
   _linear_fallback_cosa = -1.0f;
   _linear_fallback_onset = 0.0f;
   _linear_fallback_opaque = 0.0f;
+  _transformed_onset = 0.0f;
+  _transformed_opaque = 0.0f;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -83,6 +86,8 @@ qpFog(const qpFog &copy) :
   _linear_fallback_cosa = copy._linear_fallback_cosa;
   _linear_fallback_onset = copy._linear_fallback_onset;
   _linear_fallback_opaque = copy._linear_fallback_opaque;
+  _transformed_onset = copy._transformed_onset;
+  _transformed_opaque = copy._transformed_opaque;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -142,17 +147,17 @@ output(ostream &out) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: qpFog::compute_linear_range
+//     Function: qpFog::adjust_to_camera
 //       Access: Public
-//  Description: This function is intended to be called by GSG's to
-//               compute the appropriate camera-relative onset and
-//               opaque distances, based on the fog node's position
-//               within the scene graph (if linear fog is in effect).
+//  Description: This function is intended to be called by the cull
+//               traverser to compute the appropriate camera-relative
+//               onset and opaque distances, based on the fog node's
+//               position within the scene graph (if linear fog is in
+//               effect).
 ////////////////////////////////////////////////////////////////////
 void qpFog::
-compute_linear_range(float &onset, float &opaque,
-                     const qpNodePath &camera, CoordinateSystem cs) {
-  LVector3f forward = LVector3f::forward(cs);
+adjust_to_camera(const TransformState *camera_transform) {
+  LVector3f forward = LVector3f::forward();
 
   LPoint3f onset_point, opaque_point;
   if (get_num_parents() != 0) {
@@ -160,7 +165,10 @@ compute_linear_range(float &onset, float &opaque,
     // graph.
     qpNodePath this_np(this);
 
-    const LMatrix4f &mat = this_np.get_mat(camera);
+    CPT(TransformState) rel_transform = 
+      camera_transform->invert_compose(this_np.get_net_transform());
+    
+    const LMatrix4f &mat = rel_transform->get_mat();
 
     // How far out of whack are we?
     LVector3f fog_vector = (_linear_opaque_point - _linear_onset_point) * mat;
@@ -169,24 +177,30 @@ compute_linear_range(float &onset, float &opaque,
     if (cabs(cosa) < _linear_fallback_cosa) {
       // The fog vector is too far from the eye vector; use the
       // fallback mode.
-      onset = _linear_fallback_onset;
-      opaque = _linear_fallback_opaque;
-      //cerr << "fallback! " << cosa << " vs. " << _linear_fallback_cosa << "\n";
-      return;
-    }
+      _transformed_onset = _linear_fallback_onset;
+      _transformed_opaque = _linear_fallback_opaque;
 
-    onset_point = _linear_onset_point * mat;
-    opaque_point = _linear_opaque_point * mat;
+    } else {
+      _transformed_onset = forward.dot(_linear_onset_point * mat);
+      _transformed_opaque = forward.dot(_linear_opaque_point * mat);
+    }
 
   } else {
-    // If the fog object has no parents, we assume the user meant
-    // camera-relative fog.
-    onset_point = _linear_onset_point;
-    opaque_point = _linear_opaque_point;
+    // Not a camera-relative fog.
+    _transformed_onset = forward.dot(_linear_onset_point);
+    _transformed_opaque = forward.dot(_linear_opaque_point);
   }
-  
-  onset = onset_point.dot(forward);
-  opaque = opaque_point.dot(forward);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: qpFog::get_linear_range
+//       Access: Public
+//  Description: Retrieves the current onset and offset ranges.
+////////////////////////////////////////////////////////////////////
+void qpFog::
+get_linear_range(float &onset, float &opaque) {
+  onset = _transformed_onset;
+  opaque = _transformed_opaque;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 6 - 5
panda/src/pgraph/qpfog.h

@@ -26,7 +26,7 @@
 #include "cmath.h"
 #include "deg_2_rad.h"
 
-class qpNodePath;
+class TransformState;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : Fog
@@ -74,8 +74,7 @@ PUBLISHED:
   INLINE void set_color(float r, float g, float b);
   INLINE void set_color(const Colorf &color);
 
-  INLINE void set_linear_range(float onset, float opaque,
-                               CoordinateSystem cs = CS_default);
+  INLINE void set_linear_range(float onset, float opaque);
 
   INLINE const LPoint3f &get_linear_onset_point() const;
   INLINE void set_linear_onset_point(float x, float y, float z);
@@ -93,8 +92,8 @@ PUBLISHED:
   void output(ostream &out) const;
 
 public:
-  void compute_linear_range(float &onset, float &opaque, 
-                            const qpNodePath &camera, CoordinateSystem cs);
+  void adjust_to_camera(const TransformState *camera_transform);
+  void get_linear_range(float &onset, float &opaque);
 
 protected:
   void compute_density();
@@ -116,6 +115,8 @@ protected:
 
   float _linear_fallback_cosa;
   float _linear_fallback_onset, _linear_fallback_opaque;
+  
+  float _transformed_onset, _transformed_opaque;
 
 public:
   static TypeHandle get_class_type() {

+ 2 - 2
panda/src/pgraph/renderEffects.h

@@ -123,8 +123,8 @@ private:
   typedef ov_set<Effect> Effects;
   Effects _effects;
 
-  // We cache the pointer to the some critical effects stored in
-  // the state, if they exist.
+  // We cache the pointer to some critical effects stored in the
+  // state, if they exist.
   const BillboardEffect *_billboard;
 
   enum Flags {

+ 19 - 0
panda/src/pgraph/renderState.I

@@ -197,3 +197,22 @@ get_draw_order() const {
   }
   return _draw_order;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderState::get_fog
+//       Access: Public
+//  Description: This function is provided as an optimization, to
+//               speed up the render-time checking for the existance
+//               of a FogAttrib on this state.  It returns a
+//               pointer to the FogAttrib, if there is one, or
+//               NULL if there is not.
+////////////////////////////////////////////////////////////////////
+INLINE const FogAttrib *RenderState::
+get_fog() const {
+  if ((_flags & F_checked_fog) == 0) {
+    // We pretend this function is const, even though it transparently
+    // modifies the internal fog cache.
+    ((RenderState *)this)->determine_fog();
+  }
+  return _fog;
+}

+ 16 - 0
panda/src/pgraph/renderState.cxx

@@ -20,6 +20,7 @@
 #include "transparencyAttrib.h"
 #include "cullBinAttrib.h"
 #include "cullBinManager.h"
+#include "fogAttrib.h"
 #include "config_pgraph.h"
 #include "bamReader.h"
 #include "bamWriter.h"
@@ -927,6 +928,21 @@ determine_bin_index() {
   _flags |= F_checked_bin_index;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: RenderState::determine_fog
+//       Access: Private
+//  Description: This is the private implementation of get_fog().
+////////////////////////////////////////////////////////////////////
+void RenderState::
+determine_fog() {
+  const RenderAttrib *attrib = get_attrib(FogAttrib::get_class_type());
+  _fog = (const FogAttrib *)NULL;
+  if (attrib != (const RenderAttrib *)NULL) {
+    _fog = DCAST(FogAttrib, attrib);
+  }
+  _flags |= F_checked_fog;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: RenderState::register_with_read_factory
 //       Access: Public, Static

+ 8 - 0
panda/src/pgraph/renderState.h

@@ -28,6 +28,7 @@
 #include "ordered_vector.h"
 
 class GraphicsStateGuardianBase;
+class FogAttrib;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : RenderState
@@ -90,6 +91,7 @@ PUBLISHED:
 public:
   INLINE int get_bin_index() const;
   INLINE int get_draw_order() const;
+  INLINE const FogAttrib *get_fog() const;
 
   CPT(RenderState) issue_delta_modify(const RenderState *other, 
                                       GraphicsStateGuardianBase *gsg) const;
@@ -103,6 +105,7 @@ private:
   CPT(RenderState) do_compose(const RenderState *other) const;
   CPT(RenderState) do_invert_compose(const RenderState *other) const;
   void determine_bin_index();
+  void determine_fog();
 
 private:
   typedef pset<const RenderState *, IndirectLess<RenderState> > States;
@@ -161,8 +164,13 @@ private:
   int _bin_index;
   int _draw_order;
 
+  // We also cache the pointer to some critical attribs stored in the
+  // state, if they exist.
+  const FogAttrib *_fog;
+
   enum Flags {
     F_checked_bin_index    = 0x0001,
+    F_checked_fog          = 0x0002,
   };
   short _flags;
 

+ 0 - 2
panda/src/text/qptextNode.cxx

@@ -442,14 +442,12 @@ decode_text(const string &text) const {
       StringUtf8Decoder decoder(text);
       return decode_text_impl(decoder);
     }
-    break;
 
   case E_unicode:
     {
       StringUnicodeDecoder decoder(text);
       return decode_text_impl(decoder);
     }
-    break;
 
   case E_iso8859:
   default: