Browse Source

support point sprites in more cases, for instance under render2d and under a scale

David Rose 20 years ago
parent
commit
e001e35a60

+ 21 - 19
panda/src/display/graphicsStateGuardian.cxx

@@ -555,6 +555,23 @@ begin_frame() {
 ////////////////////////////////////////////////////////////////////
 bool GraphicsStateGuardian::
 begin_scene() {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::end_scene
+//       Access: Public, Virtual
+//  Description: Called between begin_frame() and end_frame() to mark
+//               the end of drawing commands for a "scene" (usually a
+//               particular DisplayRegion) within a frame.  All 3-D
+//               drawing commands, except the clear operation, must be
+//               enclosed within begin_scene() .. end_scene().
+////////////////////////////////////////////////////////////////////
+void GraphicsStateGuardian::
+end_scene() {
+  // We should clear this pointer now, so that we don't keep unneeded
+  // reference counts dangling.
+  _scene_setup = NULL;
   
   // Undo any lighting we had enabled last scene, to force the lights
   // to be reissued, in case their parameters or positions have
@@ -571,7 +588,7 @@ begin_scene() {
     // Also force the lighting state to unlit, so that issue_light()
     // will be guaranteed to be called next frame even if we have the
     // same set of light pointers we had this frame.
-    modify_state(get_unlit_state());
+    //    modify_state(get_unlit_state());
 
     _lighting_enabled_this_frame = false;
   }
@@ -586,28 +603,13 @@ begin_scene() {
       _clip_plane_info[i]._plane = (PlaneNode *)NULL;
     }
 
-    modify_state(get_unclipped_state());
+    //    modify_state(get_unclipped_state());
 
     _clip_planes_enabled_this_frame = false;
   }
 
-  return true;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: GraphicsStateGuardian::end_scene
-//       Access: Public, Virtual
-//  Description: Called between begin_frame() and end_frame() to mark
-//               the end of drawing commands for a "scene" (usually a
-//               particular DisplayRegion) within a frame.  All 3-D
-//               drawing commands, except the clear operation, must be
-//               enclosed within begin_scene() .. end_scene().
-////////////////////////////////////////////////////////////////////
-void GraphicsStateGuardian::
-end_scene() {
-  // We should clear this pointer now, so that we don't keep unneeded
-  // reference counts dangling.
-  _scene_setup = NULL;
+  // Actually, just clear all the state between scenes.
+  set_state(RenderState::make_empty());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 13 - 2
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -6401,8 +6401,19 @@ do_point_size() {
     LVector3f height(0.0f, _point_size, 1.0f);
     height = height * _projection_mat;
     float s = height[1] * _viewport_height / _point_size;
-    LVecBase3f square(0.0f, 0.0f, 1.0f / (s * s));
-    _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, square.get_data());
+    
+    if (_current_lens->is_orthographic()) {
+      // If we have an orthographic lens in effect, we don't actually
+      // apply a perspective transform: we just scale the points once,
+      // regardless of the distance from the camera.
+      LVecBase3f constant(1.0f / (s * s), 0.0f, 0.0f);
+      _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
+
+    } else {
+      // Otherwise, we give it a true perspective adjustment.
+      LVecBase3f square(0.0f, 0.0f, 1.0f / (s * s));
+      _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, square.get_data());
+    }
   }
 
   report_my_gl_errors();

+ 25 - 1
panda/src/gobj/lens.cxx

@@ -862,6 +862,30 @@ is_linear() const {
   return false;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Lens::is_perspective
+//       Access: Published, Virtual
+//  Description: Returns true if the lens represents a perspective
+//               projection (i.e. it is a PerspectiveLens), false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool Lens::
+is_perspective() const {
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Lens::is_orthographic
+//       Access: Published, Virtual
+//  Description: Returns true if the lens represents a orthographic
+//               projection (i.e. it is a OrthographicLens), false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool Lens::
+is_orthographic() const {
+  return false;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Lens::make_geometry
 //       Access: Published, Virtual
@@ -1274,7 +1298,7 @@ extrude_impl(const LPoint3f &point2d, LPoint3f &near_point, LPoint3f &far_point)
 //               set_view_vector().
 //
 //               For all linear lenses, including perspective and
-//               ortographic lenses, all points on the film compute
+//               orthographic lenses, all points on the film compute
 //               this same vector (the far plane is a flat plane, so
 //               the normal is the same everywhere).  For curved
 //               lenses like fisheye and cylindrical lenses, different

+ 2 - 0
panda/src/gobj/lens.h

@@ -136,6 +136,8 @@ PUBLISHED:
   void recompute_all();
 
   virtual bool is_linear() const;
+  virtual bool is_perspective() const;
+  virtual bool is_orthographic() const;
   virtual PT(Geom) make_geometry();
 
   virtual PT(BoundingVolume) make_bounds() const;

+ 13 - 1
panda/src/gobj/orthographicLens.cxx

@@ -45,6 +45,18 @@ is_linear() const {
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: OrthographicLens::is_orthographic
+//       Access: Published, Virtual
+//  Description: Returns true if the lens represents a orthographic
+//               projection (i.e. it is a OrthographicLens), false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool OrthographicLens::
+is_orthographic() const {
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: OrthographicLens::write
 //       Access: Public, Virtual
@@ -103,7 +115,7 @@ compute_projection_mat() {
 
   default:
     gobj_cat.error()
-      << "Invalid coordinate system " << (int)cs << " in PerspectiveLens!\n";
+      << "Invalid coordinate system " << (int)cs << " in OrthographicLens!\n";
     canonical = LMatrix4f::ident_mat();
   }
 

+ 1 - 0
panda/src/gobj/orthographicLens.h

@@ -46,6 +46,7 @@ public:
 public:
   virtual PT(Lens) make_copy() const;
   virtual bool is_linear() const;
+  virtual bool is_orthographic() const;
 
   virtual void write(ostream &out, int indent_level = 0) const;
 

+ 12 - 0
panda/src/gobj/perspectiveLens.cxx

@@ -44,6 +44,18 @@ is_linear() const {
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PerspectiveLens::is_perspective
+//       Access: Published, Virtual
+//  Description: Returns true if the lens represents a perspective
+//               projection (i.e. it is a PerspectiveLens), false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool PerspectiveLens::
+is_perspective() const {
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PerspectiveLens::compute_projection_mat
 //       Access: Protected, Virtual

+ 1 - 0
panda/src/gobj/perspectiveLens.h

@@ -39,6 +39,7 @@ public:
 public:
   virtual PT(Lens) make_copy() const;
   virtual bool is_linear() const;
+  virtual bool is_perspective() const;
 
 protected:
   virtual void compute_projection_mat();

+ 14 - 11
panda/src/gobj/qpgeomEnums.h

@@ -103,34 +103,37 @@ PUBLISHED:
     // If the points have a non-square aspect ratio.
     GR_point_aspect_ratio   = 0x0020,
 
+    // If the points are under a scale transform, uniform or non-uniform.
+    GR_point_scale          = 0x0040,
+
     // If the points are rotated off the orthonormal axis.
-    GR_point_rotate         = 0x0040,
+    GR_point_rotate         = 0x0080,
 
     // If the points require texture coordinates interpolated across
     // their face, to render textures as sprites.
-    GR_point_sprite         = 0x0080,
+    GR_point_sprite         = 0x0100,
 
     // If there is a texture matrix applied to the sprite's generated
     // texture coordinates.
-    GR_point_sprite_tex_matrix = 0x0100,
+    GR_point_sprite_tex_matrix = 0x0200,
 
     // The union of all the above point attributes, except GR_indexed_point.
-    GR_point_bits           = 0x01f3,
+    GR_point_bits           = 0x03f3,
 
     // If there are any of these composite types.
-    GR_triangle_strip       = 0x0200,
-    GR_triangle_fan         = 0x0400,
-    GR_line_strip           = 0x0800,
+    GR_triangle_strip       = 0x0400,
+    GR_triangle_fan         = 0x0800,
+    GR_line_strip           = 0x1000,
 
     // The union of all of the above composite types.
-    GR_composite_bits       = 0x0e00,
+    GR_composite_bits       = 0x1c00,
 
     // If the shade model requires a particular vertex for flat shading.
-    GR_flat_first_vertex    = 0x1000,
-    GR_flat_last_vertex     = 0x2000,
+    GR_flat_first_vertex    = 0x2000,
+    GR_flat_last_vertex     = 0x4000,
 
     // The union of the above shade model types.
-    GR_shade_model_bits     = 0x3000,
+    GR_shade_model_bits     = 0x6000,
   };
 
   // The shade model specifies whether the per-vertex colors and

+ 12 - 7
panda/src/pgraph/cullableObject.cxx

@@ -52,7 +52,9 @@ munge_geom(GraphicsStateGuardianBase *gsg,
       CPT(qpGeom) qpgeom = DCAST(qpGeom, _geom);
       _munged_data = qpgeom->get_vertex_data();
 
-      int geom_rendering = _state->get_geom_rendering(qpgeom->get_geom_rendering());
+      int geom_rendering = qpgeom->get_geom_rendering();
+      geom_rendering = _state->get_geom_rendering(geom_rendering);
+      geom_rendering = _transform->get_geom_rendering(geom_rendering);
 
       GraphicsStateGuardianBase *gsg = traverser->get_gsg();
       int gsg_bits = gsg->get_supported_geom_rendering();
@@ -331,17 +333,20 @@ munge_points_to_quads(const CullTraverser *traverser) {
 
       float scale_y = point_size;
       if (perspective) {
-        // Perspective-sized points.  Here point_size is a width in 3-d
-        // units.  To arrange that, we need to figure out the appropriate
-        // scaling factor based on the current viewport and projection
-        // matrix.
-        LVector3f height(0.0f, point_size, 1.0f);
+        // Perspective-sized points.  Here point_size is the point's
+        // height in 3-d units.  To arrange that, we need to figure
+        // out the appropriate scaling factor based on the current
+        // viewport and projection matrix.
+        float scale = _transform->get_scale()[1];
+        LVector3f height(0.0f, point_size * scale, scale);
         height = height * projection;
         scale_y = height[1] * viewport_height;
 
         // We should then divide the radius by the distance from the
         // camera plane, to emulate the glPointParameters() behavior.
-        scale_y /= gsg->compute_distance_to(eye);
+        if (!lens->is_orthographic()) {
+          scale_y /= gsg->compute_distance_to(eye);
+        }
       }
       
       // Also factor in the homogeneous scale for being in clip

+ 1 - 1
panda/src/pgraph/texGenAttrib.I

@@ -55,7 +55,7 @@ INLINE int TexGenAttrib::
 get_geom_rendering(int geom_rendering) const {
   if ((geom_rendering & qpGeom::GR_point) != 0) {
     if (_num_point_sprites > 0) {
-      return geom_rendering |= qpGeom::GR_point_sprite;
+      geom_rendering |= qpGeom::GR_point_sprite;
     }
   }
 

+ 1 - 1
panda/src/pgraph/texMatrixAttrib.I

@@ -52,7 +52,7 @@ INLINE int TexMatrixAttrib::
 get_geom_rendering(int geom_rendering) const {
   if ((geom_rendering & qpGeom::GR_point_sprite) != 0) {
     if (!is_empty()) {
-      return geom_rendering |= qpGeom::GR_point_sprite_tex_matrix;
+      geom_rendering |= qpGeom::GR_point_sprite_tex_matrix;
     }
   }
 

+ 40 - 6
panda/src/pgraph/transformState.I

@@ -288,6 +288,18 @@ has_scale() const {
   return has_components();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TransformState::has_identity_scale
+//       Access: Published
+//  Description: Returns true if the scale is uniform 1.0, or false if
+//               the scale has some real value.
+////////////////////////////////////////////////////////////////////
+INLINE bool TransformState::
+has_identity_scale() const {
+  check_components();
+  return (_flags & F_identity_scale) != 0;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TransformState::has_uniform_scale
 //       Access: Published
@@ -363,7 +375,6 @@ INLINE const LVecBase3f &TransformState::
 get_hpr() const {
   check_hpr();
   nassertr(!is_invalid(), _hpr);
-  //  nassertr(has_hpr(), _hpr);
   return _hpr;
 }
 
@@ -378,7 +389,6 @@ INLINE const LQuaternionf &TransformState::
 get_quat() const {
   check_quat();
   nassertr(!is_invalid(), _quat);
-  //  nassertr(has_quat(), _quat);
   return _quat;
 }
 
@@ -393,7 +403,6 @@ INLINE const LVecBase3f &TransformState::
 get_scale() const {
   check_components();
   nassertr(!is_invalid(), _scale);
-  //  nassertr(has_scale(), _scale);
   return _scale;
 }
 
@@ -437,6 +446,27 @@ get_mat() const {
   return _mat;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TransformState::get_geom_rendering
+//       Access: Published
+//  Description: Returns the union of the Geom::GeomRendering bits
+//               that will be required once this TransformState is
+//               applied to a geom which includes the indicated
+//               geom_rendering bits.  The RenderState's
+//               get_geom_rendering() should already have been
+//               applied.
+////////////////////////////////////////////////////////////////////
+INLINE int TransformState::
+get_geom_rendering(int geom_rendering) const {
+  if ((geom_rendering & qpGeomEnums::GR_point_perspective) != 0) {
+    if (!has_identity_scale()) {
+      geom_rendering |= qpGeomEnums::GR_point_scale;
+    }
+  }
+
+  return geom_rendering;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TransformState::cache_ref
 //       Access: Published
@@ -582,16 +612,20 @@ check_mat() const {
 //     Function: TransformState::check_uniform_scale
 //       Access: Private
 //  Description: Should be called immediately after _scale (and
-//               F_has_components) is set, this checks for a uniform
-//               scale (as well as a non-zero shear) and sets the bit
-//               appropriately.
+//               F_has_components) is set, this checks for a
+//               identity and/or uniform scale (as well as a non-zero
+//               shear) and sets the bit appropriately.
 ////////////////////////////////////////////////////////////////////
 INLINE void TransformState::
 check_uniform_scale() {
   if (IS_NEARLY_EQUAL(_scale[0], _scale[1]) && 
       IS_NEARLY_EQUAL(_scale[0], _scale[2])) {
     _flags |= F_uniform_scale;
+    if (IS_NEARLY_EQUAL(_scale[0], 1.0f)) {
+      _flags |= F_identity_scale;
+    }
   }
+
   if (!_shear.almost_equal(LVecBase3f::zero())) {
     _flags |= F_has_nonzero_shear;
   }

+ 6 - 1
panda/src/pgraph/transformState.h

@@ -28,6 +28,7 @@
 #include "event.h"
 #include "updateSeq.h"
 #include "pStatCollector.h"
+#include "qpgeomEnums.h"
 
 class GraphicsStateGuardianBase;
 class FactoryParams;
@@ -106,6 +107,7 @@ PUBLISHED:
   INLINE bool has_hpr() const;
   INLINE bool has_quat() const;
   INLINE bool has_scale() const;
+  INLINE bool has_identity_scale() const;
   INLINE bool has_uniform_scale() const;
   INLINE bool has_shear() const;
   INLINE bool has_nonzero_shear() const;
@@ -127,6 +129,8 @@ PUBLISHED:
   CPT(TransformState) compose(const TransformState *other) const;
   CPT(TransformState) invert_compose(const TransformState *other) const;
 
+  INLINE int get_geom_rendering(int geom_rendering) const;
+
   int unref() const;
 
   INLINE int cache_ref() const;
@@ -246,7 +250,8 @@ private:
     F_hpr_given          = 0x0400,
     F_hpr_known          = 0x0800,  // set if _hpr is defined
     F_uniform_scale      = 0x1000,
-    F_has_nonzero_shear  = 0x2000,
+    F_identity_scale     = 0x2000,
+    F_has_nonzero_shear  = 0x4000,
     F_is_destructing     = 0x8000,
   };
   LVecBase3f _pos, _hpr, _scale, _shear;