Просмотр исходного кода

more egg features for new geom

David Rose 21 лет назад
Родитель
Сommit
acfa6978db

+ 31 - 2
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -2677,7 +2677,7 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
 draw_triangles(const qpGeomTriangles *primitive) {
-  HRESULT hr = _pD3DDevice->DrawIndexedPrimitiveUP
+  _pD3DDevice->DrawIndexedPrimitiveUP
     (D3DPT_TRIANGLELIST, 
      primitive->get_min_vertex(),
      primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
@@ -2686,8 +2686,37 @@ draw_triangles(const qpGeomTriangles *primitive) {
      D3DFMT_INDEX16,
      _vertex_data->get_array_data(0), 
      _vertex_data->get_format()->get_array(0)->get_stride());
+}
 
-  TestDrawPrimFailure(DrawPrim,hr,_pD3DDevice,nPrims,0);
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian8::draw_tristrips
+//       Access: Public, Virtual
+//  Description: Draws a series of triangle strips.
+////////////////////////////////////////////////////////////////////
+void DXGraphicsStateGuardian8::
+draw_tristrips(const qpGeomTristrips *primitive) {
+  int min_vertex = primitive->get_min_vertex();
+  int max_vertex = primitive->get_max_vertex();
+  CPTA_ushort vertices = primitive->get_flat_first_vertices();
+  CPTA_int ends = primitive->get_ends();
+
+  CPTA_uchar array_data = _vertex_data->get_array_data(0);
+  int stride = _vertex_data->get_format()->get_array(0)->get_stride();
+
+  int num_primitives = primitive->get_num_primitives();
+  int start = 0;
+  for (CPTA_int::const_iterator pi = ends.begin(); pi != ends.end(); ++pi) {
+    int end = (*pi);
+
+    _pD3DDevice->DrawIndexedPrimitiveUP
+      (D3DPT_TRIANGLESTRIP, 
+       min_vertex, max_vertex - min_vertex + 1, 
+       end - start - 2,
+       vertices + start, D3DFMT_INDEX16,
+       array_data, stride);
+
+    start = end;
+  }
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 0
panda/src/dxgsg8/dxGraphicsStateGuardian8.h

@@ -92,6 +92,7 @@ public:
 
   virtual bool begin_draw_primitives(const qpGeomVertexData *vertex_data);
   virtual void draw_triangles(const qpGeomTriangles *primitive);
+  virtual void draw_tristrips(const qpGeomTristrips *primitive);
   virtual void end_draw_primitives();
 
   virtual TextureContext *prepare_texture(Texture *tex);

+ 5 - 0
panda/src/egg/eggCompositePrimitive.cxx

@@ -145,6 +145,11 @@ unify_attributes(EggPrimitive::Shading shading) {
     shading = get_shading();
   }
 
+  // Not having a color is implicitly white.
+  if (!has_color()) {
+    set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
+  }
+
   switch (shading) {
   case S_per_vertex:
     // Propagate everything to the vertices.

+ 4 - 2
panda/src/egg/eggGroupNode.cxx

@@ -771,9 +771,11 @@ mesh_triangles(int flags) {
 //       Access: Published
 //  Description: Removes all vertices from VertexPools within this
 //               group or below that are not referenced by at least
-//               one primitive.  Also renumbers all vertices after the
+//               one primitive.  Also collapses together equivalent
+//               vertices, and renumbers all vertices after the
 //               operation so their indices are consecutive, beginning
-//               at zero.  Returns the total number of vertices removed.
+//               at zero.  Returns the total number of vertices
+//               removed.
 //
 //               Note that this operates on the VertexPools within
 //               this group level, without respect to primitives that

+ 3 - 3
panda/src/egg/eggPrimitive.I

@@ -102,9 +102,9 @@ clear_connected_shading() {
 //               EggGroupNode).
 ////////////////////////////////////////////////////////////////////
 INLINE EggPrimitive::Shading EggPrimitive::
-get_connected_shading() {
+get_connected_shading() const {
   if (_connected_shading == S_unknown) {
-    set_connected_shading(S_unknown, this);
+    ((EggPrimitive *)this)->set_connected_shading(S_unknown, this);
   }
 
   return _connected_shading;
@@ -150,7 +150,7 @@ has_texture() const {
 INLINE bool EggPrimitive::
 has_texture(EggTexture *texture) const {
   PT_EggTexture t = texture;
-  return (find(_textures.begin(), _textures.end(), t) != _textures.end());
+  return (::find(_textures.begin(), _textures.end(), t) != _textures.end());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 35 - 3
panda/src/egg/eggPrimitive.cxx

@@ -352,6 +352,11 @@ unify_attributes(EggPrimitive::Shading shading) {
     shading = get_shading();
   }
 
+  // Not having a color is implicitly white.
+  if (!has_color()) {
+    set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
+  }
+
   switch (shading) {
   case S_per_vertex:
     // Propagate everything to the vertices.
@@ -659,6 +664,19 @@ erase(iterator first, iterator last) {
   return result;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggPrimitive::find
+//       Access: Public
+//  Description: Returns the iterator pointing to the indicated
+//               vertex, or end() if the vertex is not part of the
+//               primitive.
+////////////////////////////////////////////////////////////////////
+EggPrimitive::iterator EggPrimitive::
+find(EggVertex *vertex) {
+  PT_EggVertex vpt = vertex;
+  return ::find(begin(), end(), vpt);
+}
+
 
 ////////////////////////////////////////////////////////////////////
 //     Function: EggPrimitive::add_vertex
@@ -688,7 +706,7 @@ add_vertex(EggVertex *vertex) {
 EggVertex *EggPrimitive::
 remove_vertex(EggVertex *vertex) {
   PT_EggVertex vpt = vertex;
-  iterator i = find(begin(), end(), vpt);
+  iterator i = ::find(begin(), end(), vpt);
   if (i == end()) {
     return PT_EggVertex();
   } else {
@@ -1129,10 +1147,24 @@ set_connected_shading(EggPrimitive::Shading shading,
     // If both neighbors are overall shaded, check if the two
     // neighbors have different properties.  If they do, elevate to
     // per_face.
-    if (!matches_normal(*neighbor) || !matches_color(*neighbor)) {
+    bool matches_normal = this->matches_normal(*neighbor);
+    bool matches_color = this->matches_color(*neighbor);
+
+    if (!matches_color) {
+      // Make a special case for not having an overall color: that's
+      // implicitly white.
+      if (!neighbor->has_color() && has_color() && _drgbas.empty() &&
+          get_color() == Colorf(1.0f, 1.0f, 1.0f, 1.0f)) {
+        matches_color = true;
+      } else if (!has_color() && neighbor->has_color() && neighbor->_drgbas.empty() &&
+          neighbor->get_color() == Colorf(1.0f, 1.0f, 1.0f, 1.0f)) {
+        matches_color = true;
+      }
+    }
+    if (!matches_normal || !matches_color) {
       _connected_shading = S_per_face;
       propagate = true;
-    }
+    }      
   }
 
   if (propagate) {

+ 4 - 1
panda/src/egg/eggPrimitive.h

@@ -89,7 +89,7 @@ PUBLISHED:
 
   virtual Shading get_shading() const;
   INLINE void clear_connected_shading();
-  INLINE Shading get_connected_shading();
+  INLINE Shading get_connected_shading() const;
 
   INLINE void set_texture(EggTexture *texture);
   INLINE bool has_texture() const;
@@ -163,6 +163,7 @@ public:
   INLINE iterator erase(iterator position);
   iterator erase(iterator first, iterator last);
   INLINE void replace(iterator position, EggVertex *vertex);
+  iterator find(EggVertex *vertex);
 
 PUBLISHED:
   INLINE void clear();
@@ -178,6 +179,8 @@ PUBLISHED:
 
   INLINE EggVertexPool *get_pool() const;
 
+  virtual void write(ostream &out, int indent_level) const=0;
+
 #ifndef NDEBUG
   void test_vref_integrity() const;
 #else

+ 35 - 7
panda/src/egg/eggVertexPool.cxx

@@ -475,8 +475,9 @@ remove_vertex(EggVertex *vertex) {
 //     Function: EggVertexPool::remove_unused_vertices
 //       Access: Public
 //  Description: Removes all vertices from the pool that are not
-//               referenced by at least one primitive.  Also renumbers
-//               all vertices after the operation so their indices are
+//               referenced by at least one primitive.  Also collapses
+//               together equivalent vertices, and renumbers all
+//               vertices after the operation so their indices are
 //               consecutive, beginning at zero.  Returns the number
 //               of vertices removed.
 ////////////////////////////////////////////////////////////////////
@@ -497,11 +498,38 @@ remove_unused_vertices() {
       num_removed++;
 
     } else {
-      // The vertex *is* used somewhere.  Renumber it and add it to
-      // the new lists.
-      vertex->_index = new_index_vertices.size();
-      new_index_vertices.insert(IndexVertices::value_type(vertex->_index, vertex));
-      new_unique_vertices.insert(vertex);
+      // The vertex *is* used somewhere.  Is it identical to an
+      // existing vertex?
+      UniqueVertices::iterator uvi;
+      uvi = new_unique_vertices.find(vertex);
+      if (uvi != new_unique_vertices.end()) {
+        // Yes, there's already another vertex just like this one.
+        // Redirect all the primitives currently referencing this
+        // vertex to reference the other one instead.
+        EggVertex *orig_vertex = (*uvi);
+
+        EggVertex::PrimitiveRef pref = vertex->_pref;
+        EggVertex::PrimitiveRef::iterator pi;
+        for (pi = pref.begin(); pi != pref.end(); ++pi) {
+          EggPrimitive *prim = (*pi);
+          EggPrimitive::iterator pvi = prim->find(vertex);
+          nassertr(pvi != prim->end(), 0);
+          prim->replace(pvi, orig_vertex);
+        }
+        vertex->test_pref_integrity();
+        orig_vertex->test_pref_integrity();
+        nassertr(vertex->pref_size() == 0, 0);
+        vertex->clear_grefs();
+        vertex->_pool = NULL;
+        num_removed++;
+
+      } else {
+        // It's a unique vertex.  Renumber it and add it to the new
+        // lists.
+        vertex->_index = new_index_vertices.size();
+        new_index_vertices.insert(IndexVertices::value_type(vertex->_index, vertex));
+        new_unique_vertices.insert(vertex);
+      }
     }
   }
 

+ 7 - 6
panda/src/egg2pg/eggLoader.cxx

@@ -160,6 +160,7 @@ build_graph() {
   // Clean up the vertices.
   _data->clear_connected_shading();
   _data->remove_unused_vertices(true);
+  _data->get_connected_shading();
   _data->unify_attributes(true, true);
 
   // Then bin up the polysets and LOD nodes.
@@ -1462,7 +1463,7 @@ make_polyset(EggBin *egg_bin, PandaNode *parent) {
 
   // Now that we've meshed, apply the per-prim attributes onto the
   // vertices, so we can copy them to the GeomVertexData.
-  egg_bin->apply_first_attribute(false);
+  egg_bin->apply_last_attribute(false);
   egg_bin->post_apply_flat_attribute(false);
   vertex_pool->remove_unused_vertices();
 
@@ -1482,7 +1483,7 @@ make_polyset(EggBin *egg_bin, PandaNode *parent) {
     // Now convert the vertex pool to a GeomVertexData.
     nassertr(vertex_pool != (EggVertexPool *)NULL, NULL);
     PT(qpGeomVertexData) vertex_data = 
-      make_vertex_data(vertex_pool, first_prim->get_vertex_to_node());
+      make_vertex_data(vertex_pool, egg_bin->get_vertex_to_node());
     nassertr(vertex_data != (qpGeomVertexData *)NULL, NULL);
 
     // And create a Geom to hold the primitives.
@@ -1934,11 +1935,11 @@ make_vertex_data(EggVertexPool *vertex_pool, const LMatrix4d &transform) {
     gvi.set_vertex(vertex->get_index());
 
     gvi.set_data_type(InternalName::get_vertex());
-    gvi.set_data4(LCAST(float, vertex->get_pos4()));
+    gvi.set_data4(LCAST(float, vertex->get_pos4() * transform));
 
     if (vertex->has_normal()) {
       gvi.set_data_type(InternalName::get_normal());
-      gvi.set_data3(LCAST(float, vertex->get_normal()));
+      gvi.set_data3(LCAST(float, vertex->get_normal() * transform));
     }
 
     if (vertex->has_color()) {
@@ -1986,12 +1987,12 @@ make_primitive(const EggRenderState *render_state, EggPrimitive *egg_prim,
   if (primitive == (qpGeomPrimitive *)NULL) {
     // Don't know how to make this kind of primitive.
     egg2pg_cat.warning()
-      << "Ignoring " << egg_prim->get_class_type() << "\n";
+      << "Ignoring " << egg_prim->get_type() << "\n";
     return;
   }
 
   if (render_state->_flat_shaded) {
-    primitive->set_shade_model(qpGeomPrimitive::SM_flat_first_vertex);
+    primitive->set_shade_model(qpGeomPrimitive::SM_flat_last_vertex);
 
   } else if (egg_prim->get_shading() == EggPrimitive::S_overall) {
     primitive->set_shade_model(qpGeomPrimitive::SM_uniform);

+ 15 - 0
panda/src/glstuff/glGeomMunger_src.cxx

@@ -48,5 +48,20 @@ munge_format_impl(const qpGeomVertexFormat *orig) {
     format = qpGeomVertexFormat::register_format(new_format);
   }
 
+  /*
+  if (true) {
+    // Split out the interleaved array into n parallel arrays.
+    PT(qpGeomVertexFormat) new_format = new qpGeomVertexFormat;
+    for (int i = 0; i < format->get_num_data_types(); i++) {
+      const qpGeomVertexDataType *data_type = format->get_data_type(i);
+      PT(qpGeomVertexArrayFormat) new_array_format = new qpGeomVertexArrayFormat;
+      new_array_format->add_data_type(data_type->get_name(), data_type->get_num_components(),
+                                      data_type->get_numeric_type());
+      new_format->add_array(new_array_format);
+    }
+    format = qpGeomVertexFormat::register_format(new_format);
+  }
+  */
+
   return format;
 }

+ 28 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -2070,6 +2070,34 @@ draw_triangles(const qpGeomTriangles *primitive) {
   report_my_gl_errors();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CLP(GraphicsStateGuardian)::draw_tristrips
+//       Access: Public, Virtual
+//  Description: Draws a series of triangle strips.
+////////////////////////////////////////////////////////////////////
+void CLP(GraphicsStateGuardian)::
+draw_tristrips(const qpGeomTristrips *primitive) {
+  setup_antialias_polygon();
+
+  int min_vertex = primitive->get_min_vertex();
+  int max_vertex = primitive->get_max_vertex();
+  CPTA_ushort vertices = primitive->get_flat_last_vertices();
+  CPTA_int ends = primitive->get_ends();
+
+  int num_primitives = primitive->get_num_primitives();
+  int start = 0;
+  for (CPTA_int::const_iterator pi = ends.begin(); pi != ends.end(); ++pi) {
+    int end = (*pi);
+
+    _glDrawRangeElements(GL_TRIANGLE_STRIP, 
+                         min_vertex, max_vertex, end - start,
+                         GL_UNSIGNED_SHORT, vertices + start);
+    start = end;
+  }
+
+  report_my_gl_errors();
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CLP(GraphicsStateGuardian)::end_draw_primitives()
 //       Access: Public, Virtual

+ 1 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -91,6 +91,7 @@ public:
 
   virtual bool begin_draw_primitives(const qpGeomVertexData *vertex_data);
   virtual void draw_triangles(const qpGeomTriangles *primitive);
+  virtual void draw_tristrips(const qpGeomTristrips *primitive);
   virtual void end_draw_primitives();
 
   INLINE bool draw_display_list(GeomContext *gc);

+ 2 - 3
panda/src/gobj/qpgeom.cxx

@@ -217,8 +217,7 @@ get_num_bytes() const {
 void qpGeom::
 munge_geom(const qpGeomMunger *munger,
            CPT(qpGeom) &result, CPT(qpGeomVertexData) &data) const {
-  // Look up the format in our cache--maybe we've recently applied the
-  // indicated munger.
+  // Look up the munger in our cache--maybe we've recently applied it.
   {
     // Use read() and release_read() instead of CDReader, because the
     // call to record_geom() might recursively call back into this
@@ -249,7 +248,7 @@ munge_geom(const qpGeomMunger *munger,
   data = munger->munge_data(get_vertex_data());
   ((qpGeomMunger *)munger)->munge_geom_impl(result, data);
 
-  if (result.p() != this) {
+  {
     // Record the new result in the cache.
     {
       CDWriter cdata(((qpGeom *)this)->_cycler);

+ 0 - 1
panda/src/gobj/qpgeomMunger.cxx

@@ -148,7 +148,6 @@ do_munge_format(const qpGeomVertexFormat *format) {
 CPT(qpGeomVertexData) qpGeomMunger::
 do_munge_data(const qpGeomVertexData *data) {
   nassertr(_is_registered, NULL);
-  PStatTimer timer(_munge_pcollector);
 
   CPT(qpGeomVertexFormat) orig_format = data->get_format();
   CPT(qpGeomVertexFormat) new_format = munge_format(orig_format);

+ 4 - 0
panda/src/gobj/qpgeomVertexData.cxx

@@ -24,6 +24,9 @@
 
 TypeHandle qpGeomVertexData::_type_handle;
 
+// Temporarily not a member of the class.
+static PStatCollector _munge_pcollector("Cull:Munge:Data");
+
 ////////////////////////////////////////////////////////////////////
 //     Function: qpGeomVertexData::Default Constructor
 //       Access: Private
@@ -301,6 +304,7 @@ convert_to(const qpGeomVertexFormat *new_format) const {
     gobj_cat.debug()
       << "Converting " << num_vertices << " vertices.\n";
   }
+  PStatTimer timer(_munge_pcollector);
 
   PT(qpGeomVertexData) new_data = new qpGeomVertexData(new_format);