From 18169d527e6e7739985de8b4e915d9ca92aedec9 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 23 Mar 2005 03:31:18 +0000 Subject: [PATCH] lines and points, antialiasing in qpgeom --- panda/src/display/graphicsStateGuardian.cxx | 32 +++ panda/src/display/graphicsStateGuardian.h | 3 + panda/src/doc/eggSyntax.txt | 7 +- panda/src/egg/eggCompositePrimitive.I | 11 - panda/src/egg/eggCompositePrimitive.cxx | 101 ++++++++- panda/src/egg/eggCompositePrimitive.h | 7 +- panda/src/egg/eggGroupNode.cxx | 30 ++- panda/src/egg/eggLine.I | 61 +++++- panda/src/egg/eggLine.cxx | 32 ++- panda/src/egg/eggLine.h | 22 +- panda/src/egg/eggPoint.I | 59 +++++- panda/src/egg/eggPoint.cxx | 8 +- panda/src/egg/eggPoint.h | 9 + panda/src/egg/eggPrimitive.cxx | 6 +- panda/src/egg/eggTriangleStrip.cxx | 59 ++---- panda/src/egg/eggTriangleStrip.h | 5 +- panda/src/egg/parser.cxx.prebuilt | 180 ++++++++-------- panda/src/egg/parser.yxx | 8 + panda/src/egg2pg/eggLoader.cxx | 14 ++ panda/src/egg2pg/eggRenderState.I | 4 + panda/src/egg2pg/eggRenderState.cxx | 21 ++ panda/src/egg2pg/eggRenderState.h | 2 + .../glstuff/glGraphicsStateGuardian_src.cxx | 58 +++++- .../src/glstuff/glGraphicsStateGuardian_src.h | 2 + panda/src/gobj/Sources.pp | 9 + panda/src/gobj/config_gobj.cxx | 9 + panda/src/gobj/gobj_composite1.cxx | 3 + panda/src/gobj/qpgeom.I | 22 ++ panda/src/gobj/qpgeom.cxx | 10 + panda/src/gobj/qpgeom.h | 2 + panda/src/gobj/qpgeomLines.cxx | 160 ++++++++++++++ panda/src/gobj/qpgeomLines.h | 74 +++++++ panda/src/gobj/qpgeomLinestrips.cxx | 196 ++++++++++++++++++ panda/src/gobj/qpgeomLinestrips.h | 73 +++++++ panda/src/gobj/qpgeomPoints.cxx | 137 ++++++++++++ panda/src/gobj/qpgeomPoints.h | 71 +++++++ panda/src/gobj/qpgeomPrimitive.h | 8 + panda/src/gobj/qpgeomTriangles.cxx | 14 ++ panda/src/gobj/qpgeomTriangles.h | 1 + panda/src/gobj/qpgeomTrifans.cxx | 14 ++ panda/src/gobj/qpgeomTrifans.h | 1 + panda/src/gobj/qpgeomTristrips.cxx | 16 +- panda/src/gobj/qpgeomTristrips.h | 1 + panda/src/gsgbase/graphicsStateGuardianBase.h | 6 + 44 files changed, 1399 insertions(+), 169 deletions(-) create mode 100644 panda/src/gobj/qpgeomLines.cxx create mode 100644 panda/src/gobj/qpgeomLines.h create mode 100644 panda/src/gobj/qpgeomLinestrips.cxx create mode 100644 panda/src/gobj/qpgeomLinestrips.h create mode 100644 panda/src/gobj/qpgeomPoints.cxx create mode 100644 panda/src/gobj/qpgeomPoints.h diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 77d7e319db..411888e180 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -41,6 +41,7 @@ #include "pStatTimer.h" #include "qpgeomTristrips.h" #include "qpgeomTrifans.h" +#include "qpgeomLinestrips.h" #include @@ -712,6 +713,37 @@ draw_trifans(const qpGeomTrifans *primitive) { } } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::draw_lines +// Access: Public, Virtual +// Description: Draws a series of disconnected line segments. +//////////////////////////////////////////////////////////////////// +void GraphicsStateGuardian:: +draw_lines(const qpGeomLines *) { +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::draw_linestrips +// Access: Public, Virtual +// Description: Draws a series of line strips. +//////////////////////////////////////////////////////////////////// +void GraphicsStateGuardian:: +draw_linestrips(const qpGeomLinestrips *primitive) { + CPT(qpGeomPrimitive) new_prim = primitive->decompose(); + if (!new_prim->is_of_type(qpGeomLinestrips::get_class_type())) { + new_prim->draw(this); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::draw_points +// Access: Public, Virtual +// Description: Draws a series of disconnected points. +//////////////////////////////////////////////////////////////////// +void GraphicsStateGuardian:: +draw_points(const qpGeomPoints *) { +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::end_draw_primitives() // Access: Public, Virtual diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 0fecb2c43c..2205ffcabe 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -154,6 +154,9 @@ public: virtual void draw_triangles(const qpGeomTriangles *primitive); virtual void draw_tristrips(const qpGeomTristrips *primitive); virtual void draw_trifans(const qpGeomTrifans *primitive); + virtual void draw_lines(const qpGeomLines *primitive); + virtual void draw_linestrips(const qpGeomLinestrips *primitive); + virtual void draw_points(const qpGeomPoints *primitive); virtual void end_draw_primitives(); virtual bool framebuffer_bind_to_texture(GraphicsOutput *win, Texture *tex); diff --git a/panda/src/doc/eggSyntax.txt b/panda/src/doc/eggSyntax.txt index ae9af36f6b..8ae64d0636 100644 --- a/panda/src/doc/eggSyntax.txt +++ b/panda/src/doc/eggSyntax.txt @@ -707,6 +707,7 @@ GEOMETRY ENTRIES indices { pool-name } } + [component attributes] } A Line is a connected set of line segments. The listed N vertices @@ -714,7 +715,11 @@ GEOMETRY ENTRIES vertex 1, vertex 1 and vertex 2, etc. The line is not implicitly closed; if you wish to represent a loop, you must repeat vertex 0 at the end. As with a PointLight, normals, textures, colors, - draw_order, and the "thick" attribute are all valid. + draw_order, and the "thick" attribute are all valid. Also, since a + Line (with more than two vertices) is made up of multiple line + segments, it may contain a number of entries, to set a + different color and/or normal for each line segment, as in + TriangleStrip, below. name { diff --git a/panda/src/egg/eggCompositePrimitive.I b/panda/src/egg/eggCompositePrimitive.I index f0163485f6..3038ebb97d 100644 --- a/panda/src/egg/eggCompositePrimitive.I +++ b/panda/src/egg/eggCompositePrimitive.I @@ -35,17 +35,6 @@ INLINE EggCompositePrimitive:: EggCompositePrimitive(const EggCompositePrimitive ©) : EggPrimitive(copy) { } -//////////////////////////////////////////////////////////////////// -// Function: EggCompositePrimitive::Destructor -// Access: Published -// Description: -//////////////////////////////////////////////////////////////////// -INLINE EggCompositePrimitive:: -~EggCompositePrimitive() { - clear(); - nassertv(_components.empty()); -} - //////////////////////////////////////////////////////////////////// // Function: EggCompositePrimitive::Copy assignment operator // Access: Published diff --git a/panda/src/egg/eggCompositePrimitive.cxx b/panda/src/egg/eggCompositePrimitive.cxx index 874360623a..57c2f9f1b3 100644 --- a/panda/src/egg/eggCompositePrimitive.cxx +++ b/panda/src/egg/eggCompositePrimitive.cxx @@ -22,6 +22,18 @@ TypeHandle EggCompositePrimitive::_type_handle; +//////////////////////////////////////////////////////////////////// +// Function: EggCompositePrimitive::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +EggCompositePrimitive:: +~EggCompositePrimitive() { + // Every derived class of EggCompositePrimitive must call clear() in + // its destructor. + nassertv(_components.empty()); +} + //////////////////////////////////////////////////////////////////// // Function: EggCompositePrimitive::get_shading // Access: Published, Virtual @@ -146,7 +158,7 @@ unify_attributes(EggPrimitive::Shading shading) { } // Not having a color is implicitly white. - if (!has_color()) { + if (!has_color() && shading != S_overall) { set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); } @@ -253,6 +265,57 @@ unify_attributes(EggPrimitive::Shading shading) { case S_unknown: break; } + + if (!has_color() && shading == S_overall) { + set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggCompositePrimitive::apply_last_attribute +// Access: Published, Virtual +// Description: Sets the last vertex of the triangle (or each +// component) to the primitive normal and/or color, if +// the primitive is flat-shaded. This reflects the +// OpenGL convention of storing flat-shaded properties on +// the last vertex, although it is not usually a +// convention in Egg. +// +// This may introduce redundant vertices to the vertex +// pool. +//////////////////////////////////////////////////////////////////// +void EggCompositePrimitive:: +apply_last_attribute() { + // The first component gets applied to the third vertex, and so on + // from there. + int num_lead_vertices = get_num_lead_vertices(); + for (int i = 0; i < get_num_components(); i++) { + EggAttributes *component = get_component(i); + do_apply_flat_attribute(i + num_lead_vertices, component); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggCompositePrimitive::apply_first_attribute +// Access: Published, Virtual +// Description: Sets the first vertex of the triangle (or each +// component) to the primitive normal and/or color, if +// the primitive is flat-shaded. This reflects the +// DirectX convention of storing flat-shaded properties +// on the first vertex, although it is not usually a +// convention in Egg. +// +// This may introduce redundant vertices to the vertex +// pool. +//////////////////////////////////////////////////////////////////// +void EggCompositePrimitive:: +apply_first_attribute() { + // The first component gets applied to the first vertex, and so on + // from there. + for (int i = 0; i < get_num_components(); i++) { + EggAttributes *component = get_component(i); + do_apply_flat_attribute(i, component); + } } //////////////////////////////////////////////////////////////////// @@ -266,9 +329,10 @@ unify_attributes(EggPrimitive::Shading shading) { void EggCompositePrimitive:: post_apply_flat_attribute() { if (!empty()) { + int num_lead_vertices = get_num_lead_vertices(); for (int i = 0; i < (int)size(); i++) { EggVertex *vertex = get_vertex(i); - EggAttributes *component = get_component(max(i - 2, 0)); + EggAttributes *component = get_component(max(i - num_lead_vertices, 0)); // Use set_normal() instead of copy_normal(), to avoid getting // the morphs--we don't want them here, since we're just putting @@ -300,7 +364,7 @@ post_apply_flat_attribute() { //////////////////////////////////////////////////////////////////// bool EggCompositePrimitive:: cleanup() { - return size() >= 3; + return (int)size() >= get_num_lead_vertices() + 1; } //////////////////////////////////////////////////////////////////// @@ -319,8 +383,9 @@ void EggCompositePrimitive:: prepare_add_vertex(EggVertex *vertex, int i, int n) { EggPrimitive::prepare_add_vertex(vertex, i, n); - if (n >= 3) { - i = max(i - 2, 0); + int num_lead_vertices = get_num_lead_vertices(); + if (n >= num_lead_vertices + 1) { + i = max(i - num_lead_vertices, 0); nassertv(i <= (int)_components.size()); _components.insert(_components.begin() + i, new EggAttributes(*this)); } @@ -346,14 +411,36 @@ void EggCompositePrimitive:: prepare_remove_vertex(EggVertex *vertex, int i, int n) { EggPrimitive::prepare_remove_vertex(vertex, i, n); - if (n >= 3) { - i = max(i - 2, 0); + int num_lead_vertices = get_num_lead_vertices(); + if (n >= num_lead_vertices + 1) { + i = max(i - num_lead_vertices, 0); nassertv(i < (int)_components.size()); delete _components[i]; _components.erase(_components.begin() + i); } } +//////////////////////////////////////////////////////////////////// +// Function: EggCompositePrimitive::triangulate_poly +// Access: Protected, Virtual +// Description: Fills the container up with EggPolygons that +// represent the component triangles of this triangle +// strip. +// +// It is assumed that the EggCompositePrimitive is not +// already a child of any other group when this function +// is called. +// +// Returns true if the triangulation is successful, or +// false if there was some error (in which case the +// container may contain some partial triangulation). +//////////////////////////////////////////////////////////////////// +bool EggCompositePrimitive:: +do_triangulate(EggGroupNode *container) const { + container->add_child((EggCompositePrimitive *)this); + return true; +} + //////////////////////////////////////////////////////////////////// // Function: EggCompositePrimitive::write_body // Access: Protected diff --git a/panda/src/egg/eggCompositePrimitive.h b/panda/src/egg/eggCompositePrimitive.h index 254370318d..53c2f0b555 100644 --- a/panda/src/egg/eggCompositePrimitive.h +++ b/panda/src/egg/eggCompositePrimitive.h @@ -35,7 +35,7 @@ PUBLISHED: INLINE EggCompositePrimitive(const string &name = ""); INLINE EggCompositePrimitive(const EggCompositePrimitive ©); INLINE EggCompositePrimitive &operator = (const EggCompositePrimitive ©); - INLINE ~EggCompositePrimitive(); + virtual ~EggCompositePrimitive(); virtual Shading get_shading() const; @@ -48,14 +48,17 @@ PUBLISHED: PT(EggCompositePrimitive) triangulate_in_place(); virtual void unify_attributes(Shading shading); + virtual void apply_last_attribute(); + virtual void apply_first_attribute(); virtual void post_apply_flat_attribute(); virtual bool cleanup(); protected: + virtual int get_num_lead_vertices() const=0; virtual void prepare_add_vertex(EggVertex *vertex, int i, int n); virtual void prepare_remove_vertex(EggVertex *vertex, int i, int n); - virtual bool do_triangulate(EggGroupNode *container) const=0; + virtual bool do_triangulate(EggGroupNode *container) const; void write_body(ostream &out, int indent_level) const; diff --git a/panda/src/egg/eggGroupNode.cxx b/panda/src/egg/eggGroupNode.cxx index d77b3a1ec5..547ea65543 100644 --- a/panda/src/egg/eggGroupNode.cxx +++ b/panda/src/egg/eggGroupNode.cxx @@ -922,7 +922,35 @@ rebuild_vertex_pool(EggVertexPool *vertex_pool, bool recurse) { for (ci = _children.begin(); ci != _children.end(); ++ci) { EggNode *child = *ci; - if (child->is_of_type(EggPrimitive::get_class_type())) { + if (child->is_of_type(EggCompositePrimitive::get_class_type())) { + typedef pvector< PT(EggVertex) > Vertices; + typedef pvector Attributes; + Vertices vertices; + Attributes attributes; + + EggCompositePrimitive *prim = DCAST(EggCompositePrimitive, child); + EggPrimitive::const_iterator pi; + for (pi = prim->begin(); pi != prim->end(); ++pi) { + vertices.push_back(*pi); + } + int i; + int num_components = prim->get_num_components(); + for (i = 0; i < num_components; i++) { + attributes.push_back(*prim->get_component(i)); + } + + prim->clear(); + + Vertices::const_iterator vi; + for (vi = vertices.begin(); vi != vertices.end(); ++vi) { + EggVertex *vertex = (*vi); + prim->add_vertex(vertex_pool->create_unique_vertex(*vertex)); + } + for (i = 0; i < num_components; i++) { + prim->set_component(i, &attributes[i]); + } + + } else if (child->is_of_type(EggPrimitive::get_class_type())) { typedef pvector< PT(EggVertex) > Vertices; Vertices vertices; diff --git a/panda/src/egg/eggLine.I b/panda/src/egg/eggLine.I index 414e1d2fd3..95807039e5 100644 --- a/panda/src/egg/eggLine.I +++ b/panda/src/egg/eggLine.I @@ -23,7 +23,10 @@ // Description: //////////////////////////////////////////////////////////////////// INLINE EggLine:: -EggLine(const string &name) : EggPrimitive(name) { +EggLine(const string &name) : + EggCompositePrimitive(name), + _has_thick(false) +{ } //////////////////////////////////////////////////////////////////// @@ -32,7 +35,11 @@ EggLine(const string &name) : EggPrimitive(name) { // Description: //////////////////////////////////////////////////////////////////// INLINE EggLine:: -EggLine(const EggLine ©) : EggPrimitive(copy) { +EggLine(const EggLine ©) : + EggCompositePrimitive(copy), + _thick(copy._thick), + _has_thick(copy._has_thick) +{ } //////////////////////////////////////////////////////////////////// @@ -42,6 +49,54 @@ EggLine(const EggLine ©) : EggPrimitive(copy) { //////////////////////////////////////////////////////////////////// INLINE EggLine &EggLine:: operator = (const EggLine ©) { - EggPrimitive::operator = (copy); + EggCompositePrimitive::operator = (copy); + _thick = copy._thick; + _has_thick = copy._has_thick; return *this; } + +//////////////////////////////////////////////////////////////////// +// Function: EggLine::has_thick +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool EggLine:: +has_thick() const { + return _has_thick; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggLine::get_thick +// Access: Published +// Description: Returns the thick set on this particular attribute. +// If there is no thick set, returns white. +//////////////////////////////////////////////////////////////////// +INLINE double EggLine:: +get_thick() const { + if (has_thick()) { + return _thick; + } else { + return 1.0; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggLine:: +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggLine:: +set_thick(double thick) { + _thick = thick; + _has_thick = true; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggLine:: +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggLine:: +clear_thick() { + _has_thick = false; +} diff --git a/panda/src/egg/eggLine.cxx b/panda/src/egg/eggLine.cxx index 0517f292b6..b6889afb6a 100644 --- a/panda/src/egg/eggLine.cxx +++ b/panda/src/egg/eggLine.cxx @@ -22,6 +22,17 @@ TypeHandle EggLine::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: EggLine::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +EggLine:: +~EggLine() { + clear(); +} + //////////////////////////////////////////////////////////////////// // Function: EggLine::write // Access: Public, Virtual @@ -31,6 +42,25 @@ TypeHandle EggLine::_type_handle; void EggLine:: write(ostream &out, int indent_level) const { write_header(out, indent_level, ""); - write_body(out, indent_level+2); + + if (has_thick()) { + indent(out, indent_level + 2) + << " thick { " << get_thick() << " }\n"; + } + + write_body(out, indent_level + 2); indent(out, indent_level) << "}\n"; } + +//////////////////////////////////////////////////////////////////// +// Function: EggLine::get_num_lead_vertices +// Access: Protected, Virtual +// Description: Returns the number of initial vertices that are not +// used in defining any component; the first component +// is defined by the (n + 1)th vertex, and then a new +// component at each vertex thereafter. +//////////////////////////////////////////////////////////////////// +int EggLine:: +get_num_lead_vertices() const { + return 1; +} diff --git a/panda/src/egg/eggLine.h b/panda/src/egg/eggLine.h index 4977ea2518..0e29533291 100644 --- a/panda/src/egg/eggLine.h +++ b/panda/src/egg/eggLine.h @@ -21,30 +21,42 @@ #include "pandabase.h" -#include "eggPrimitive.h" +#include "eggCompositePrimitive.h" //////////////////////////////////////////////////////////////////// // Class : EggLine // Description : A line segment, or a series of connected line // segments, defined by a entry. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDAEGG EggLine : public EggPrimitive { +class EXPCL_PANDAEGG EggLine : public EggCompositePrimitive { PUBLISHED: INLINE EggLine(const string &name = ""); INLINE EggLine(const EggLine ©); INLINE EggLine &operator = (const EggLine ©); + virtual ~EggLine(); virtual void write(ostream &out, int indent_level) const; -public: + INLINE bool has_thick() const; + INLINE double get_thick() const; + INLINE void set_thick(const double thick); + INLINE void clear_thick(); +protected: + virtual int get_num_lead_vertices() const; + +private: + double _thick; + bool _has_thick; + +public: static TypeHandle get_class_type() { return _type_handle; } static void init_type() { - EggPrimitive::init_type(); + EggCompositePrimitive::init_type(); register_type(_type_handle, "EggLine", - EggPrimitive::get_class_type()); + EggCompositePrimitive::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); diff --git a/panda/src/egg/eggPoint.I b/panda/src/egg/eggPoint.I index e07c9495cb..c835845c12 100644 --- a/panda/src/egg/eggPoint.I +++ b/panda/src/egg/eggPoint.I @@ -23,7 +23,10 @@ // Description: //////////////////////////////////////////////////////////////////// INLINE EggPoint:: -EggPoint(const string &name) : EggPrimitive(name) { +EggPoint(const string &name) : + EggPrimitive(name), + _has_thick(false) +{ } //////////////////////////////////////////////////////////////////// @@ -32,7 +35,11 @@ EggPoint(const string &name) : EggPrimitive(name) { // Description: //////////////////////////////////////////////////////////////////// INLINE EggPoint:: -EggPoint(const EggPoint ©) : EggPrimitive(copy) { +EggPoint(const EggPoint ©) : + EggPrimitive(copy), + _thick(copy._thick), + _has_thick(copy._has_thick) +{ } //////////////////////////////////////////////////////////////////// @@ -43,5 +50,53 @@ EggPoint(const EggPoint ©) : EggPrimitive(copy) { INLINE EggPoint &EggPoint:: operator = (const EggPoint ©) { EggPrimitive::operator = (copy); + _thick = copy._thick; + _has_thick = copy._has_thick; return *this; } + +//////////////////////////////////////////////////////////////////// +// Function: EggPoint::has_thick +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool EggPoint:: +has_thick() const { + return _has_thick; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggPoint::get_thick +// Access: Published +// Description: Returns the thick set on this particular attribute. +// If there is no thick set, returns white. +//////////////////////////////////////////////////////////////////// +INLINE double EggPoint:: +get_thick() const { + if (has_thick()) { + return _thick; + } else { + return 1.0; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggPoint:: +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggPoint:: +set_thick(double thick) { + _thick = thick; + _has_thick = true; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggPoint:: +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggPoint:: +clear_thick() { + _has_thick = false; +} diff --git a/panda/src/egg/eggPoint.cxx b/panda/src/egg/eggPoint.cxx index c026626033..2bc36e0bc7 100644 --- a/panda/src/egg/eggPoint.cxx +++ b/panda/src/egg/eggPoint.cxx @@ -47,6 +47,12 @@ cleanup() { void EggPoint:: write(ostream &out, int indent_level) const { write_header(out, indent_level, ""); - write_body(out, indent_level+2); + + if (has_thick()) { + indent(out, indent_level + 2) + << " thick { " << get_thick() << " }\n"; + } + + write_body(out, indent_level + 2); indent(out, indent_level) << "}\n"; } diff --git a/panda/src/egg/eggPoint.h b/panda/src/egg/eggPoint.h index 9afe6db227..16f0d46746 100644 --- a/panda/src/egg/eggPoint.h +++ b/panda/src/egg/eggPoint.h @@ -34,10 +34,19 @@ PUBLISHED: INLINE EggPoint(const EggPoint ©); INLINE EggPoint &operator = (const EggPoint ©); + INLINE bool has_thick() const; + INLINE double get_thick() const; + INLINE void set_thick(const double thick); + INLINE void clear_thick(); + virtual bool cleanup(); virtual void write(ostream &out, int indent_level) const; +private: + double _thick; + bool _has_thick; + public: static TypeHandle get_class_type() { diff --git a/panda/src/egg/eggPrimitive.cxx b/panda/src/egg/eggPrimitive.cxx index 7b985c421f..2fc4bc93f9 100644 --- a/panda/src/egg/eggPrimitive.cxx +++ b/panda/src/egg/eggPrimitive.cxx @@ -353,7 +353,7 @@ unify_attributes(EggPrimitive::Shading shading) { } // Not having a color is implicitly white. - if (!has_color()) { + if (!has_color() && shading != S_overall) { set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); } @@ -408,6 +408,10 @@ unify_attributes(EggPrimitive::Shading shading) { case S_unknown: break; } + + if (!has_color() && shading == S_overall) { + set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/egg/eggTriangleStrip.cxx b/panda/src/egg/eggTriangleStrip.cxx index 6aae88b449..7fa1a4a800 100644 --- a/panda/src/egg/eggTriangleStrip.cxx +++ b/panda/src/egg/eggTriangleStrip.cxx @@ -29,49 +29,13 @@ TypeHandle EggTriangleStrip::_type_handle; //////////////////////////////////////////////////////////////////// -// Function: EggTriangleStrip::apply_last_attribute +// Function: EggTriangleStrip::Destructor // Access: Published, Virtual -// Description: Sets the last vertex of the triangle (or each -// component) to the primitive normal and/or color, if -// the primitive is flat-shaded. This reflects the -// OpenGL convention of storing flat-shaded properties on -// the last vertex, although it is not usually a -// convention in Egg. -// -// This may introduce redundant vertices to the vertex -// pool. +// Description: //////////////////////////////////////////////////////////////////// -void EggTriangleStrip:: -apply_last_attribute() { - // The first component gets applied to the third vertex, and so on - // from there. - for (int i = 0; i < get_num_components(); i++) { - EggAttributes *component = get_component(i); - do_apply_flat_attribute(i + 2, component); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: EggTriangleStrip::apply_first_attribute -// Access: Published, Virtual -// Description: Sets the first vertex of the triangle (or each -// component) to the primitive normal and/or color, if -// the primitive is flat-shaded. This reflects the -// DirectX convention of storing flat-shaded properties -// on the first vertex, although it is not usually a -// convention in Egg. -// -// This may introduce redundant vertices to the vertex -// pool. -//////////////////////////////////////////////////////////////////// -void EggTriangleStrip:: -apply_first_attribute() { - // The first component gets applied to the first vertex, and so on - // from there. - for (int i = 0; i < get_num_components(); i++) { - EggAttributes *component = get_component(i); - do_apply_flat_attribute(i, component); - } +EggTriangleStrip:: +~EggTriangleStrip() { + clear(); } //////////////////////////////////////////////////////////////////// @@ -87,6 +51,19 @@ write(ostream &out, int indent_level) const { indent(out, indent_level) << "}\n"; } +//////////////////////////////////////////////////////////////////// +// Function: EggTriangleStrip::get_num_lead_vertices +// Access: Protected, Virtual +// Description: Returns the number of initial vertices that are not +// used in defining any component; the first component +// is defined by the (n + 1)th vertex, and then a new +// component at each vertex thereafter. +//////////////////////////////////////////////////////////////////// +int EggTriangleStrip:: +get_num_lead_vertices() const { + return 2; +} + //////////////////////////////////////////////////////////////////// // Function: EggTriangleStrip::triangulate_poly // Access: Protected, Virtual diff --git a/panda/src/egg/eggTriangleStrip.h b/panda/src/egg/eggTriangleStrip.h index ca44f7fb40..9d57b320ec 100644 --- a/panda/src/egg/eggTriangleStrip.h +++ b/panda/src/egg/eggTriangleStrip.h @@ -34,13 +34,12 @@ PUBLISHED: INLINE EggTriangleStrip(const string &name = ""); INLINE EggTriangleStrip(const EggTriangleStrip ©); INLINE EggTriangleStrip &operator = (const EggTriangleStrip ©); - - virtual void apply_last_attribute(); - virtual void apply_first_attribute(); + virtual ~EggTriangleStrip(); virtual void write(ostream &out, int indent_level) const; protected: + virtual int get_num_lead_vertices() const; virtual bool do_triangulate(EggGroupNode *container) const; public: diff --git a/panda/src/egg/parser.cxx.prebuilt b/panda/src/egg/parser.cxx.prebuilt index a6ceb1dbfd..17be1ac39e 100644 --- a/panda/src/egg/parser.cxx.prebuilt +++ b/panda/src/egg/parser.cxx.prebuilt @@ -451,17 +451,17 @@ static const short yyrline[] = 1468, 1471, 1473, 1491, 1524, 1529, 1553, 1565, 1571, 1587, 1587, 1606, 1606, 1625, 1625, 1644, 1644, 1663, 1663, 1682, 1682, 1702, 1704, 1705, 1715, 1717, 1717, 1738, 1739, 1740, - 1741, 1742, 1743, 1744, 1745, 1803, 1805, 1806, 1807, 1808, - 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1821, 1822, 1885, - 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, - 1964, 1981, 2021, 2038, 2043, 2051, 2068, 2073, 2081, 2098, - 2114, 2145, 2163, 2183, 2203, 2209, 2219, 2226, 2244, 2260, - 2281, 2281, 2303, 2303, 2325, 2327, 2331, 2335, 2339, 2343, - 2357, 2357, 2378, 2380, 2392, 2405, 2405, 2426, 2428, 2445, - 2458, 2458, 2479, 2481, 2496, 2510, 2515, 2528, 2533, 2546, - 2567, 2588, 2612, 2618, 2629, 2641, 2647, 2657, 2662, 2675, - 2680, 2684, 2696, 2701, 2716, 2721, 2734, 2736, 2750, 2757, - 2763, 2779, 2788, 2794 + 1741, 1742, 1743, 1744, 1745, 1811, 1813, 1814, 1815, 1816, + 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1829, 1830, 1893, + 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, + 1972, 1989, 2029, 2046, 2051, 2059, 2076, 2081, 2089, 2106, + 2122, 2153, 2171, 2191, 2211, 2217, 2227, 2234, 2252, 2268, + 2289, 2289, 2311, 2311, 2333, 2335, 2339, 2343, 2347, 2351, + 2365, 2365, 2386, 2388, 2400, 2413, 2413, 2434, 2436, 2453, + 2466, 2466, 2487, 2489, 2504, 2518, 2523, 2536, 2541, 2554, + 2575, 2596, 2620, 2626, 2637, 2649, 2655, 2665, 2670, 2683, + 2688, 2692, 2704, 2709, 2724, 2729, 2742, 2744, 2758, 2765, + 2771, 2787, 2796, 2802 }; #endif @@ -3016,13 +3016,21 @@ case 154: primitive->set_draw_order((int)value); } else if (cmp_nocase_uh(name, "bin") == 0) { primitive->set_bin(strval); + } else if (cmp_nocase_uh(name, "thick") == 0) { + if (primitive->is_of_type(EggLine::get_class_type())) { + DCAST(EggLine, primitive)->set_thick(value); + } else if (primitive->is_of_type(EggPoint::get_class_type())) { + DCAST(EggPoint, primitive)->set_thick(value); + } else { + eggyywarning("scalar thick is only meaningful for points and lines."); + } } else { eggyywarning("Unknown scalar " + name); } } break; case 166: -#line 1816 "parser.yxx" +#line 1824 "parser.yxx" { EggNurbsCurve *curve = DCAST(EggNurbsCurve, yyvsp[0]._egg); EggNurbsSurface *nurbs = DCAST(EggNurbsSurface, egg_stack.back()); @@ -3030,7 +3038,7 @@ case 166: } break; case 168: -#line 1823 "parser.yxx" +#line 1831 "parser.yxx" { EggNurbsSurface *primitive = DCAST(EggNurbsSurface, egg_stack.back()); string name = yyvsp[-3]._string; @@ -3085,7 +3093,7 @@ case 168: } break; case 179: -#line 1897 "parser.yxx" +#line 1905 "parser.yxx" { EggNurbsCurve *primitive = DCAST(EggNurbsCurve, egg_stack.back()); string name = yyvsp[-3]._string; @@ -3146,7 +3154,7 @@ case 179: } break; case 180: -#line 1966 "parser.yxx" +#line 1974 "parser.yxx" { if (yyvsp[0]._egg != (EggTexture *)NULL) { EggTexture *texture = DCAST(EggTexture, yyvsp[0]._egg); @@ -3155,7 +3163,7 @@ case 180: } break; case 181: -#line 1983 "parser.yxx" +#line 1991 "parser.yxx" { EggTexture *texture = NULL; @@ -3187,7 +3195,7 @@ case 181: } break; case 182: -#line 2023 "parser.yxx" +#line 2031 "parser.yxx" { if (yyvsp[0]._egg != (EggMaterial *)NULL) { EggMaterial *material = DCAST(EggMaterial, yyvsp[0]._egg); @@ -3196,13 +3204,13 @@ case 182: } break; case 183: -#line 2040 "parser.yxx" +#line 2048 "parser.yxx" { DCAST(EggPrimitive, egg_stack.back())->set_normal(Normald(yyvsp[-2]._number, yyvsp[-1]._number, yyvsp[0]._number)); } break; case 184: -#line 2044 "parser.yxx" +#line 2052 "parser.yxx" { bool inserted = DCAST(EggPrimitive, egg_stack.back())->_dnormals. insert(EggMorphNormal(yyvsp[-5]._string, LVector3d(yyvsp[-3]._number, yyvsp[-2]._number, yyvsp[-1]._number))).second; @@ -3212,7 +3220,7 @@ case 184: } break; case 185: -#line 2052 "parser.yxx" +#line 2060 "parser.yxx" { bool inserted = DCAST(EggPrimitive, egg_stack.back())->_dnormals. insert(EggMorphNormal(yyvsp[-4]._string, LVector3d(yyvsp[-3]._number, yyvsp[-2]._number, yyvsp[-1]._number))).second; @@ -3222,13 +3230,13 @@ case 185: } break; case 186: -#line 2070 "parser.yxx" +#line 2078 "parser.yxx" { DCAST(EggPrimitive, egg_stack.back())->set_color(Colorf(yyvsp[-3]._number, yyvsp[-2]._number, yyvsp[-1]._number, yyvsp[0]._number)); } break; case 187: -#line 2074 "parser.yxx" +#line 2082 "parser.yxx" { bool inserted = DCAST(EggPrimitive, egg_stack.back())->_drgbas. insert(EggMorphColor(yyvsp[-6]._string, LVector4f(yyvsp[-4]._number, yyvsp[-3]._number, yyvsp[-2]._number, yyvsp[-1]._number))).second; @@ -3238,7 +3246,7 @@ case 187: } break; case 188: -#line 2082 "parser.yxx" +#line 2090 "parser.yxx" { bool inserted = DCAST(EggPrimitive, egg_stack.back())->_drgbas. insert(EggMorphColor(yyvsp[-5]._string, LVector4f(yyvsp[-4]._number, yyvsp[-3]._number, yyvsp[-2]._number, yyvsp[-1]._number))).second; @@ -3248,7 +3256,7 @@ case 188: } break; case 189: -#line 2100 "parser.yxx" +#line 2108 "parser.yxx" { EggPrimitive *primitive = DCAST(EggPrimitive, egg_stack.back()); int value = (int)yyvsp[0]._number; @@ -3256,7 +3264,7 @@ case 189: } break; case 190: -#line 2116 "parser.yxx" +#line 2124 "parser.yxx" { if (yyvsp[-2]._egg != (EggVertexPool *)NULL) { EggVertexPool *pool = DCAST(EggVertexPool, yyvsp[-2]._egg); @@ -3279,7 +3287,7 @@ case 190: } break; case 191: -#line 2147 "parser.yxx" +#line 2155 "parser.yxx" { EggNurbsSurface *nurbs = DCAST(EggNurbsSurface, egg_stack.back()); int u_order = (int)yyvsp[-1]._number; @@ -3289,7 +3297,7 @@ case 191: } break; case 192: -#line 2165 "parser.yxx" +#line 2173 "parser.yxx" { EggNurbsSurface *nurbs = DCAST(EggNurbsSurface, egg_stack.back()); PTA_double nums = yyvsp[0]._number_list; @@ -3301,7 +3309,7 @@ case 192: } break; case 193: -#line 2185 "parser.yxx" +#line 2193 "parser.yxx" { EggNurbsSurface *nurbs = DCAST(EggNurbsSurface, egg_stack.back()); PTA_double nums = yyvsp[0]._number_list; @@ -3313,14 +3321,14 @@ case 193: } break; case 194: -#line 2205 "parser.yxx" +#line 2213 "parser.yxx" { EggNurbsSurface *nurbs = DCAST(EggNurbsSurface, egg_stack.back()); nurbs->_trims.push_back(EggNurbsSurface::Trim()); } break; case 196: -#line 2221 "parser.yxx" +#line 2229 "parser.yxx" { EggNurbsSurface *nurbs = DCAST(EggNurbsSurface, egg_stack.back()); nassertr(!nurbs->_trims.empty(), 0); @@ -3328,7 +3336,7 @@ case 196: } break; case 197: -#line 2227 "parser.yxx" +#line 2235 "parser.yxx" { EggNurbsSurface *nurbs = DCAST(EggNurbsSurface, egg_stack.back()); nassertr(!nurbs->_trims.empty(), 0); @@ -3338,7 +3346,7 @@ case 197: } break; case 198: -#line 2246 "parser.yxx" +#line 2254 "parser.yxx" { EggNurbsCurve *nurbs = DCAST(EggNurbsCurve, egg_stack.back()); int order = (int)yyvsp[0]._number; @@ -3346,7 +3354,7 @@ case 198: } break; case 199: -#line 2262 "parser.yxx" +#line 2270 "parser.yxx" { EggNurbsCurve *nurbs = DCAST(EggNurbsCurve, egg_stack.back()); PTA_double nums = yyvsp[0]._number_list; @@ -3358,7 +3366,7 @@ case 199: } break; case 200: -#line 2283 "parser.yxx" +#line 2291 "parser.yxx" { EggTable *table = new EggTable(yyvsp[0]._string); table->set_table_type(EggTable::TT_table); @@ -3366,14 +3374,14 @@ case 200: } break; case 201: -#line 2289 "parser.yxx" +#line 2297 "parser.yxx" { yyval._egg = egg_stack.back(); egg_stack.pop_back(); } break; case 202: -#line 2305 "parser.yxx" +#line 2313 "parser.yxx" { EggTable *table = new EggTable(yyvsp[0]._string); table->set_table_type(EggTable::TT_bundle); @@ -3381,58 +3389,58 @@ case 202: } break; case 203: -#line 2311 "parser.yxx" +#line 2319 "parser.yxx" { yyval._egg = egg_stack.back(); egg_stack.pop_back(); } break; case 205: -#line 2328 "parser.yxx" -{ - DCAST(EggTable, egg_stack.back())->add_child(DCAST(EggNode, yyvsp[0]._egg)); -} - break; -case 206: -#line 2332 "parser.yxx" -{ - DCAST(EggTable, egg_stack.back())->add_child(DCAST(EggNode, yyvsp[0]._egg)); -} - break; -case 207: #line 2336 "parser.yxx" { DCAST(EggTable, egg_stack.back())->add_child(DCAST(EggNode, yyvsp[0]._egg)); } break; -case 208: +case 206: #line 2340 "parser.yxx" { DCAST(EggTable, egg_stack.back())->add_child(DCAST(EggNode, yyvsp[0]._egg)); } break; -case 209: +case 207: #line 2344 "parser.yxx" +{ + DCAST(EggTable, egg_stack.back())->add_child(DCAST(EggNode, yyvsp[0]._egg)); +} + break; +case 208: +#line 2348 "parser.yxx" +{ + DCAST(EggTable, egg_stack.back())->add_child(DCAST(EggNode, yyvsp[0]._egg)); +} + break; +case 209: +#line 2352 "parser.yxx" { DCAST(EggTable, egg_stack.back())->add_child(DCAST(EggNode, yyvsp[0]._egg)); } break; case 210: -#line 2359 "parser.yxx" +#line 2367 "parser.yxx" { EggSAnimData *anim_data = new EggSAnimData(yyvsp[0]._string); egg_stack.push_back(anim_data); } break; case 211: -#line 2364 "parser.yxx" +#line 2372 "parser.yxx" { yyval._egg = egg_stack.back(); egg_stack.pop_back(); } break; case 213: -#line 2381 "parser.yxx" +#line 2389 "parser.yxx" { EggSAnimData *anim_data = DCAST(EggSAnimData, egg_stack.back()); string name = yyvsp[-3]._string; @@ -3446,27 +3454,27 @@ case 213: } break; case 214: -#line 2393 "parser.yxx" +#line 2401 "parser.yxx" { DCAST(EggSAnimData, egg_stack.back())->set_data(yyvsp[-1]._number_list); } break; case 215: -#line 2407 "parser.yxx" +#line 2415 "parser.yxx" { EggXfmAnimData *anim_data = new EggXfmAnimData(yyvsp[0]._string); egg_stack.push_back(anim_data); } break; case 216: -#line 2412 "parser.yxx" +#line 2420 "parser.yxx" { yyval._egg = egg_stack.back(); egg_stack.pop_back(); } break; case 218: -#line 2429 "parser.yxx" +#line 2437 "parser.yxx" { EggXfmAnimData *anim_data = DCAST(EggXfmAnimData, egg_stack.back()); string name = yyvsp[-3]._string; @@ -3485,27 +3493,27 @@ case 218: } break; case 219: -#line 2446 "parser.yxx" +#line 2454 "parser.yxx" { DCAST(EggXfmAnimData, egg_stack.back())->set_data(yyvsp[-1]._number_list); } break; case 220: -#line 2460 "parser.yxx" +#line 2468 "parser.yxx" { EggXfmSAnim *anim_group = new EggXfmSAnim(yyvsp[0]._string); egg_stack.push_back(anim_group); } break; case 221: -#line 2465 "parser.yxx" +#line 2473 "parser.yxx" { yyval._egg = egg_stack.back(); egg_stack.pop_back(); } break; case 223: -#line 2482 "parser.yxx" +#line 2490 "parser.yxx" { EggXfmSAnim *anim_group = DCAST(EggXfmSAnim, egg_stack.back()); string name = yyvsp[-3]._string; @@ -3522,37 +3530,37 @@ case 223: } break; case 224: -#line 2497 "parser.yxx" +#line 2505 "parser.yxx" { DCAST(EggXfmSAnim, egg_stack.back())->add_child(DCAST(EggNode, yyvsp[0]._egg)); } break; case 225: -#line 2512 "parser.yxx" +#line 2520 "parser.yxx" { yyval._number_list = PTA_double::empty_array(0); } break; case 226: -#line 2516 "parser.yxx" +#line 2524 "parser.yxx" { yyval._number_list.push_back((double)yyvsp[0]._number); } break; case 227: -#line 2530 "parser.yxx" +#line 2538 "parser.yxx" { yyval._number_list = PTA_double::empty_array(0); } break; case 228: -#line 2534 "parser.yxx" +#line 2542 "parser.yxx" { yyval._number_list.push_back(yyvsp[0]._number); } break; case 229: -#line 2548 "parser.yxx" +#line 2556 "parser.yxx" { string name = yyvsp[0]._string; Textures::iterator vpi = textures.find(name); @@ -3565,7 +3573,7 @@ case 229: } break; case 230: -#line 2569 "parser.yxx" +#line 2577 "parser.yxx" { string name = yyvsp[0]._string; Materials::iterator vpi = materials.find(name); @@ -3578,7 +3586,7 @@ case 230: } break; case 231: -#line 2590 "parser.yxx" +#line 2598 "parser.yxx" { string name = yyvsp[0]._string; VertexPools::iterator vpi = vertex_pools.find(name); @@ -3593,69 +3601,69 @@ case 231: } break; case 232: -#line 2614 "parser.yxx" +#line 2622 "parser.yxx" { eggyyerror("Name required."); yyval._string = ""; } break; case 235: -#line 2643 "parser.yxx" +#line 2651 "parser.yxx" { eggyyerror("String required."); yyval._string = ""; } break; case 237: -#line 2659 "parser.yxx" +#line 2667 "parser.yxx" { yyval._string = ""; } break; case 239: -#line 2677 "parser.yxx" +#line 2685 "parser.yxx" { yyval._string = yyvsp[0]._string; } break; case 240: -#line 2681 "parser.yxx" +#line 2689 "parser.yxx" { yyval._string = yyvsp[0]._string; } break; case 242: -#line 2698 "parser.yxx" +#line 2706 "parser.yxx" { yyval._string = ""; } break; case 243: -#line 2702 "parser.yxx" +#line 2710 "parser.yxx" { yyval._string = yyvsp[0]._string; } break; case 244: -#line 2718 "parser.yxx" +#line 2726 "parser.yxx" { yyval._string = yyvsp[0]._string; } break; case 245: -#line 2722 "parser.yxx" +#line 2730 "parser.yxx" { yyval._string = yyvsp[-1]._string + "\n" + yyvsp[0]._string; } break; case 247: -#line 2737 "parser.yxx" +#line 2745 "parser.yxx" { yyval._number = yyvsp[0]._ulong; } break; case 248: -#line 2752 "parser.yxx" +#line 2760 "parser.yxx" { yyval._number = yyvsp[0]._number; yyval._ulong = (unsigned long)yyvsp[0]._number; @@ -3663,7 +3671,7 @@ case 248: } break; case 249: -#line 2758 "parser.yxx" +#line 2766 "parser.yxx" { yyval._number = yyvsp[0]._ulong; yyval._ulong = yyvsp[0]._ulong; @@ -3671,7 +3679,7 @@ case 249: } break; case 250: -#line 2764 "parser.yxx" +#line 2772 "parser.yxx" { yyval._number = 0.0; yyval._ulong = 0; @@ -3679,7 +3687,7 @@ case 250: } break; case 251: -#line 2781 "parser.yxx" +#line 2789 "parser.yxx" { int i = (int)yyvsp[0]._number; if ((double)i != yyvsp[0]._number) { @@ -3689,7 +3697,7 @@ case 251: } break; case 252: -#line 2789 "parser.yxx" +#line 2797 "parser.yxx" { yyval._number = yyvsp[0]._ulong; } @@ -3927,4 +3935,4 @@ yyreturn: #endif return yyresult; } -#line 2796 "parser.yxx" +#line 2804 "parser.yxx" diff --git a/panda/src/egg/parser.yxx b/panda/src/egg/parser.yxx index 6ed576a485..42bd766b92 100644 --- a/panda/src/egg/parser.yxx +++ b/panda/src/egg/parser.yxx @@ -1787,6 +1787,14 @@ primitive_body: primitive->set_draw_order((int)value); } else if (cmp_nocase_uh(name, "bin") == 0) { primitive->set_bin(strval); + } else if (cmp_nocase_uh(name, "thick") == 0) { + if (primitive->is_of_type(EggLine::get_class_type())) { + DCAST(EggLine, primitive)->set_thick(value); + } else if (primitive->is_of_type(EggPoint::get_class_type())) { + DCAST(EggPoint, primitive)->set_thick(value); + } else { + eggyywarning("scalar thick is only meaningful for points and lines."); + } } else { eggyywarning("Unknown scalar " + name); } diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index c0f3d46359..853639a5dc 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -40,6 +40,9 @@ #include "qpgeom.h" #include "qpgeomTriangles.h" #include "qpgeomTristrips.h" +#include "qpgeomLines.h" +#include "qpgeomLinestrips.h" +#include "qpgeomPoints.h" #include "sequenceNode.h" #include "switchNode.h" #include "portalNode.h" @@ -1993,8 +1996,19 @@ make_primitive(const EggRenderState *render_state, EggPrimitive *egg_prim, if (egg_prim->size() == 3) { primitive = new qpGeomTriangles(qpGeomUsageHint::UH_static); } + } else if (egg_prim->is_of_type(EggTriangleStrip::get_class_type())) { primitive = new qpGeomTristrips(qpGeomUsageHint::UH_static); + + } else if (egg_prim->is_of_type(EggLine::get_class_type())) { + if (egg_prim->size() == 2) { + primitive = new qpGeomLines(qpGeomUsageHint::UH_static); + } else { + primitive = new qpGeomLinestrips(qpGeomUsageHint::UH_static); + } + + } else if (egg_prim->is_of_type(EggPoint::get_class_type())) { + primitive = new qpGeomPoints(qpGeomUsageHint::UH_static); } if (primitive == (qpGeomPrimitive *)NULL) { diff --git a/panda/src/egg2pg/eggRenderState.I b/panda/src/egg2pg/eggRenderState.I index 46fb150cc2..96dbde7b0f 100644 --- a/panda/src/egg2pg/eggRenderState.I +++ b/panda/src/egg2pg/eggRenderState.I @@ -27,6 +27,7 @@ EggRenderState(EggLoader &loader) : _state(RenderState::make_empty()), _hidden(false), _flat_shaded(false), + _primitive_type(qpGeomPrimitive::PT_none), _loader(loader) { } @@ -60,5 +61,8 @@ compare_to(const EggRenderState &other) const { if (_flat_shaded != other._flat_shaded) { return (int)_flat_shaded - (int)other._flat_shaded; } + if (_primitive_type != other._primitive_type) { + return (int)_primitive_type - (int)other._primitive_type; + } return 0; } diff --git a/panda/src/egg2pg/eggRenderState.cxx b/panda/src/egg2pg/eggRenderState.cxx index 3ffca9e55e..8d42272f07 100644 --- a/panda/src/egg2pg/eggRenderState.cxx +++ b/panda/src/egg2pg/eggRenderState.cxx @@ -18,6 +18,8 @@ #include "eggRenderState.h" #include "eggRenderMode.h" +#include "eggLine.h" +#include "eggPoint.h" #include "textureAttrib.h" #include "renderAttrib.h" #include "eggTexture.h" @@ -32,6 +34,7 @@ #include "depthWriteAttrib.h" #include "depthTestAttrib.h" #include "texMatrixAttrib.h" +#include "renderModeAttrib.h" #include "material.h" #include "materialAttrib.h" #include "materialPool.h" @@ -349,6 +352,24 @@ fill_state(EggPrimitive *egg_prim) { } } + if (egg_prim->is_of_type(EggLine::get_class_type())) { + _primitive_type = qpGeomPrimitive::PT_lines; + EggLine *egg_line = DCAST(EggLine, egg_prim); + if (egg_line->get_thick() != 1.0) { + add_attrib(RenderModeAttrib::make(RenderModeAttrib::M_unchanged, + egg_line->get_thick())); + } + } else if (egg_prim->is_of_type(EggPoint::get_class_type())) { + _primitive_type = qpGeomPrimitive::PT_points; + EggPoint *egg_point = DCAST(EggPoint, egg_prim); + if (egg_point->get_thick() != 1.0) { + add_attrib(RenderModeAttrib::make(RenderModeAttrib::M_unchanged, + egg_point->get_thick())); + } + } else { + _primitive_type = qpGeomPrimitive::PT_polygons; + } + if (has_bin) { add_attrib(CullBinAttrib::make(bin, draw_order)); diff --git a/panda/src/egg2pg/eggRenderState.h b/panda/src/egg2pg/eggRenderState.h index 256f7adad4..8f4299c8cb 100644 --- a/panda/src/egg2pg/eggRenderState.h +++ b/panda/src/egg2pg/eggRenderState.h @@ -26,6 +26,7 @@ #include "renderState.h" #include "renderAttrib.h" #include "internalName.h" +#include "qpgeomPrimitive.h" #include "luse.h" #include "pointerTo.h" #include "pvector.h" @@ -64,6 +65,7 @@ public: CPT(RenderState) _state; bool _hidden; bool _flat_shaded; + qpGeomPrimitive::PrimitiveType _primitive_type; typedef EggLoader::BakeInUVs BakeInUVs; typedef EggLoader::TextureDef TextureDef; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index cf5c7295d8..a42a4632dd 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -25,6 +25,9 @@ #include "qpgeomTriangles.h" #include "qpgeomTristrips.h" #include "qpgeomTrifans.h" +#include "qpgeomLines.h" +#include "qpgeomLinestrips.h" +#include "qpgeomPoints.h" #include "graphicsWindow.h" #include "lens.h" #include "perspectiveLens.h" @@ -2065,6 +2068,20 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger, _geom_display_list = 0; + if (_auto_antialias_mode) { + switch (geom->get_primitive_type()) { + case qpGeomPrimitive::PT_polygons: + setup_antialias_polygon(); + break; + case qpGeomPrimitive::PT_points: + setup_antialias_point(); + break; + case qpGeomPrimitive::PT_lines: + setup_antialias_line(); + break; + } + } + if (geom->get_usage_hint() == qpGeomUsageHint::UH_static && _vertex_data->get_usage_hint() == qpGeomUsageHint::UH_static && display_lists) { @@ -2209,7 +2226,6 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger, //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: draw_triangles(const qpGeomTriangles *primitive) { - // setup_antialias_polygon(); _vertices_tri_pcollector.add_level(primitive->get_num_vertices()); const unsigned short *client_pointer = setup_primitive(primitive); @@ -2229,8 +2245,6 @@ draw_triangles(const qpGeomTriangles *primitive) { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: draw_tristrips(const qpGeomTristrips *primitive) { - // setup_antialias_polygon(); - _vertices_tristrip_pcollector.add_level(primitive->get_num_vertices()); const unsigned short *client_pointer = setup_primitive(primitive); @@ -2250,6 +2264,44 @@ draw_tristrips(const qpGeomTristrips *primitive) { report_my_gl_errors(); } +//////////////////////////////////////////////////////////////////// +// Function: CLP(GraphicsStateGuardian)::draw_lines +// Access: Public, Virtual +// Description: Draws a series of disconnected line segments. +//////////////////////////////////////////////////////////////////// +void CLP(GraphicsStateGuardian):: +draw_lines(const qpGeomLines *primitive) { + _vertices_tri_pcollector.add_level(primitive->get_num_vertices()); + const unsigned short *client_pointer = setup_primitive(primitive); + + _glDrawRangeElements(GL_LINES, + primitive->get_min_vertex(), + primitive->get_max_vertex(), + primitive->get_num_vertices(), + GL_UNSIGNED_SHORT, client_pointer); + + report_my_gl_errors(); +} + +//////////////////////////////////////////////////////////////////// +// Function: CLP(GraphicsStateGuardian)::draw_points +// Access: Public, Virtual +// Description: Draws a series of disconnected points. +//////////////////////////////////////////////////////////////////// +void CLP(GraphicsStateGuardian):: +draw_points(const qpGeomPoints *primitive) { + _vertices_tri_pcollector.add_level(primitive->get_num_vertices()); + const unsigned short *client_pointer = setup_primitive(primitive); + + _glDrawRangeElements(GL_POINTS, + primitive->get_min_vertex(), + primitive->get_max_vertex(), + primitive->get_num_vertices(), + GL_UNSIGNED_SHORT, client_pointer); + + report_my_gl_errors(); +} + //////////////////////////////////////////////////////////////////// // Function: CLP(GraphicsStateGuardian)::end_draw_primitives() // Access: Public, Virtual diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 34a965cd93..cc3a1da0a4 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -98,6 +98,8 @@ public: const qpGeomVertexData *vertex_data); virtual void draw_triangles(const qpGeomTriangles *primitive); virtual void draw_tristrips(const qpGeomTristrips *primitive); + virtual void draw_lines(const qpGeomLines *primitive); + virtual void draw_points(const qpGeomPoints *primitive); virtual void end_draw_primitives(); INLINE bool draw_display_list(GeomContext *gc); diff --git a/panda/src/gobj/Sources.pp b/panda/src/gobj/Sources.pp index bb5238114d..7afcbf8ae9 100644 --- a/panda/src/gobj/Sources.pp +++ b/panda/src/gobj/Sources.pp @@ -24,6 +24,9 @@ qpgeomTriangles.h \ qpgeomTristrips.h \ qpgeomTrifans.h \ + qpgeomLines.h \ + qpgeomLinestrips.h \ + qpgeomPoints.h \ qpgeomUsageHint.h \ qpgeomVertexArrayData.h qpgeomVertexArrayData.I \ qpgeomVertexArrayFormat.h qpgeomVertexArrayFormat.I \ @@ -62,6 +65,9 @@ qpgeomTriangles.cxx \ qpgeomTristrips.cxx \ qpgeomTrifans.cxx \ + qpgeomLines.cxx \ + qpgeomLinestrips.cxx \ + qpgeomPoints.cxx \ qpgeomVertexArrayData.cxx \ qpgeomVertexArrayFormat.cxx \ qpgeomCacheEntry.cxx \ @@ -96,6 +102,9 @@ qpgeomTriangles.h \ qpgeomTristrips.h \ qpgeomTrifans.h \ + qpgeomLines.h \ + qpgeomLinestrips.h \ + qpgeomPoints.h \ qpgeomUsageHint.h \ qpgeomVertexArrayData.h qpgeomVertexArrayData.I \ qpgeomVertexArrayFormat.h qpgeomVertexArrayFormat.I \ diff --git a/panda/src/gobj/config_gobj.cxx b/panda/src/gobj/config_gobj.cxx index 0f041caf3a..0946557bab 100644 --- a/panda/src/gobj/config_gobj.cxx +++ b/panda/src/gobj/config_gobj.cxx @@ -28,6 +28,9 @@ #include "qpgeomTriangles.h" #include "qpgeomTristrips.h" #include "qpgeomTrifans.h" +#include "qpgeomLines.h" +#include "qpgeomLinestrips.h" +#include "qpgeomPoints.h" #include "qpgeomVertexArrayData.h" #include "qpgeomVertexArrayFormat.h" #include "qpgeomVertexData.h" @@ -189,6 +192,9 @@ ConfigureFn(config_gobj) { qpGeomTriangles::init_type(); qpGeomTristrips::init_type(); qpGeomTrifans::init_type(); + qpGeomLines::init_type(); + qpGeomLinestrips::init_type(); + qpGeomPoints::init_type(); qpGeomVertexArrayData::init_type(); qpGeomVertexArrayFormat::init_type(); qpGeomVertexData::init_type(); @@ -223,6 +229,9 @@ ConfigureFn(config_gobj) { qpGeomTriangles::register_with_read_factory(); qpGeomTristrips::register_with_read_factory(); qpGeomTrifans::register_with_read_factory(); + qpGeomLines::register_with_read_factory(); + qpGeomLinestrips::register_with_read_factory(); + qpGeomPoints::register_with_read_factory(); qpGeomVertexArrayData::register_with_read_factory(); qpGeomVertexArrayFormat::register_with_read_factory(); qpGeomVertexData::register_with_read_factory(); diff --git a/panda/src/gobj/gobj_composite1.cxx b/panda/src/gobj/gobj_composite1.cxx index 54ac764c22..55922f4812 100644 --- a/panda/src/gobj/gobj_composite1.cxx +++ b/panda/src/gobj/gobj_composite1.cxx @@ -17,6 +17,9 @@ #include "qpgeomTriangles.cxx" #include "qpgeomTristrips.cxx" #include "qpgeomTrifans.cxx" +#include "qpgeomLines.cxx" +#include "qpgeomLinestrips.cxx" +#include "qpgeomPoints.cxx" #include "qpgeomVertexArrayData.cxx" #include "qpgeomVertexArrayFormat.cxx" #include "qpgeomCacheEntry.cxx" diff --git a/panda/src/gobj/qpgeom.I b/panda/src/gobj/qpgeom.I index 7227cdadac..a30cd65474 100644 --- a/panda/src/gobj/qpgeom.I +++ b/panda/src/gobj/qpgeom.I @@ -17,6 +17,20 @@ //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// Function: qpGeom::get_primitive_type +// Access: Published +// Description: Returns the primitive type that is common to all +// GeomPrimitives added within the Geom. All nested +// primitives within a particular Geom must be the same +// type. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomPrimitive::PrimitiveType qpGeom:: +get_primitive_type() const { + CDReader cdata(_cycler); + return cdata->_primitive_type; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeom::get_usage_hint // Access: Published @@ -104,6 +118,11 @@ set_primitive(int i, const qpGeomPrimitive *primitive) { clear_cache(); CDWriter cdata(_cycler); nassertv(i >= 0 && i < (int)cdata->_primitives.size()); + + // All primitives within a particular Geom must have the same + // primitive type. + nassertv(cdata->_primitive_type == qpGeomPrimitive::PT_none || + cdata->_primitive_type == primitive->get_primitive_type()); if (cdata->_got_usage_hint && cdata->_primitives[i]->get_usage_hint() != primitive->get_usage_hint()) { if (cdata->_primitives[i]->get_usage_hint() < primitive->get_usage_hint()) { @@ -118,6 +137,7 @@ set_primitive(int i, const qpGeomPrimitive *primitive) { } } cdata->_primitives[i] = (qpGeomPrimitive *)primitive; + cdata->_primitive_type = primitive->get_primitive_type(); cdata->_modified = qpGeom::get_next_modified(); } @@ -169,6 +189,7 @@ operator < (const CacheEntry &other) const { //////////////////////////////////////////////////////////////////// INLINE qpGeom::CData:: CData() : + _primitive_type(qpGeomPrimitive::PT_none), _usage_hint(qpGeomUsageHint::UH_static), _got_usage_hint(false) { @@ -183,6 +204,7 @@ INLINE qpGeom::CData:: CData(const qpGeom::CData ©) : _data(copy._data), _primitives(copy._primitives), + _primitive_type(copy._primitive_type), _usage_hint(copy._usage_hint), _got_usage_hint(copy._got_usage_hint), _modified(copy._modified) diff --git a/panda/src/gobj/qpgeom.cxx b/panda/src/gobj/qpgeom.cxx index b696605467..e1716f3581 100644 --- a/panda/src/gobj/qpgeom.cxx +++ b/panda/src/gobj/qpgeom.cxx @@ -149,7 +149,13 @@ void qpGeom:: add_primitive(const qpGeomPrimitive *primitive) { clear_cache(); CDWriter cdata(_cycler); + // All primitives within a particular Geom must have the same + // primitive type. + nassertv(cdata->_primitive_type == qpGeomPrimitive::PT_none || + cdata->_primitive_type == primitive->get_primitive_type()); + cdata->_primitives.push_back((qpGeomPrimitive *)primitive); + cdata->_primitive_type = primitive->get_primitive_type(); if (cdata->_got_usage_hint) { cdata->_usage_hint = min(cdata->_usage_hint, primitive->get_usage_hint()); @@ -174,6 +180,9 @@ remove_primitive(int i) { cdata->_got_usage_hint = false; } cdata->_primitives.erase(cdata->_primitives.begin() + i); + if (cdata->_primitives.empty()) { + cdata->_primitive_type = qpGeomPrimitive::PT_none; + } cdata->_modified = qpGeom::get_next_modified(); } @@ -190,6 +199,7 @@ clear_primitives() { clear_cache(); CDWriter cdata(_cycler); cdata->_primitives.clear(); + cdata->_primitive_type = qpGeomPrimitive::PT_none; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/qpgeom.h b/panda/src/gobj/qpgeom.h index c1b94db86a..c8250ae16e 100644 --- a/panda/src/gobj/qpgeom.h +++ b/panda/src/gobj/qpgeom.h @@ -66,6 +66,7 @@ PUBLISHED: // Temporary. virtual Geom *make_copy() const; + INLINE qpGeomPrimitive::PrimitiveType get_primitive_type() const; INLINE qpGeomUsageHint::UsageHint get_usage_hint() const; INLINE CPT(qpGeomVertexData) get_vertex_data() const; @@ -137,6 +138,7 @@ private: PT(qpGeomVertexData) _data; Primitives _primitives; + qpGeomPrimitive::PrimitiveType _primitive_type; qpGeomUsageHint::UsageHint _usage_hint; bool _got_usage_hint; UpdateSeq _modified; diff --git a/panda/src/gobj/qpgeomLines.cxx b/panda/src/gobj/qpgeomLines.cxx new file mode 100644 index 0000000000..f327e0f260 --- /dev/null +++ b/panda/src/gobj/qpgeomLines.cxx @@ -0,0 +1,160 @@ +// Filename: qpgeomLines.cxx +// Created by: drose (22Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "qpgeomLines.h" +#include "pStatTimer.h" +#include "bamReader.h" +#include "bamWriter.h" + +TypeHandle qpGeomLines::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLines::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomLines:: +qpGeomLines(qpGeomUsageHint::UsageHint usage_hint) : + qpGeomPrimitive(usage_hint) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLines::Copy Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomLines:: +qpGeomLines(const qpGeomLines ©) : + qpGeomPrimitive(copy) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLines::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomLines:: +~qpGeomLines() { +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLines::make_copy +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +PT(qpGeomPrimitive) qpGeomLines:: +make_copy() const { + return new qpGeomLines(*this); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLines::get_primitive_type +// Access: Published, Virtual +// Description: Returns the fundamental rendering type of this +// primitive: whether it is points, lines, or polygons. +// This is used primarily to set up the appropriate +// antialiasing settings when AntialiasAttrib::M_auto is +// in effect. +//////////////////////////////////////////////////////////////////// +qpGeomPrimitive::PrimitiveType qpGeomLines:: +get_primitive_type() const { + return PT_lines; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLines::get_num_vertices_per_primitive +// Access: Published, Virtual +// Description: If the primitive type is a simple type in which all +// primitives have the same number of vertices, like +// lines, returns the number of vertices per +// primitive. If the primitive type is a more complex +// type in which different primitives might have +// different numbers of vertices, for instance a +// line strip, returns 0. +//////////////////////////////////////////////////////////////////// +int qpGeomLines:: +get_num_vertices_per_primitive() const { + return 2; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLines::draw +// Access: Public, Virtual +// Description: Calls the appropriate method on the GSG to draw the +// primitive. +//////////////////////////////////////////////////////////////////// +void qpGeomLines:: +draw(GraphicsStateGuardianBase *gsg) const { + gsg->draw_lines(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLines::rotate_impl +// Access: Protected, Virtual +// Description: The virtual implementation of do_rotate(). +//////////////////////////////////////////////////////////////////// +CPTA_ushort qpGeomLines:: +rotate_impl() const { + // To rotate lines, we just move reverse the pairs of vertices. + CPTA_ushort vertices = get_vertices(); + ShadeModel shade_model = get_shade_model(); + + PTA_ushort new_vertices; + new_vertices.reserve(vertices.size()); + + for (int begin = 0; begin < (int)vertices.size(); begin += 2) { + new_vertices.push_back(vertices[begin + 1]); + new_vertices.push_back(vertices[begin]); + } + + nassertr(new_vertices.size() == vertices.size(), vertices); + return new_vertices; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLines::register_with_read_factory +// Access: Public, Static +// Description: Tells the BamReader how to create objects of type +// qpGeom. +//////////////////////////////////////////////////////////////////// +void qpGeomLines:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLines::make_from_bam +// Access: Protected, Static +// Description: This function is called by the BamReader's factory +// when a new object of type qpGeom is encountered +// in the Bam file. It should create the qpGeom +// and extract its information from the file. +//////////////////////////////////////////////////////////////////// +TypedWritable *qpGeomLines:: +make_from_bam(const FactoryParams ¶ms) { + qpGeomLines *object = new qpGeomLines(qpGeomUsageHint::UH_client); + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + object->fillin(scan, manager); + + return object; +} diff --git a/panda/src/gobj/qpgeomLines.h b/panda/src/gobj/qpgeomLines.h new file mode 100644 index 0000000000..ecf1d611d5 --- /dev/null +++ b/panda/src/gobj/qpgeomLines.h @@ -0,0 +1,74 @@ +// Filename: qpgeomLines.h +// Created by: drose (22Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef qpGEOMLINES_H +#define qpGEOMLINES_H + +#include "pandabase.h" +#include "qpgeomPrimitive.h" + +//////////////////////////////////////////////////////////////////// +// Class : qpGeomLines +// Description : Defines a series of disconnected line segments. +// +// This is part of the experimental Geom rewrite. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA qpGeomLines : public qpGeomPrimitive { +PUBLISHED: + qpGeomLines(qpGeomUsageHint::UsageHint usage_hint); + qpGeomLines(const qpGeomLines ©); + virtual ~qpGeomLines(); + + virtual PT(qpGeomPrimitive) make_copy() const; + virtual PrimitiveType get_primitive_type() const; + + virtual int get_num_vertices_per_primitive() const; + +public: + virtual void draw(GraphicsStateGuardianBase *gsg) const; + +protected: + virtual CPTA_ushort rotate_impl() const; + +public: + static void register_with_read_factory(); + +protected: + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + qpGeomPrimitive::init_type(); + register_type(_type_handle, "qpGeomLines", + qpGeomPrimitive::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; + + friend class qpGeom; +}; + +#endif diff --git a/panda/src/gobj/qpgeomLinestrips.cxx b/panda/src/gobj/qpgeomLinestrips.cxx new file mode 100644 index 0000000000..4978981e3f --- /dev/null +++ b/panda/src/gobj/qpgeomLinestrips.cxx @@ -0,0 +1,196 @@ +// Filename: qpgeomLinestrips.cxx +// Created by: drose (22Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "qpgeomLinestrips.h" +#include "qpgeomLines.h" +#include "pStatTimer.h" +#include "bamReader.h" +#include "bamWriter.h" + +TypeHandle qpGeomLinestrips::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLinestrips::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomLinestrips:: +qpGeomLinestrips(qpGeomUsageHint::UsageHint usage_hint) : + qpGeomPrimitive(usage_hint) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLinestrips::Copy Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomLinestrips:: +qpGeomLinestrips(const qpGeomLinestrips ©) : + qpGeomPrimitive(copy) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLinestrips::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomLinestrips:: +~qpGeomLinestrips() { +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLinestrips::make_copy +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +PT(qpGeomPrimitive) qpGeomLinestrips:: +make_copy() const { + return new qpGeomLinestrips(*this); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLinestrips::get_primitive_type +// Access: Published, Virtual +// Description: Returns the fundamental rendering type of this +// primitive: whether it is points, lines, or polygons. +// This is used primarily to set up the appropriate +// antialiasing settings when AntialiasAttrib::M_auto is +// in effect. +//////////////////////////////////////////////////////////////////// +qpGeomPrimitive::PrimitiveType qpGeomLinestrips:: +get_primitive_type() const { + return PT_lines; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLinestrips::draw +// Access: Public, Virtual +// Description: Calls the appropriate method on the GSG to draw the +// primitive. +//////////////////////////////////////////////////////////////////// +void qpGeomLinestrips:: +draw(GraphicsStateGuardianBase *gsg) const { + gsg->draw_linestrips(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLinestrips::decompose_impl +// Access: Protected, Virtual +// Description: Decomposes a complex primitive type into a simpler +// primitive type, for instance line strips to +// lines, and returns a pointer to the new primitive +// definition. If the decomposition cannot be +// performed, this might return the original object. +// +// This method is useful for application code that wants +// to iterate through the set of lines on the +// primitive without having to write handlers for each +// possible kind of primitive type. +//////////////////////////////////////////////////////////////////// +CPT(qpGeomPrimitive) qpGeomLinestrips:: +decompose_impl() const { + PT(qpGeomLines) lines = new qpGeomLines(get_usage_hint()); + lines->set_shade_model(get_shade_model()); + CPTA_ushort vertices = get_vertices(); + CPTA_int ends = get_ends(); + + int vi = 0; + int li = 0; + while (li < (int)ends.size()) { + int end = ends[li]; + nassertr(vi + 1 <= end, lines.p()); + nassertr(vi < (int)vertices.size(), this); + int v0 = vertices[vi]; + ++vi; + while (vi < end) { + lines->add_vertex(v0); + lines->add_vertex(vertices[vi]); + nassertr(vi < (int)vertices.size(), this); + v0 = vertices[vi]; + lines->close_primitive(); + ++vi; + } + ++li; + } + nassertr(vi == (int)vertices.size(), lines.p()); + + return lines.p(); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLinestrips::rotate_impl +// Access: Protected, Virtual +// Description: The virtual implementation of do_rotate(). +//////////////////////////////////////////////////////////////////// +CPTA_ushort qpGeomLinestrips:: +rotate_impl() const { + // To rotate a line strip, we just reverse the vertices. + CPTA_ushort vertices = get_vertices(); + CPTA_int ends = get_ends(); + PTA_ushort new_vertices; + new_vertices.reserve(vertices.size()); + + int begin = 0; + CPTA_int::const_iterator ei; + for (ei = ends.begin(); ei != ends.end(); ++ei) { + int end = (*ei); + int num_vertices = end - begin; + + for (int vi = end - 1; vi >= begin; --vi) { + new_vertices.push_back(vertices[vi]); + } + + begin = end; + } + nassertr(new_vertices.size() == vertices.size(), vertices); + + return new_vertices; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLinestrips::register_with_read_factory +// Access: Public, Static +// Description: Tells the BamReader how to create objects of type +// qpGeom. +//////////////////////////////////////////////////////////////////// +void qpGeomLinestrips:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomLinestrips::make_from_bam +// Access: Protected, Static +// Description: This function is called by the BamReader's factory +// when a new object of type qpGeom is encountered +// in the Bam file. It should create the qpGeom +// and extract its information from the file. +//////////////////////////////////////////////////////////////////// +TypedWritable *qpGeomLinestrips:: +make_from_bam(const FactoryParams ¶ms) { + qpGeomLinestrips *object = new qpGeomLinestrips(qpGeomUsageHint::UH_client); + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + object->fillin(scan, manager); + + return object; +} diff --git a/panda/src/gobj/qpgeomLinestrips.h b/panda/src/gobj/qpgeomLinestrips.h new file mode 100644 index 0000000000..775086cab4 --- /dev/null +++ b/panda/src/gobj/qpgeomLinestrips.h @@ -0,0 +1,73 @@ +// Filename: qpgeomLinestrips.h +// Created by: drose (22Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef qpGEOMLINESTRIPS_H +#define qpGEOMLINESTRIPS_H + +#include "pandabase.h" +#include "qpgeomPrimitive.h" + +//////////////////////////////////////////////////////////////////// +// Class : qpGeomLinestrips +// Description : Defines a series of line strips. +// +// This is part of the experimental Geom rewrite. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA qpGeomLinestrips : public qpGeomPrimitive { +PUBLISHED: + qpGeomLinestrips(qpGeomUsageHint::UsageHint usage_hint); + qpGeomLinestrips(const qpGeomLinestrips ©); + virtual ~qpGeomLinestrips(); + + virtual PT(qpGeomPrimitive) make_copy() const; + virtual PrimitiveType get_primitive_type() const; + +public: + virtual void draw(GraphicsStateGuardianBase *gsg) const; + +protected: + virtual CPT(qpGeomPrimitive) decompose_impl() const; + virtual CPTA_ushort rotate_impl() const; + +public: + static void register_with_read_factory(); + +protected: + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + qpGeomPrimitive::init_type(); + register_type(_type_handle, "qpGeomLinestrips", + qpGeomPrimitive::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; + + friend class qpGeom; +}; + +#endif diff --git a/panda/src/gobj/qpgeomPoints.cxx b/panda/src/gobj/qpgeomPoints.cxx new file mode 100644 index 0000000000..c43f6de155 --- /dev/null +++ b/panda/src/gobj/qpgeomPoints.cxx @@ -0,0 +1,137 @@ +// Filename: qpgeomPoints.cxx +// Created by: drose (22Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "qpgeomPoints.h" +#include "pStatTimer.h" +#include "bamReader.h" +#include "bamWriter.h" + +TypeHandle qpGeomPoints::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomPoints::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomPoints:: +qpGeomPoints(qpGeomUsageHint::UsageHint usage_hint) : + qpGeomPrimitive(usage_hint) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomPoints::Copy Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomPoints:: +qpGeomPoints(const qpGeomPoints ©) : + qpGeomPrimitive(copy) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomPoints::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomPoints:: +~qpGeomPoints() { +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomPoints::make_copy +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +PT(qpGeomPrimitive) qpGeomPoints:: +make_copy() const { + return new qpGeomPoints(*this); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomPoints::get_primitive_type +// Access: Published, Virtual +// Description: Returns the fundamental rendering type of this +// primitive: whether it is points, lines, or polygons. +// This is used primarily to set up the appropriate +// antialiasing settings when AntialiasAttrib::M_auto is +// in effect. +//////////////////////////////////////////////////////////////////// +qpGeomPrimitive::PrimitiveType qpGeomPoints:: +get_primitive_type() const { + return PT_points; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomPoints::get_num_vertices_per_primitive +// Access: Published, Virtual +// Description: If the primitive type is a simple type in which all +// primitives have the same number of vertices, like +// points, returns the number of vertices per +// primitive. If the primitive type is a more complex +// type in which different primitives might have +// different numbers of vertices, for instance a +// point strip, returns 0. +//////////////////////////////////////////////////////////////////// +int qpGeomPoints:: +get_num_vertices_per_primitive() const { + return 1; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomPoints::draw +// Access: Public, Virtual +// Description: Calls the appropriate method on the GSG to draw the +// primitive. +//////////////////////////////////////////////////////////////////// +void qpGeomPoints:: +draw(GraphicsStateGuardianBase *gsg) const { + gsg->draw_points(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomPoints::register_with_read_factory +// Access: Public, Static +// Description: Tells the BamReader how to create objects of type +// qpGeom. +//////////////////////////////////////////////////////////////////// +void qpGeomPoints:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomPoints::make_from_bam +// Access: Protected, Static +// Description: This function is called by the BamReader's factory +// when a new object of type qpGeom is encountered +// in the Bam file. It should create the qpGeom +// and extract its information from the file. +//////////////////////////////////////////////////////////////////// +TypedWritable *qpGeomPoints:: +make_from_bam(const FactoryParams ¶ms) { + qpGeomPoints *object = new qpGeomPoints(qpGeomUsageHint::UH_client); + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + object->fillin(scan, manager); + + return object; +} diff --git a/panda/src/gobj/qpgeomPoints.h b/panda/src/gobj/qpgeomPoints.h new file mode 100644 index 0000000000..2b5a208280 --- /dev/null +++ b/panda/src/gobj/qpgeomPoints.h @@ -0,0 +1,71 @@ +// Filename: qpgeomPoints.h +// Created by: drose (22Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef qpGEOMPOINTS_H +#define qpGEOMPOINTS_H + +#include "pandabase.h" +#include "qpgeomPrimitive.h" + +//////////////////////////////////////////////////////////////////// +// Class : qpGeomPoints +// Description : Defines a series of disconnected points. +// +// This is part of the experimental Geom rewrite. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA qpGeomPoints : public qpGeomPrimitive { +PUBLISHED: + qpGeomPoints(qpGeomUsageHint::UsageHint usage_hint); + qpGeomPoints(const qpGeomPoints ©); + virtual ~qpGeomPoints(); + + virtual PT(qpGeomPrimitive) make_copy() const; + virtual PrimitiveType get_primitive_type() const; + + virtual int get_num_vertices_per_primitive() const; + +public: + virtual void draw(GraphicsStateGuardianBase *gsg) const; + +public: + static void register_with_read_factory(); + +protected: + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + qpGeomPrimitive::init_type(); + register_type(_type_handle, "qpGeomPoints", + qpGeomPrimitive::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; + + friend class qpGeom; +}; + +#endif diff --git a/panda/src/gobj/qpgeomPrimitive.h b/panda/src/gobj/qpgeomPrimitive.h index d8bd4603a0..8267eae6d5 100644 --- a/panda/src/gobj/qpgeomPrimitive.h +++ b/panda/src/gobj/qpgeomPrimitive.h @@ -92,6 +92,14 @@ PUBLISHED: SM_flat_last_vertex, }; + enum PrimitiveType { + PT_none, + PT_polygons, + PT_lines, + PT_points + }; + + virtual PrimitiveType get_primitive_type() const=0; INLINE qpGeomUsageHint::UsageHint get_usage_hint() const; INLINE ShadeModel get_shade_model() const; diff --git a/panda/src/gobj/qpgeomTriangles.cxx b/panda/src/gobj/qpgeomTriangles.cxx index 9e8d1dfea1..0ffdcfc42f 100644 --- a/panda/src/gobj/qpgeomTriangles.cxx +++ b/panda/src/gobj/qpgeomTriangles.cxx @@ -64,6 +64,20 @@ make_copy() const { return new qpGeomTriangles(*this); } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomTriangles::get_primitive_type +// Access: Published, Virtual +// Description: Returns the fundamental rendering type of this +// primitive: whether it is points, lines, or polygons. +// This is used primarily to set up the appropriate +// antialiasing settings when AntialiasAttrib::M_auto is +// in effect. +//////////////////////////////////////////////////////////////////// +qpGeomPrimitive::PrimitiveType qpGeomTriangles:: +get_primitive_type() const { + return PT_polygons; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomTriangles::get_num_vertices_per_primitive // Access: Published, Virtual diff --git a/panda/src/gobj/qpgeomTriangles.h b/panda/src/gobj/qpgeomTriangles.h index 48d8936a56..6c0b7219bf 100644 --- a/panda/src/gobj/qpgeomTriangles.h +++ b/panda/src/gobj/qpgeomTriangles.h @@ -35,6 +35,7 @@ PUBLISHED: virtual ~qpGeomTriangles(); virtual PT(qpGeomPrimitive) make_copy() const; + virtual PrimitiveType get_primitive_type() const; virtual int get_num_vertices_per_primitive() const; diff --git a/panda/src/gobj/qpgeomTrifans.cxx b/panda/src/gobj/qpgeomTrifans.cxx index 367d4e8640..4e70ac8fa2 100644 --- a/panda/src/gobj/qpgeomTrifans.cxx +++ b/panda/src/gobj/qpgeomTrifans.cxx @@ -64,6 +64,20 @@ make_copy() const { return new qpGeomTrifans(*this); } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomTrifans::get_primitive_type +// Access: Published, Virtual +// Description: Returns the fundamental rendering type of this +// primitive: whether it is points, lines, or polygons. +// This is used primarily to set up the appropriate +// antialiasing settings when AntialiasAttrib::M_auto is +// in effect. +//////////////////////////////////////////////////////////////////// +qpGeomPrimitive::PrimitiveType qpGeomTrifans:: +get_primitive_type() const { + return PT_polygons; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomTrifans::draw // Access: Public, Virtual diff --git a/panda/src/gobj/qpgeomTrifans.h b/panda/src/gobj/qpgeomTrifans.h index 55044b9dfe..07d33f97e0 100644 --- a/panda/src/gobj/qpgeomTrifans.h +++ b/panda/src/gobj/qpgeomTrifans.h @@ -35,6 +35,7 @@ PUBLISHED: virtual ~qpGeomTrifans(); virtual PT(qpGeomPrimitive) make_copy() const; + virtual PrimitiveType get_primitive_type() const; public: virtual void draw(GraphicsStateGuardianBase *gsg) const; diff --git a/panda/src/gobj/qpgeomTristrips.cxx b/panda/src/gobj/qpgeomTristrips.cxx index 452a4e5287..fcb0674080 100644 --- a/panda/src/gobj/qpgeomTristrips.cxx +++ b/panda/src/gobj/qpgeomTristrips.cxx @@ -65,6 +65,20 @@ make_copy() const { return new qpGeomTristrips(*this); } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomTristrips::get_primitive_type +// Access: Published, Virtual +// Description: Returns the fundamental rendering type of this +// primitive: whether it is points, lines, or polygons. +// This is used primarily to set up the appropriate +// antialiasing settings when AntialiasAttrib::M_auto is +// in effect. +//////////////////////////////////////////////////////////////////// +qpGeomPrimitive::PrimitiveType qpGeomTristrips:: +get_primitive_type() const { + return PT_polygons; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomTristrips::draw // Access: Public, Virtual @@ -99,7 +113,7 @@ decompose_impl() const { // We need a slightly different algorithm for SM_flat_first_vertex // than for SM_flat_last_vertex, to preserve the key vertex in the - // right place. The remaining shade models can either either + // right place. The remaining shade models can use either // algorithm. if (get_shade_model() == SM_flat_first_vertex) { // Preserve the first vertex of each component triangle as the diff --git a/panda/src/gobj/qpgeomTristrips.h b/panda/src/gobj/qpgeomTristrips.h index a24f0f1791..c99555abcb 100644 --- a/panda/src/gobj/qpgeomTristrips.h +++ b/panda/src/gobj/qpgeomTristrips.h @@ -35,6 +35,7 @@ PUBLISHED: virtual ~qpGeomTristrips(); virtual PT(qpGeomPrimitive) make_copy() const; + virtual PrimitiveType get_primitive_type() const; public: virtual void draw(GraphicsStateGuardianBase *gsg) const; diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index 74a5abe93f..a24f4bb35c 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -52,6 +52,9 @@ class qpGeomPrimitive; class qpGeomTriangles; class qpGeomTristrips; class qpGeomTrifans; +class qpGeomLines; +class qpGeomLinestrips; +class qpGeomPoints; class qpGeomMunger; class PreparedGraphicsObjects; @@ -190,6 +193,9 @@ public: virtual void draw_triangles(const qpGeomTriangles *primitive)=0; virtual void draw_tristrips(const qpGeomTristrips *primitive)=0; virtual void draw_trifans(const qpGeomTrifans *primitive)=0; + virtual void draw_lines(const qpGeomLines *primitive)=0; + virtual void draw_linestrips(const qpGeomLinestrips *primitive)=0; + virtual void draw_points(const qpGeomPoints *primitive)=0; virtual void end_draw_primitives()=0; virtual void framebuffer_copy_to_texture