Browse Source

Fix issues with point rendering, both software and hardware.

rdb 11 years ago
parent
commit
ab8ebe6e30

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

@@ -538,7 +538,7 @@ reset() {
     }
   }
   if (_supports_point_parameters) {
-    _supported_geom_rendering |= Geom::GR_point_perspective;
+    _supported_geom_rendering |= Geom::GR_point_perspective | Geom::GR_point_scale;
   } else {
     _glPointParameterfv = null_glPointParameterfv;
   }
@@ -2764,7 +2764,7 @@ end_frame(Thread *current_thread) {
 
     // And deleted queries, too, unless we're using query timers
     // in which case we'll need to reuse lots of them.
-    if (!_timer_queries_active && !_deleted_queries.empty()) {
+    if (!get_timer_queries_active() && !_deleted_queries.empty()) {
       if (GLCAT.is_spam()) {
         DeletedNames::iterator dqi;
         for (dqi = _deleted_queries.begin();
@@ -11335,6 +11335,7 @@ do_point_size() {
     // matrix.
     LVector3 height(0.0f, _point_size, 1.0f);
     height = height * _projection_mat->get_mat();
+    height = height * _internal_transform->get_scale()[1];
     PN_stdfloat s = height[1] * _viewport_height / _point_size;
 
     if (_current_lens->is_orthographic()) {

+ 27 - 0
panda/src/gobj/geomPrimitive.I

@@ -429,6 +429,17 @@ add_vertices(int v1, int v2, int v3, int v4) {
   add_vertex(v4);
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomPrimitive::get_index_format
+//       Access: Public
+//  Description: Returns a registered format appropriate for using to
+//               store the index table.
+////////////////////////////////////////////////////////////////////
+INLINE const GeomVertexArrayFormat *GeomPrimitive::
+get_index_format() const {
+  return get_index_format(get_index_type());
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomPrimitive::make_index_data
 //       Access: Public
@@ -439,6 +450,22 @@ make_index_data() const {
   return new GeomVertexArrayData(get_index_format(), get_usage_hint());
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GeomPrimitive::make_index_format
+//       Access: Private, Static
+//  Description: Returns a registered format appropriate for using to
+//               store the index table.
+////////////////////////////////////////////////////////////////////
+INLINE CPT(GeomVertexArrayFormat) GeomPrimitive::
+make_index_format(NumericType index_type) {
+  PT(GeomVertexArrayFormat) format = new GeomVertexArrayFormat;
+  // It's important that the index format *not* respect the global
+  // setting of vertex-column-alignment.  It needs to be tightly
+  // packed, so we specify an explict column_alignment of 1.
+  format->add_column(InternalName::get_index(), 1, index_type, C_index, 0, 1);
+  return GeomVertexArrayFormat::register_format(format);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomPrimitive::CData::Constructor
 //       Access: Public

+ 40 - 12
panda/src/gobj/geomPrimitive.cxx

@@ -1233,6 +1233,11 @@ set_vertices(const GeomVertexArrayData *vertices, int num_vertices) {
   cdata->_vertices = (GeomVertexArrayData *)vertices;
   cdata->_num_vertices = num_vertices;
 
+  // Validate the format and make sure to copy its numeric type.
+  const GeomVertexArrayFormat *format = vertices->get_array_format();
+  nassertv(format->get_num_columns() == 1);
+  cdata->_index_type = format->get_column(0)->get_numeric_type();
+
   cdata->_modified = Geom::get_next_modified();
   cdata->_got_minmax = false;
 }
@@ -1564,18 +1569,41 @@ release_all() {
 
 ////////////////////////////////////////////////////////////////////
 //     Function: GeomPrimitive::get_index_format
-//       Access: Public
-//  Description: Returns a registered format appropriate for using to
-//               store the index table.
-////////////////////////////////////////////////////////////////////
-CPT(GeomVertexArrayFormat) GeomPrimitive::
-get_index_format() const {
-  PT(GeomVertexArrayFormat) format = new GeomVertexArrayFormat;
-  // It's important that the index format *not* respect the global
-  // setting of vertex-column-alignment.  It needs to be tightly
-  // packed, so we specify an explict column_alignment of 1.
-  format->add_column(InternalName::get_index(), 1, get_index_type(), C_index, 0, 1);
-  return GeomVertexArrayFormat::register_format(format);
+//       Access: Public, Static
+//  Description: Returns a registered GeomVertexArrayFormat of the
+//               indicated unsigned integer numeric type for storing
+//               index values.
+////////////////////////////////////////////////////////////////////
+const GeomVertexArrayFormat *GeomPrimitive::
+get_index_format(NumericType index_type) {
+  switch (index_type) {
+  case NT_uint8:
+    {
+      static CPT(GeomVertexArrayFormat) cformat = NULL;
+      if (cformat == NULL) {
+        cformat = make_index_format(NT_uint8);
+      }
+      return cformat;
+    }
+  case NT_uint16:
+    {
+      static CPT(GeomVertexArrayFormat) cformat = NULL;
+      if (cformat == NULL) {
+        cformat = make_index_format(NT_uint16);
+      }
+      return cformat;
+    }
+  case NT_uint32:
+    {
+      static CPT(GeomVertexArrayFormat) cformat = NULL;
+      if (cformat == NULL) {
+        cformat = make_index_format(NT_uint32);
+      }
+      return cformat;
+    }
+  }
+
+  return NULL;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 7 - 4
panda/src/gobj/geomPrimitive.h

@@ -185,15 +185,18 @@ public:
   void prepare(PreparedGraphicsObjects *prepared_objects);
   bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
 
-  IndexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects, 
+  IndexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
                                   GraphicsStateGuardianBase *gsg);
   bool release(PreparedGraphicsObjects *prepared_objects);
   int release_all();
 
-  CPT(GeomVertexArrayFormat) get_index_format() const;
+  static const GeomVertexArrayFormat *get_index_format(NumericType index_type);
+  INLINE const GeomVertexArrayFormat *get_index_format() const;
   INLINE PT(GeomVertexArrayData) make_index_data() const;
 
 private:
+  static CPT(GeomVertexArrayFormat) make_index_format(NumericType index_type);
+
   void clear_prepared(PreparedGraphicsObjects *prepared_objects);
   static int get_highest_index_value(NumericType index_type);
   static int get_strip_cut_index(NumericType index_type);
@@ -204,7 +207,7 @@ public:
                     bool force) const=0;
 
   void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
-                         bool &found_any, 
+                         bool &found_any,
                          const GeomVertexData *vertex_data,
                          bool got_mat, const LMatrix4 &mat,
                          const InternalName *column_name,
@@ -216,7 +219,7 @@ protected:
   virtual CPT(GeomPrimitive) doubleside_impl() const;
   virtual CPT(GeomPrimitive) reverse_impl() const;
   virtual bool requires_unused_vertices() const;
-  virtual void append_unused_vertices(GeomVertexArrayData *vertices, 
+  virtual void append_unused_vertices(GeomVertexArrayData *vertices,
                                       int vertex);
 
 private:

+ 39 - 37
panda/src/pgraph/cullableObject.cxx

@@ -76,11 +76,11 @@ munge_geom(GraphicsStateGuardianBase *gsg,
         nassertr(geom_reader.check_valid(&data_reader), false);
       }
 #endif  // _DEBUG
-      
+
       geom_rendering = geom_reader.get_geom_rendering();
       geom_rendering = _state->get_geom_rendering(geom_rendering);
       geom_rendering = _modelview_transform->get_geom_rendering(geom_rendering);
-      
+
       if (geom_rendering & Geom::GR_point_bits) {
         if (geom_reader.get_primitive_type() != Geom::PT_points) {
           if (singular_points) {
@@ -90,7 +90,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
         }
       }
     }
-    
+
     GraphicsStateGuardianBase *gsg = traverser->get_gsg();
     int gsg_bits = gsg->get_supported_geom_rendering();
     if (!hardware_point_sprites) {
@@ -113,7 +113,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
       // _munged_data, and might also replace _state.
       if (pgraph_cat.is_spam()) {
         pgraph_cat.spam()
-          << "munge_points_to_quads() for geometry with bits: " 
+          << "munge_points_to_quads() for geometry with bits: "
           << hex << geom_rendering << ", unsupported: "
           << (unsupported_bits & Geom::GR_point_bits) << dec << "\n";
       }
@@ -128,7 +128,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
       // If we have to compute the light vector, we have to animate
       // the vertices in the CPU--and we have to do it before we call
       // munge_geom(), which might lose the tangent and binormal.
-      CPT(GeomVertexData) animated_vertices = 
+      CPT(GeomVertexData) animated_vertices =
         _munged_data->animate_vertices(force, current_thread);
       if (animated_vertices != _munged_data) {
         cpu_animated = true;
@@ -154,7 +154,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
       // has been munged--that is, we couldn't arrange to handle the
       // animation in hardware--then we have to calculate that
       // animation now.
-      CPT(GeomVertexData) animated_vertices = 
+      CPT(GeomVertexData) animated_vertices =
         _munged_data->animate_vertices(force, current_thread);
       if (animated_vertices != _munged_data) {
         cpu_animated = true;
@@ -238,7 +238,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
 
   // Better get the animated vertices, in case we're showing sprites
   // on an animated model for some reason.
-  CPT(GeomVertexData) source_data = 
+  CPT(GeomVertexData) source_data =
     _munged_data->animate_vertices(force, current_thread);
 
   if (!force && !source_data->request_resident()) {
@@ -306,22 +306,22 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
     FormatMap::iterator fmi = _format_map.find(sformat);
     if (fmi != _format_map.end()) {
       new_format = (*fmi).second;
-      
+
     } else {
       // 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, 
+        new_array_format =
+          new GeomVertexArrayFormat(InternalName::get_vertex(), 3,
                                     Geom::NT_stdfloat,
                                     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, 
+        new_array_format =
+          new GeomVertexArrayFormat(InternalName::get_vertex(), 4,
                                     Geom::NT_stdfloat,
                                     Geom::C_clip_point);
       }
@@ -342,14 +342,14 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
           (InternalName::get_texcoord(), 2,
            Geom::NT_stdfloat,
            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;
     }
@@ -406,7 +406,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
       LPoint3 eye = modelview.xform_point(vertex.get_data3());
       points[vi]._eye = eye;
       points[vi]._dist = gsg->compute_distance_to(points[vi]._eye);
-    
+
       // The point in clip coordinates.
       LPoint4 p4 = LPoint4(eye[0], eye[1], eye[2], 1.0f) * projection;
 
@@ -431,7 +431,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
           scale_y /= gsg->compute_distance_to(eye);
         }
       }
-      
+
       // Also factor in the homogeneous scale for being in clip
       // coordinates still.
       scale_y *= p4[3];
@@ -445,7 +445,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
       LPoint2 c0(scale_x, scale_y);
       LPoint2 c1(-scale_x, scale_y);
 
-      if (has_rotate) { 
+      if (has_rotate) {
         // If we have a rotate factor, apply it to those two corners.
         PN_stdfloat r = rotate.get_data1f();
         LMatrix3 mat = LMatrix3::rotate_mat(r);
@@ -459,7 +459,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
       PN_stdfloat ry = 1.0f / viewport_height;
       c0.set(c0[0] * rx, c0[1] * ry);
       c1.set(c1[0] * rx, c1[1] * ry);
-    
+
       if (retransform_sprites) {
         // With retransform_sprites in effect, we must reconvert the
         // resulting quad back into the original 3-D space.
@@ -467,7 +467,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
         new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] + c1[0], p4[1] + c1[1], p4[2], p4[3])));
         new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3])));
         new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3])));
-      
+
         if (has_normal) {
           const LNormal &c = normal.get_data3();
           new_normal.set_data3(c);
@@ -475,7 +475,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
           new_normal.set_data3(c);
           new_normal.set_data3(c);
         }
-      
+
       } else {
         // Without retransform_sprites, we can simply load the
         // clip-space coordinates.
@@ -483,7 +483,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
         new_vertex.set_data4(p4[0] + c1[0], p4[1] + c1[1], p4[2], p4[3]);
         new_vertex.set_data4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3]);
         new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]);
-      
+
         if (has_normal) {
           LNormal c = render_transform.xform_vec(normal.get_data3());
           new_normal.set_data3(c);
@@ -519,18 +519,20 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
     nassertr(new_data->get_num_rows() == new_verts, false);
   }
 
-  PT(Geom) new_geom = new Geom(new_data);
-    
-  // Create an appropriate GeomVertexArrayFormat for the primitive
-  // index.
-  static CPT(GeomVertexArrayFormat) new_prim_format;
-  if (new_prim_format == (GeomVertexArrayFormat *)NULL) {
-    new_prim_format =
-      GeomVertexArrayFormat::register_format
-      (new GeomVertexArrayFormat(InternalName::get_index(), 1, 
-                                 GeomEnums::NT_uint16, GeomEnums::C_index));
+  // Determine the format we should use to store the indices.
+  const GeomVertexArrayFormat *new_prim_format = NULL;
+  if (new_verts < 0xff) {
+    new_prim_format = GeomPrimitive::get_index_format(GeomEnums::NT_uint8);
+
+  } else if (new_verts < 0xffff) {
+    new_prim_format = GeomPrimitive::get_index_format(GeomEnums::NT_uint16);
+
+  } else {
+    new_prim_format = GeomPrimitive::get_index_format(GeomEnums::NT_uint32);
   }
 
+  PT(Geom) new_geom = new Geom(new_data);
+
   // Replace each primitive in the Geom (it's presumably a GeomPoints
   // primitive, although it might be some other kind of primitive if
   // we got here because RenderModeAttrib::M_point is enabled) with a
@@ -573,11 +575,11 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
             vertices[i] = v;
           }
         }
-  
+
         // Now sort the points in order from back-to-front so they will
         // render properly with transparency, at least with each other.
         sort(vertices, vertices_end, SortPoints(points));
-  
+
         // Go through the points, now in sorted order, and generate a pair
         // of triangles for each one.  We generate indexed triangles
         // instead of two-triangle strips, since this seems to be
@@ -587,7 +589,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
         PT(GeomPrimitive) new_primitive = new GeomTriangles(Geom::UH_stream);
         int new_prim_verts = 6 * num_vertices;  // two triangles per point.
 
-        PT(GeomVertexArrayData) new_index 
+        PT(GeomVertexArrayData) new_index
           = new GeomVertexArrayData(new_prim_format, GeomEnums::UH_stream);
         new_index->unclean_set_num_rows(new_prim_verts);
 
@@ -667,14 +669,14 @@ munge_texcoord_light_vector(const CullTraverser *traverser, bool force) {
       string source_name = tex_gen->get_source_name(stage);
       Light *light_obj = light.node()->as_light();
       nassertr(light_obj != (Light *)NULL, false);
-      
+
       // Determine the names of the tangent and binormal columns
       // associated with the stage's texcoord name.
       PT(InternalName) tangent_name = InternalName::get_tangent_name(source_name);
       PT(InternalName) binormal_name = InternalName::get_binormal_name(source_name);
-      
+
       PT(InternalName) texcoord_name = stage->get_texcoord_name();
-      
+
       if (_munged_data->has_column(tangent_name) &&
           _munged_data->has_column(binormal_name)) {
 

+ 1 - 1
panda/src/pgraph/transformState.cxx

@@ -2322,7 +2322,7 @@ do_calc_components() {
     _hpr.set(0.0f, 0.0f, 0.0f);
     _quat = LQuaternion::ident_quat();
     _pos.set(0.0f, 0.0f, 0.0f);
-    _flags |= F_has_components | F_components_known | F_hpr_known | F_quat_known | F_uniform_scale;
+    _flags |= F_has_components | F_components_known | F_hpr_known | F_quat_known | F_uniform_scale | F_identity_scale;
 
   } else {
     // If we don't have components and we're not identity, the only