Forráskód Böngészése

fix some sprite issues

David Rose 17 éve
szülő
commit
0a6a6dcb3e

+ 6 - 0
panda/src/gobj/config_gobj.cxx

@@ -191,6 +191,12 @@ ConfigVariableBool hardware_point_sprites
           "computed in software, even if the hardware claims it can "
           "computed in software, even if the hardware claims it can "
           "support them directly."));
           "support them directly."));
 
 
+ConfigVariableBool hardware_points
+("hardware-points", true,
+ PRC_DESC("Set this true to allow the use of hardware extensions when "
+          "rendering large points.  When false, large points (even if "
+          "untextured) will be simulated via quads computed in software."));
+
 ConfigVariableBool matrix_palette
 ConfigVariableBool matrix_palette
 ("matrix-palette", false,
 ("matrix-palette", false,
  PRC_DESC("Set this true to allow the use of the matrix palette when "
  PRC_DESC("Set this true to allow the use of the matrix palette when "

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

@@ -62,6 +62,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_arrays;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool display_lists;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool display_lists;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_animated_vertices;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_animated_vertices;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_point_sprites;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_point_sprites;
+extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_points;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool matrix_palette;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool matrix_palette;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool display_list_animation;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool display_list_animation;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool connect_triangle_strips;
 extern EXPCL_PANDA_GOBJ ConfigVariableBool connect_triangle_strips;

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

@@ -177,3 +177,22 @@ INLINE bool CullableObject::SortPoints::
 operator () (unsigned short a, unsigned short b) const {
 operator () (unsigned short a, unsigned short b) const {
   return _array[a]._dist > _array[b]._dist;
   return _array[a]._dist > _array[b]._dist;
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullableObject::SourceFormat::operator <
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE bool CullableObject::SourceFormat::
+operator < (const CullableObject::SourceFormat &other) const {
+  if (_format != other._format) {
+    return _format < other._format;
+  }
+  if (_sprite_texcoord != other._sprite_texcoord) {
+    return (int)_sprite_texcoord < (int)other._sprite_texcoord;
+  }
+  if (_retransform_sprites != other._retransform_sprites) {
+    return (int)_retransform_sprites < (int)other._retransform_sprites;
+  }
+  return false;
+}

+ 91 - 60
panda/src/pgraph/cullableObject.cxx

@@ -27,8 +27,10 @@
 #include "geomVertexReader.h"
 #include "geomVertexReader.h"
 #include "geomTriangles.h"
 #include "geomTriangles.h"
 #include "light.h"
 #include "light.h"
+#include "lightMutexHolder.h"
 
 
 CullableObject::FormatMap CullableObject::_format_map;
 CullableObject::FormatMap CullableObject::_format_map;
+LightMutex CullableObject::_format_lock;
 
 
 PStatCollector CullableObject::_munge_geom_pcollector("*:Munge:Geom");
 PStatCollector CullableObject::_munge_geom_pcollector("*:Munge:Geom");
 PStatCollector CullableObject::_munge_sprites_pcollector("*:Munge:Sprites");
 PStatCollector CullableObject::_munge_sprites_pcollector("*:Munge:Sprites");
@@ -83,6 +85,11 @@ munge_geom(GraphicsStateGuardianBase *gsg,
       // supports them.
       // supports them.
       gsg_bits &= ~(Geom::GR_point_perspective | Geom::GR_point_sprite);
       gsg_bits &= ~(Geom::GR_point_perspective | Geom::GR_point_sprite);
     }
     }
+    if (!hardware_points) {
+      // If hardware-points is off, we don't all any kind of point
+      // rendering, except plain old one-pixel points;
+      gsg_bits &= ~(Geom::GR_point_bits & ~Geom::GR_point);
+    }
     int unsupported_bits = geom_rendering & ~gsg_bits;
     int unsupported_bits = geom_rendering & ~gsg_bits;
 
 
     if ((unsupported_bits & Geom::GR_point_bits) != 0) {
     if ((unsupported_bits & Geom::GR_point_bits) != 0) {
@@ -205,29 +212,35 @@ output(ostream &out) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool CullableObject::
 bool CullableObject::
 munge_points_to_quads(const CullTraverser *traverser, bool force) {
 munge_points_to_quads(const CullTraverser *traverser, bool force) {
-  if (!force && !_munged_data->request_resident()) {
+  Thread *current_thread = traverser->get_current_thread();
+
+  // Better get the animated vertices, in case we're showing sprites
+  // on an animated model for some reason.
+  CPT(GeomVertexData) source_data = 
+    _munged_data->animate_vertices(force, current_thread);
+
+  if (!force && !source_data->request_resident()) {
     return false;
     return false;
   }
   }
 
 
-  Thread *current_thread = traverser->get_current_thread();
   PStatTimer timer(_munge_sprites_pcollector, current_thread);
   PStatTimer timer(_munge_sprites_pcollector, current_thread);
-  _sw_sprites_pcollector.add_level(_munged_data->get_num_rows());
+  _sw_sprites_pcollector.add_level(source_data->get_num_rows());
 
 
   GraphicsStateGuardianBase *gsg = traverser->get_gsg();
   GraphicsStateGuardianBase *gsg = traverser->get_gsg();
 
 
-  GeomVertexReader vertex(_munged_data, InternalName::get_vertex(),
+  GeomVertexReader vertex(source_data, InternalName::get_vertex(),
                           current_thread);
                           current_thread);
-  GeomVertexReader normal(_munged_data, InternalName::get_normal(),
+  GeomVertexReader normal(source_data, InternalName::get_normal(),
                           current_thread);
                           current_thread);
-  GeomVertexReader color(_munged_data, InternalName::get_color(),
+  GeomVertexReader color(source_data, InternalName::get_color(),
                          current_thread);
                          current_thread);
-  GeomVertexReader texcoord(_munged_data, InternalName::get_texcoord(),
+  GeomVertexReader texcoord(source_data, InternalName::get_texcoord(),
                             current_thread);
                             current_thread);
-  GeomVertexReader rotate(_munged_data, InternalName::get_rotate(),
+  GeomVertexReader rotate(source_data, InternalName::get_rotate(),
                           current_thread);
                           current_thread);
-  GeomVertexReader size(_munged_data, InternalName::get_size(),
+  GeomVertexReader size(source_data, InternalName::get_size(),
                         current_thread);
                         current_thread);
-  GeomVertexReader aspect_ratio(_munged_data, InternalName::get_aspect_ratio(),
+  GeomVertexReader aspect_ratio(source_data, InternalName::get_aspect_ratio(),
                                 current_thread);
                                 current_thread);
 
 
   bool has_normal = (normal.has_column());
   bool has_normal = (normal.has_column());
@@ -244,7 +257,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
       sprite_texcoord = true;
       sprite_texcoord = true;
 
 
       // Turn off the TexGenAttrib, since we don't want it now.
       // Turn off the TexGenAttrib, since we don't want it now.
-      _state = _state->add_attrib(tex_gen->remove_stage(TextureStage::get_default()));
+      _state = _state->set_attrib(tex_gen->remove_stage(TextureStage::get_default()));
     }
     }
   }
   }
 
 
@@ -258,61 +271,66 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
     if (render_mode->get_mode() != RenderModeAttrib::M_filled_flat) {
     if (render_mode->get_mode() != RenderModeAttrib::M_filled_flat) {
       // Render the new polygons with M_filled_flat, for a slight
       // Render the new polygons with M_filled_flat, for a slight
       // performance advantage when software rendering.
       // performance advantage when software rendering.
-      _state = _state->add_attrib(RenderModeAttrib::make(RenderModeAttrib::M_filled_flat));
+      _state = _state->set_attrib(RenderModeAttrib::make(RenderModeAttrib::M_filled_flat));
     }
     }
   }
   }
 
 
   // Get the vertex format of the newly created geometry.
   // Get the vertex format of the newly created geometry.
   CPT(GeomVertexFormat) new_format;
   CPT(GeomVertexFormat) new_format;
-  FormatMap::iterator fmi = _format_map.find(_munged_data->get_format());
-  if (fmi != _format_map.end()) {
-    new_format = (*fmi).second;
 
 
-  } else {
-    // We have to construct the format now.
-    PT(GeomVertexArrayFormat) new_array_format;
-    if (retransform_sprites) {
-      // With retransform_sprites in effect, we will be sending ordinary
-      // 3-D points to the graphics API.
-      new_array_format = 
-        new GeomVertexArrayFormat(InternalName::get_vertex(), 3, 
-                                  Geom::NT_float32,
-                                  Geom::C_point);
+  {
+    LightMutexHolder holder(_format_lock);
+    SourceFormat sformat(source_data->get_format(), sprite_texcoord);
+    FormatMap::iterator fmi = _format_map.find(sformat);
+    if (fmi != _format_map.end()) {
+      new_format = (*fmi).second;
+      
     } else {
     } else {
-      // Without retransform_sprites, we will be sending 4-component
-      // clip-space points.
-      new_array_format = 
-        new GeomVertexArrayFormat(InternalName::get_vertex(), 4, 
-                                  Geom::NT_float32,
-                                  Geom::C_clip_point);
-    }
-    if (has_normal) {
-      const GeomVertexColumn *c = normal.get_column();
-      new_array_format->add_column
-        (InternalName::get_normal(), c->get_num_components(),
-         c->get_numeric_type(), c->get_contents());
-    }
-    if (has_color) {
-      const GeomVertexColumn *c = color.get_column();
-      new_array_format->add_column
-        (InternalName::get_color(), c->get_num_components(),
-         c->get_numeric_type(), c->get_contents());
-    }
-    if (sprite_texcoord) {
-      new_array_format->add_column
-        (InternalName::get_texcoord(), 2,
-         Geom::NT_float32,
-         Geom::C_texcoord);
-
-    } else if (has_texcoord) {
-      const GeomVertexColumn *c = texcoord.get_column();
-      new_array_format->add_column
-        (InternalName::get_texcoord(), c->get_num_components(),
-         c->get_numeric_type(), c->get_contents());
+      // We have to construct the format now.
+      PT(GeomVertexArrayFormat) new_array_format;
+      if (sformat._retransform_sprites) {
+        // With retransform_sprites in effect, we will be sending ordinary
+        // 3-D points to the graphics API.
+        new_array_format = 
+          new GeomVertexArrayFormat(InternalName::get_vertex(), 3, 
+                                    Geom::NT_float32,
+                                    Geom::C_point);
+      } else {
+        // Without retransform_sprites, we will be sending 4-component
+        // clip-space points.
+        new_array_format = 
+          new GeomVertexArrayFormat(InternalName::get_vertex(), 4, 
+                                    Geom::NT_float32,
+                                    Geom::C_clip_point);
+      }
+      if (has_normal) {
+        const GeomVertexColumn *c = normal.get_column();
+        new_array_format->add_column
+          (InternalName::get_normal(), c->get_num_components(),
+           c->get_numeric_type(), c->get_contents());
+      }
+      if (has_color) {
+        const GeomVertexColumn *c = color.get_column();
+        new_array_format->add_column
+          (InternalName::get_color(), c->get_num_components(),
+           c->get_numeric_type(), c->get_contents());
+      }
+      if (sprite_texcoord) {
+        new_array_format->add_column
+          (InternalName::get_texcoord(), 2,
+           Geom::NT_float32,
+           Geom::C_texcoord);
+        
+      } else if (has_texcoord) {
+        const GeomVertexColumn *c = texcoord.get_column();
+        new_array_format->add_column
+          (InternalName::get_texcoord(), c->get_num_components(),
+           c->get_numeric_type(), c->get_contents());
+      }
+      
+      new_format = GeomVertexFormat::register_format(new_array_format);
+      _format_map[sformat] = new_format;
     }
     }
-
-    new_format = GeomVertexFormat::register_format(new_array_format);
-    _format_map[_munged_data->get_format()] = new_format;
   }
   }
 
 
   const LMatrix4f &modelview = _modelview_transform->get_mat();
   const LMatrix4f &modelview = _modelview_transform->get_mat();
@@ -341,11 +359,11 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
   // We always convert all the vertices, assuming all the vertices
   // We always convert all the vertices, assuming all the vertices
   // will referenced by GeomPrimitives, because we want to optimize
   // will referenced by GeomPrimitives, because we want to optimize
   // for the most common case.
   // for the most common case.
-  int orig_verts = _munged_data->get_num_rows();
+  int orig_verts = source_data->get_num_rows();
   int new_verts = 4 * orig_verts;        // each vertex becomes four.
   int new_verts = 4 * orig_verts;        // each vertex becomes four.
 
 
   PT(GeomVertexData) new_data = new GeomVertexData
   PT(GeomVertexData) new_data = new GeomVertexData
-    (_munged_data->get_name(), new_format, Geom::UH_stream);
+    (source_data->get_name(), new_format, Geom::UH_stream);
   new_data->unclean_set_num_rows(new_verts);
   new_data->unclean_set_num_rows(new_verts);
 
 
   GeomVertexWriter new_vertex(new_data, InternalName::get_vertex());
   GeomVertexWriter new_vertex(new_data, InternalName::get_vertex());
@@ -730,3 +748,16 @@ get_flash_hardware_state() {
 
 
   return flash_hardware_state;
   return flash_hardware_state;
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: CullableObject::SourceFormat::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+CullableObject::SourceFormat::
+SourceFormat(const GeomVertexFormat *format, bool sprite_texcoord) :
+  _format(format),
+  _sprite_texcoord(sprite_texcoord) 
+{
+  _retransform_sprites = retransform_sprites;
+}

+ 12 - 1
panda/src/pgraph/cullableObject.h

@@ -29,6 +29,7 @@
 #include "pStatCollector.h"
 #include "pStatCollector.h"
 #include "deletedChain.h"
 #include "deletedChain.h"
 #include "graphicsStateGuardianBase.h"
 #include "graphicsStateGuardianBase.h"
+#include "lightMutex.h"
 
 
 class CullTraverser;
 class CullTraverser;
 
 
@@ -106,8 +107,18 @@ private:
   };
   };
 
 
   // This is a cache of converted vertex formats.
   // This is a cache of converted vertex formats.
-  typedef pmap<CPT(GeomVertexFormat), CPT(GeomVertexFormat) > FormatMap;
+  class SourceFormat {
+  public:
+    SourceFormat(const GeomVertexFormat *format, bool sprite_texcoord);
+    INLINE bool operator < (const SourceFormat &other) const;
+
+    CPT(GeomVertexFormat) _format;
+    bool _sprite_texcoord;
+    bool _retransform_sprites;
+  };
+  typedef pmap<SourceFormat, CPT(GeomVertexFormat) > FormatMap;
   static FormatMap _format_map;
   static FormatMap _format_map;
+  static LightMutex _format_lock;
 
 
   static PStatCollector _munge_geom_pcollector;
   static PStatCollector _munge_geom_pcollector;
   static PStatCollector _munge_sprites_pcollector;
   static PStatCollector _munge_sprites_pcollector;

+ 4 - 0
panda/src/pgraph/renderModeAttrib.cxx

@@ -93,6 +93,10 @@ output(ostream &out) const {
     break;
     break;
   }
   }
 
 
+  if (get_thickness() != 1.0f) {
+    out << ", thick " << get_thickness();
+  }
+
   if (get_perspective()) {
   if (get_perspective()) {
     out << ", perspective";
     out << ", perspective";
   }
   }