From ea51a7a6f7bd5a691e332e3f381db6131b4754a5 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 21 Mar 2005 17:52:15 +0000 Subject: [PATCH] ColorMunger --- panda/src/display/Sources.pp | 3 + panda/src/display/colorMunger.I | 18 ++ panda/src/display/colorMunger.cxx | 101 +++++++++++ panda/src/display/colorMunger.h | 73 ++++++++ panda/src/display/config_display.cxx | 4 +- panda/src/display/display_composite1.cxx | 1 + panda/src/display/graphicsStateGuardian.cxx | 5 +- panda/src/display/graphicsStateGuardian.h | 5 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 5 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 4 +- panda/src/glstuff/glGeomMunger_src.I | 4 +- panda/src/glstuff/glGeomMunger_src.cxx | 39 ++++- panda/src/glstuff/glGeomMunger_src.h | 17 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 5 +- .../src/glstuff/glGraphicsStateGuardian_src.h | 4 +- panda/src/glstuff/glmisc_src.cxx | 1 + panda/src/gobj/drawable.cxx | 3 +- panda/src/gobj/drawable.h | 2 + panda/src/gobj/geom.cxx | 3 +- panda/src/gobj/geom.h | 1 + panda/src/gobj/qpgeom.cxx | 5 +- panda/src/gobj/qpgeom.h | 1 + panda/src/gobj/qpgeomMunger.I | 26 ++- panda/src/gobj/qpgeomMunger.cxx | 48 ++++-- panda/src/gobj/qpgeomMunger.h | 5 +- panda/src/gobj/qpgeomVertexArrayFormat.cxx | 19 ++- panda/src/gobj/qpgeomVertexArrayFormat.h | 8 +- panda/src/gobj/qpgeomVertexCacheManager.I | 5 +- panda/src/gobj/qpgeomVertexData.cxx | 160 +++++++++++++++++- panda/src/gobj/qpgeomVertexData.h | 14 +- panda/src/gobj/qpgeomVertexFormat.cxx | 8 +- panda/src/gobj/qpgeomVertexFormat.h | 2 +- panda/src/gobj/qpgeomVertexIterator.I | 67 +++++++- panda/src/gobj/qpgeomVertexIterator.h | 8 +- panda/src/gsgbase/graphicsStateGuardianBase.h | 4 +- panda/src/pgraph/cullableObject.I | 2 +- panda/src/pgraph/cullableObject.cxx | 1 + panda/src/pgraph/cullableObject.h | 1 + 38 files changed, 624 insertions(+), 58 deletions(-) create mode 100644 panda/src/display/colorMunger.I create mode 100644 panda/src/display/colorMunger.cxx create mode 100644 panda/src/display/colorMunger.h diff --git a/panda/src/display/Sources.pp b/panda/src/display/Sources.pp index ef291791ac..554db7e077 100644 --- a/panda/src/display/Sources.pp +++ b/panda/src/display/Sources.pp @@ -11,6 +11,7 @@ #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx #define SOURCES \ + colorMunger.I colorMunger.h \ config_display.h \ drawableRegion.I drawableRegion.h \ displayRegion.I displayRegion.h \ @@ -34,6 +35,7 @@ lensStack.I lensStack.h #define INCLUDED_SOURCES \ + colorMunger.cxx \ config_display.cxx \ drawableRegion.cxx \ displayRegion.cxx \ @@ -51,6 +53,7 @@ windowProperties.cxx #define INSTALL_HEADERS \ + colorMunger.I colorMunger.h \ config_display.h \ drawableRegion.I drawableRegion.h \ displayRegion.I displayRegion.h displayRegionStack.I \ diff --git a/panda/src/display/colorMunger.I b/panda/src/display/colorMunger.I new file mode 100644 index 0000000000..4568a07c26 --- /dev/null +++ b/panda/src/display/colorMunger.I @@ -0,0 +1,18 @@ +// Filename: colorMunger.I +// Created by: drose (21Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + diff --git a/panda/src/display/colorMunger.cxx b/panda/src/display/colorMunger.cxx new file mode 100644 index 0000000000..3d99b72695 --- /dev/null +++ b/panda/src/display/colorMunger.cxx @@ -0,0 +1,101 @@ +// Filename: colorMunger.cxx +// Created by: drose (21Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "colorMunger.h" +#include "renderState.h" +#include "dcast.h" + +TypeHandle ColorMunger::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: ColorMunger::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +ColorMunger:: +ColorMunger(const GraphicsStateGuardianBase *gsg, const RenderState *state, + int num_components, + qpGeomVertexDataType::NumericType numeric_type) : + qpGeomMunger(gsg, state), + _num_components(num_components), + _numeric_type(numeric_type) +{ + _color = state->get_color(); + _color_scale = state->get_color_scale(); +} + +//////////////////////////////////////////////////////////////////// +// Function: ColorMunger::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +ColorMunger:: +~ColorMunger() { +} + +//////////////////////////////////////////////////////////////////// +// Function: ColorMunger::munge_data_impl +// Access: Protected, Virtual +// Description: Given a source GeomVertexData, converts it as +// necessary for rendering. +//////////////////////////////////////////////////////////////////// +CPT(qpGeomVertexData) ColorMunger:: +munge_data_impl(const qpGeomVertexData *data) { + CPT(qpGeomVertexData) new_data = data; + + if (_color != (ColorAttrib *)NULL && + _color->get_color_type() == ColorAttrib::T_flat) { + Colorf color = _color->get_color(); + if (_color_scale != (ColorScaleAttrib *)NULL && + _color_scale->has_scale()) { + const LVecBase4f &cs = _color_scale->get_scale(); + color.set(color[0] * cs[0], + color[1] * cs[1], + color[2] * cs[2], + color[3] * cs[3]); + } + new_data = new_data->set_color(color, _num_components, _numeric_type); + + } else if (_color_scale != (ColorScaleAttrib *)NULL && + _color_scale->has_scale()) { + const LVecBase4f &cs = _color_scale->get_scale(); + new_data = new_data->scale_color(cs, _num_components, _numeric_type); + } + + return qpGeomMunger::munge_data_impl(new_data); +} + +//////////////////////////////////////////////////////////////////// +// Function: ColorMunger::compare_to_impl +// Access: Protected, Virtual +// Description: Called to compare two GeomMungers who are known to be +// of the same type, for an apples-to-apples comparison. +// This will never be called on two pointers of a +// different type. +//////////////////////////////////////////////////////////////////// +int ColorMunger:: +compare_to_impl(const qpGeomMunger *other) const { + const ColorMunger *om = DCAST(ColorMunger, other); + if (_color != om->_color) { + return _color < om->_color ? -1 : 1; + } + if (_color_scale != om->_color_scale) { + return _color_scale < om->_color_scale ? -1 : 1; + } + return 0; +} diff --git a/panda/src/display/colorMunger.h b/panda/src/display/colorMunger.h new file mode 100644 index 0000000000..34bc22d216 --- /dev/null +++ b/panda/src/display/colorMunger.h @@ -0,0 +1,73 @@ +// Filename: colorMunger.h +// Created by: drose (21Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// 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 COLORMUNGER_H +#define COLORMUNGER_H + +#include "pandabase.h" +#include "qpgeomMunger.h" +#include "colorAttrib.h" +#include "colorScaleAttrib.h" +#include "pointerTo.h" + +//////////////////////////////////////////////////////////////////// +// Class : ColorMunger +// Description : Applies ColorAttrib and ColorScaleAttrib by munging +// the vertex data. +// +// This is part of the experimental Geom rewrite. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA ColorMunger : public qpGeomMunger { +public: + ColorMunger(const GraphicsStateGuardianBase *gsg, const RenderState *state, + int num_components, + qpGeomVertexDataType::NumericType numeric_type); + virtual ~ColorMunger(); + +protected: + virtual CPT(qpGeomVertexData) munge_data_impl(const qpGeomVertexData *data); + virtual int compare_to_impl(const qpGeomMunger *other) const; + +private: + int _num_components; + qpGeomVertexDataType::NumericType _numeric_type; + CPT(ColorAttrib) _color; + CPT(ColorScaleAttrib) _color_scale; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + qpGeomMunger::init_type(); + register_type(_type_handle, "ColorMunger", + qpGeomMunger::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; +}; + +#include "colorMunger.I" + +#endif + diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index f52fb1fb2a..3d172c83d9 100644 --- a/panda/src/display/config_display.cxx +++ b/panda/src/display/config_display.cxx @@ -18,6 +18,7 @@ #include "config_display.h" +#include "colorMunger.h" #include "graphicsStateGuardian.h" #include "graphicsPipe.h" #include "graphicsOutput.h" @@ -246,7 +247,8 @@ init_libdisplay() { return; } initialized = true; - + + ColorMunger::init_type(); GraphicsStateGuardian::init_type(); GraphicsPipe::init_type(); GraphicsOutput::init_type(); diff --git a/panda/src/display/display_composite1.cxx b/panda/src/display/display_composite1.cxx index 31609ad0ac..df4ffd42a0 100644 --- a/panda/src/display/display_composite1.cxx +++ b/panda/src/display/display_composite1.cxx @@ -1,3 +1,4 @@ +#include "colorMunger.cxx" #include "drawableRegion.cxx" #include "displayRegion.cxx" #include "graphicsEngine.cxx" diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 3f06d8ec47..77d7e319db 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -670,7 +670,9 @@ finish_decal() { // are ok, false to abort this group of primitives. //////////////////////////////////////////////////////////////////// bool GraphicsStateGuardian:: -begin_draw_primitives(const qpGeom *, const qpGeomVertexData *data) { +begin_draw_primitives(const qpGeom *, const qpGeomMunger *munger, + const qpGeomVertexData *data) { + _munger = munger; _vertex_data = data; return true; } @@ -719,6 +721,7 @@ draw_trifans(const qpGeomTrifans *primitive) { //////////////////////////////////////////////////////////////////// void GraphicsStateGuardian:: end_draw_primitives() { + _munger = NULL; _vertex_data = NULL; } diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index cbaafe1b6e..0fecb2c43c 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -148,7 +148,9 @@ public: virtual CPT(RenderState) begin_decal_base_second(); virtual void finish_decal(); - virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data); + virtual bool begin_draw_primitives(const qpGeom *geom, + const qpGeomMunger *munger, + const qpGeomVertexData *vertex_data); virtual void draw_triangles(const qpGeomTriangles *primitive); virtual void draw_tristrips(const qpGeomTristrips *primitive); virtual void draw_trifans(const qpGeomTrifans *primitive); @@ -251,6 +253,7 @@ protected: CPT(RenderState) _state; CPT(TransformState) _transform; + CPT(qpGeomMunger) _munger; CPT(qpGeomVertexData) _vertex_data; int _buffer_mask; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 38c1d92b0e..04827092d7 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -2607,10 +2607,11 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) { // are ok, false to abort this group of primitives. //////////////////////////////////////////////////////////////////// bool DXGraphicsStateGuardian8:: -begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data) { +begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger, + const qpGeomVertexData *vertex_data) { DO_PSTATS_STUFF(_draw_primitive_pcollector.start()); - if (!GraphicsStateGuardian::begin_draw_primitives(geom, vertex_data)) { + if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) { return false; } nassertr(_vertex_data != (qpGeomVertexData *)NULL, false); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index b98f8d5ea1..b91c8ac17a 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -90,7 +90,9 @@ public: virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc); virtual void draw_sphere(GeomSphere *geom, GeomContext *gc); - virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data); + virtual bool begin_draw_primitives(const qpGeom *geom, + const qpGeomMunger *munger, + const qpGeomVertexData *vertex_data); virtual void draw_triangles(const qpGeomTriangles *primitive); virtual void draw_tristrips(const qpGeomTristrips *primitive); virtual void end_draw_primitives(); diff --git a/panda/src/glstuff/glGeomMunger_src.I b/panda/src/glstuff/glGeomMunger_src.I index 24b1bb6bed..44879c1028 100644 --- a/panda/src/glstuff/glGeomMunger_src.I +++ b/panda/src/glstuff/glGeomMunger_src.I @@ -24,6 +24,8 @@ //////////////////////////////////////////////////////////////////// INLINE CLP(GeomMunger):: CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state) : - qpGeomMunger(gsg, state) + ColorMunger(gsg, state, 4, qpGeomVertexDataType::NT_uint8), + _texture(state->get_texture()), + _tex_gen(state->get_tex_gen()) { } diff --git a/panda/src/glstuff/glGeomMunger_src.cxx b/panda/src/glstuff/glGeomMunger_src.cxx index d81f098b2a..c48e96c092 100644 --- a/panda/src/glstuff/glGeomMunger_src.cxx +++ b/panda/src/glstuff/glGeomMunger_src.cxx @@ -16,8 +16,9 @@ // //////////////////////////////////////////////////////////////////// -TypeHandle CLP(GeomMunger)::_type_handle; +#include "dcast.h" +TypeHandle CLP(GeomMunger)::_type_handle; //////////////////////////////////////////////////////////////////// // Function: CLP(GeomMunger)::munge_format_impl @@ -65,3 +66,39 @@ munge_format_impl(const qpGeomVertexFormat *orig) { return format; } + +//////////////////////////////////////////////////////////////////// +// Function: CLP(GeomMunger)::compare_to_impl +// Access: Protected, Virtual +// Description: Called to compare two GeomMungers who are known to be +// of the same type, for an apples-to-apples comparison. +// This will never be called on two pointers of a +// different type. +//////////////////////////////////////////////////////////////////// +int CLP(GeomMunger):: +compare_to_impl(const qpGeomMunger *other) const { + const CLP(GeomMunger) *om = DCAST(CLP(GeomMunger), other); + if (_texture != om->_texture) { + return _texture < om->_texture ? -1 : 1; + } + if (_tex_gen != om->_tex_gen) { + return _tex_gen < om->_tex_gen ? -1 : 1; + } + return ColorMunger::compare_to_impl(other); +} + +//////////////////////////////////////////////////////////////////// +// Function: CLP(GeomMunger)::geom_compare_to_impl +// Access: Protected, Virtual +// Description: Called to compare two GeomMungers who are known to be +// of the same type, for an apples-to-apples comparison. +// This will never be called on two pointers of a +// different type. +//////////////////////////////////////////////////////////////////// +int CLP(GeomMunger):: +geom_compare_to_impl(const qpGeomMunger *other) const { + // We don't consider _texture and _tex_gen for these purposes; they + // affect only whether the GL display list should be regenerated or + // not. + return ColorMunger::compare_to_impl(other); +} diff --git a/panda/src/glstuff/glGeomMunger_src.h b/panda/src/glstuff/glGeomMunger_src.h index 51506949e3..43dbe09307 100644 --- a/panda/src/glstuff/glGeomMunger_src.h +++ b/panda/src/glstuff/glGeomMunger_src.h @@ -17,8 +17,11 @@ //////////////////////////////////////////////////////////////////// #include "pandabase.h" -#include "qpgeomMunger.h" +#include "colorMunger.h" #include "graphicsStateGuardian.h" +#include "textureAttrib.h" +#include "texGenAttrib.h" +#include "renderState.h" //////////////////////////////////////////////////////////////////// // Class : GLGeomMunger @@ -26,21 +29,27 @@ // for OpenGL rendering. In particular, it makes sure // colors aren't stored in DirectX's packed_argb format. //////////////////////////////////////////////////////////////////// -class EXPCL_GL CLP(GeomMunger) : public qpGeomMunger { +class EXPCL_GL CLP(GeomMunger) : public ColorMunger { public: INLINE CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state); protected: virtual CPT(qpGeomVertexFormat) munge_format_impl(const qpGeomVertexFormat *orig); + virtual int compare_to_impl(const qpGeomMunger *other) const; + virtual int geom_compare_to_impl(const qpGeomMunger *other) const; + +private: + CPT(TextureAttrib) _texture; + CPT(TexGenAttrib) _tex_gen; public: static TypeHandle get_class_type() { return _type_handle; } static void init_type() { - qpGeomMunger::init_type(); + ColorMunger::init_type(); register_type(_type_handle, CLASSPREFIX_QUOTED "GeomMunger", - qpGeomMunger::get_class_type()); + ColorMunger::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index d4558e4472..1b2be482ae 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2037,8 +2037,9 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) { // are ok, false to abort this group of primitives. //////////////////////////////////////////////////////////////////// bool CLP(GraphicsStateGuardian):: -begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data) { - if (!GraphicsStateGuardian::begin_draw_primitives(geom, vertex_data)) { +begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger, + const qpGeomVertexData *vertex_data) { + if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) { return false; } nassertr(_vertex_data != (qpGeomVertexData *)NULL, false); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index b6d5dd23b6..6f63b56443 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -92,7 +92,9 @@ public: virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc); virtual void draw_sphere(GeomSphere *geom, GeomContext *gc); - virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data); + virtual bool begin_draw_primitives(const qpGeom *geom, + const qpGeomMunger *munger, + const qpGeomVertexData *vertex_data); virtual void draw_triangles(const qpGeomTriangles *primitive); virtual void draw_tristrips(const qpGeomTristrips *primitive); virtual void end_draw_primitives(); diff --git a/panda/src/glstuff/glmisc_src.cxx b/panda/src/glstuff/glmisc_src.cxx index 5135cf125d..87478d7caa 100644 --- a/panda/src/glstuff/glmisc_src.cxx +++ b/panda/src/glstuff/glmisc_src.cxx @@ -75,6 +75,7 @@ void CLP(init_classes)() { CLP(GeomContext)::init_type(); CLP(VertexBufferContext)::init_type(); CLP(IndexBufferContext)::init_type(); + CLP(GeomMunger)::init_type(); PandaSystem *ps = PandaSystem::get_global_ptr(); ps->add_system(GLSYSTEM_NAME); diff --git a/panda/src/gobj/drawable.cxx b/panda/src/gobj/drawable.cxx index d888de8d8f..713008cfa1 100644 --- a/panda/src/gobj/drawable.cxx +++ b/panda/src/gobj/drawable.cxx @@ -48,7 +48,8 @@ dDrawable:: // At this level, this doesn't do very much. //////////////////////////////////////////////////////////////////// void dDrawable:: -draw(GraphicsStateGuardianBase *, const qpGeomVertexData *) const { +draw(GraphicsStateGuardianBase *, const qpGeomMunger *, + const qpGeomVertexData *) const { if (is_dirty()) { ((dDrawable *)this)->config(); } diff --git a/panda/src/gobj/drawable.h b/panda/src/gobj/drawable.h index 569dd90068..272ef5444f 100644 --- a/panda/src/gobj/drawable.h +++ b/panda/src/gobj/drawable.h @@ -34,6 +34,7 @@ class Datagram; class DatagramIterator; class BamReader; class BamWriter; +class qpGeomMunger; class qpGeomVertexData; //////////////////////////////////////////////////////////////////// @@ -52,6 +53,7 @@ public: virtual ~dDrawable(); virtual void draw(GraphicsStateGuardianBase *gsg, + const qpGeomMunger *munger, const qpGeomVertexData *vertex_data) const; virtual bool is_dynamic() const; diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index 5f9cdce9bc..afdc5c84d9 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -915,7 +915,8 @@ release_all() { // Description: Actually draws the Geom with the indicated GSG. //////////////////////////////////////////////////////////////////// void Geom:: -draw(GraphicsStateGuardianBase *gsg, const qpGeomVertexData *) const { +draw(GraphicsStateGuardianBase *gsg, + const qpGeomMunger *, const qpGeomVertexData *) const { PreparedGraphicsObjects *prepared_objects = gsg->get_prepared_objects(); if (is_dirty()) { ((Geom *)this)->config(); diff --git a/panda/src/gobj/geom.h b/panda/src/gobj/geom.h index f09028a471..219bbdc1b9 100644 --- a/panda/src/gobj/geom.h +++ b/panda/src/gobj/geom.h @@ -241,6 +241,7 @@ public: // From parent dDrawable virtual void draw(GraphicsStateGuardianBase *gsg, + const qpGeomMunger *munger, const qpGeomVertexData *vertex_data) const; // From parent Configurable diff --git a/panda/src/gobj/qpgeom.cxx b/panda/src/gobj/qpgeom.cxx index 6d821c6d26..9e8bf7a6a0 100644 --- a/panda/src/gobj/qpgeom.cxx +++ b/panda/src/gobj/qpgeom.cxx @@ -354,7 +354,8 @@ clear_cache() { // pre-munged to support the GSG's needs). //////////////////////////////////////////////////////////////////// void qpGeom:: -draw(GraphicsStateGuardianBase *gsg, const qpGeomVertexData *vertex_data) const { +draw(GraphicsStateGuardianBase *gsg, const qpGeomMunger *munger, + const qpGeomVertexData *vertex_data) const { #ifdef DO_PIPELINING // Make sure the usage_hint is already updated before we start to // draw, so we don't end up with a circular lock if the GSG asks us @@ -373,7 +374,7 @@ draw(GraphicsStateGuardianBase *gsg, const qpGeomVertexData *vertex_data) const CDReader cdata(_cycler); - if (gsg->begin_draw_primitives(this, vertex_data)) { + if (gsg->begin_draw_primitives(this, munger, vertex_data)) { Primitives::const_iterator pi; for (pi = cdata->_primitives.begin(); pi != cdata->_primitives.end(); diff --git a/panda/src/gobj/qpgeom.h b/panda/src/gobj/qpgeom.h index 1316887259..b537e2d93a 100644 --- a/panda/src/gobj/qpgeom.h +++ b/panda/src/gobj/qpgeom.h @@ -90,6 +90,7 @@ PUBLISHED: public: void draw(GraphicsStateGuardianBase *gsg, + const qpGeomMunger *munger, const qpGeomVertexData *vertex_data) const; static UpdateSeq get_next_modified(); diff --git a/panda/src/gobj/qpgeomMunger.I b/panda/src/gobj/qpgeomMunger.I index c8931c8c84..bae731e01b 100644 --- a/panda/src/gobj/qpgeomMunger.I +++ b/panda/src/gobj/qpgeomMunger.I @@ -71,6 +71,30 @@ compare_to(const qpGeomMunger &other) const { return compare_to_impl(&other); } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomMunger::geom_compare_to +// Access: Public +// Description: Compares two GeomMungers, considering only whether +// they would produce a different answer to +// munge_format(), munge_data(), or munge_geom(). (They +// still might be different in other ways, but if they +// would produce the same answer, this function consider +// them to be the same.) +//////////////////////////////////////////////////////////////////// +INLINE int qpGeomMunger:: +geom_compare_to(const qpGeomMunger &other) const { + // First, we compare the types; if they are of different types then + // they sort differently. + TypeHandle type = get_type(); + TypeHandle other_type = other.get_type(); + if (type != other_type) { + return type.get_index() - other_type.get_index(); + } + + // We only call compare_to_impl() if they have the same type. + return geom_compare_to_impl(&other); +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomMunger::munge_format // Access: Public @@ -96,7 +120,7 @@ munge_data(const qpGeomVertexData *data) const { // We cast away the const pointer, because do_munge_data() needs to // update caches and stuff, but we trust it not to change any // user-definable parameters. - return ((qpGeomMunger *)this)->do_munge_data(data); + return ((qpGeomMunger *)this)->munge_data_impl(data); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/qpgeomMunger.cxx b/panda/src/gobj/qpgeomMunger.cxx index 536a5f3f69..c7ce369ef6 100644 --- a/panda/src/gobj/qpgeomMunger.cxx +++ b/panda/src/gobj/qpgeomMunger.cxx @@ -140,13 +140,24 @@ do_munge_format(const qpGeomVertexFormat *format) { } //////////////////////////////////////////////////////////////////// -// Function: qpGeomMunger::do_munge_data -// Access: Protected -// Description: The protected implementation of munge_data(). This -// exists just to cast away the const pointer. +// Function: qpGeomMunger::munge_format_impl +// Access: Protected, Virtual +// Description: Given a source GeomVertexFormat, converts it if +// necessary to the appropriate format for rendering. +//////////////////////////////////////////////////////////////////// +CPT(qpGeomVertexFormat) qpGeomMunger:: +munge_format_impl(const qpGeomVertexFormat *orig) { + return orig; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomMunger::munge_data_impl +// Access: Protected, Virtual +// Description: Given a source GeomVertexData, converts it as +// necessary for rendering. //////////////////////////////////////////////////////////////////// CPT(qpGeomVertexData) qpGeomMunger:: -do_munge_data(const qpGeomVertexData *data) { +munge_data_impl(const qpGeomVertexData *data) { nassertr(_is_registered, NULL); CPT(qpGeomVertexFormat) orig_format = data->get_format(); @@ -160,17 +171,6 @@ do_munge_data(const qpGeomVertexData *data) { return data->convert_to(new_format); } -//////////////////////////////////////////////////////////////////// -// Function: qpGeomMunger::munge_format_impl -// Access: Protected, Virtual -// Description: Given a source GeomVertexFormat, converts it if -// necessary to the appropriate format for rendering. -//////////////////////////////////////////////////////////////////// -CPT(qpGeomVertexFormat) qpGeomMunger:: -munge_format_impl(const qpGeomVertexFormat *orig) { - return orig; -} - //////////////////////////////////////////////////////////////////// // Function: qpGeomMunger::munge_geom_impl // Access: Protected, Virtual @@ -178,7 +178,8 @@ munge_format_impl(const qpGeomVertexFormat *orig) { //////////////////////////////////////////////////////////////////// void qpGeomMunger:: munge_geom_impl(CPT(qpGeom) &, CPT(qpGeomVertexData) &) { - // The default implementation does nothing. + // The default implementation does nothing (the work has already + // been done in munge_format_impl). } //////////////////////////////////////////////////////////////////// @@ -194,6 +195,19 @@ compare_to_impl(const qpGeomMunger *other) const { return 0; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomMunger::geom_compare_to_impl +// Access: Protected, Virtual +// Description: Called to compare two GeomMungers who are known to be +// of the same type, for an apples-to-apples comparison. +// This will never be called on two pointers of a +// different type. +//////////////////////////////////////////////////////////////////// +int qpGeomMunger:: +geom_compare_to_impl(const qpGeomMunger *other) const { + return compare_to_impl(other); +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomMunger::make_registry // Access: Private diff --git a/panda/src/gobj/qpgeomMunger.h b/panda/src/gobj/qpgeomMunger.h index ceb6403136..e4e60b9a40 100644 --- a/panda/src/gobj/qpgeomMunger.h +++ b/panda/src/gobj/qpgeomMunger.h @@ -74,14 +74,16 @@ public: public: INLINE int compare_to(const qpGeomMunger &other) const; + INLINE int geom_compare_to(const qpGeomMunger &other) const; protected: CPT(qpGeomVertexFormat) do_munge_format(const qpGeomVertexFormat *format); - CPT(qpGeomVertexData) do_munge_data(const qpGeomVertexData *data); virtual CPT(qpGeomVertexFormat) munge_format_impl(const qpGeomVertexFormat *orig); + virtual CPT(qpGeomVertexData) munge_data_impl(const qpGeomVertexData *data); virtual void munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &data); virtual int compare_to_impl(const qpGeomMunger *other) const; + virtual int geom_compare_to_impl(const qpGeomMunger *other) const; private: class Registry; @@ -91,6 +93,7 @@ private: void do_register(); void do_unregister(); +private: typedef pmap Formats; Formats _formats; diff --git a/panda/src/gobj/qpgeomVertexArrayFormat.cxx b/panda/src/gobj/qpgeomVertexArrayFormat.cxx index aef1b9f8d5..a7e8a43be3 100644 --- a/panda/src/gobj/qpgeomVertexArrayFormat.cxx +++ b/panda/src/gobj/qpgeomVertexArrayFormat.cxx @@ -188,8 +188,11 @@ qpGeomVertexArrayFormat:: // "vertex" or "normal"; you must specify where in each // record the table starts, and how many components // (dimensions) exist per vertex. +// +// The return value is the index number of the new data +// type. //////////////////////////////////////////////////////////////////// -void qpGeomVertexArrayFormat:: +int qpGeomVertexArrayFormat:: add_data_type(const InternalName *name, int num_components, qpGeomVertexDataType::NumericType numeric_type, int start) { if (start < 0) { @@ -200,8 +203,8 @@ add_data_type(const InternalName *name, int num_components, start = ((start + pad_to - 1) / pad_to) * pad_to; } - add_data_type(qpGeomVertexDataType(name, num_components, - numeric_type, start)); + return add_data_type(qpGeomVertexDataType(name, num_components, + numeric_type, start)); } //////////////////////////////////////////////////////////////////// @@ -216,10 +219,13 @@ add_data_type(const InternalName *name, int num_components, // Adding a data type with the same name as a previous // type, or that overlaps with one or more previous // types, quietly removes the previous type(s). +// +// The return value is the index number of the new data +// type. //////////////////////////////////////////////////////////////////// -void qpGeomVertexArrayFormat:: +int qpGeomVertexArrayFormat:: add_data_type(const qpGeomVertexDataType &data_type) { - nassertv(!_is_registered); + nassertr(!_is_registered, -1); // Make sure there isn't already a data type with this name. remove_data_type(data_type.get_name()); @@ -242,8 +248,11 @@ add_data_type(const qpGeomVertexDataType &data_type) { _data_types_unsorted = true; } + int new_index = (int)_data_types.size(); _data_types.push_back(new_data_type); _data_types_by_name.insert(DataTypesByName::value_type(new_data_type->get_name(), new_data_type)); + + return new_index; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/qpgeomVertexArrayFormat.h b/panda/src/gobj/qpgeomVertexArrayFormat.h index e3b1f98973..3c50ee3e1d 100644 --- a/panda/src/gobj/qpgeomVertexArrayFormat.h +++ b/panda/src/gobj/qpgeomVertexArrayFormat.h @@ -83,10 +83,10 @@ PUBLISHED: INLINE int get_total_bytes() const; INLINE int get_pad_to() const; - void add_data_type(const InternalName *name, int num_components, - qpGeomVertexDataType::NumericType numeric_type, - int start = -1); - void add_data_type(const qpGeomVertexDataType &data_type); + int add_data_type(const InternalName *name, int num_components, + qpGeomVertexDataType::NumericType numeric_type, + int start = -1); + int add_data_type(const qpGeomVertexDataType &data_type); void remove_data_type(const InternalName *name); void clear_data_types(); diff --git a/panda/src/gobj/qpgeomVertexCacheManager.I b/panda/src/gobj/qpgeomVertexCacheManager.I index 5dc5090b3b..9c615990a2 100644 --- a/panda/src/gobj/qpgeomVertexCacheManager.I +++ b/panda/src/gobj/qpgeomVertexCacheManager.I @@ -286,7 +286,10 @@ operator < (const qpGeomVertexCacheManager::Entry &other) const { if (_u._geom._source != other._u._geom._source) { return _u._geom._source < other._u._geom._source; } - return _u._geom._modifier < other._u._geom._modifier; + if (_u._geom._modifier != other._u._geom._modifier) { + return _u._geom._modifier->geom_compare_to(*other._u._geom._modifier) < 0; + } + return 0; } return false; diff --git a/panda/src/gobj/qpgeomVertexData.cxx b/panda/src/gobj/qpgeomVertexData.cxx index 7f77e65f2e..1eef7e17b4 100644 --- a/panda/src/gobj/qpgeomVertexData.cxx +++ b/panda/src/gobj/qpgeomVertexData.cxx @@ -17,6 +17,7 @@ //////////////////////////////////////////////////////////////////// #include "qpgeomVertexData.h" +#include "qpgeomVertexIterator.h" #include "pStatTimer.h" #include "bamReader.h" #include "bamWriter.h" @@ -24,7 +25,9 @@ TypeHandle qpGeomVertexData::_type_handle; -PStatCollector qpGeomVertexData::_munge_data_pcollector("Cull:Munge:Data"); +PStatCollector qpGeomVertexData::_convert_pcollector("Cull:Munge:Convert"); +PStatCollector qpGeomVertexData::_scale_color_pcollector("Cull:Munge:Scale color"); +PStatCollector qpGeomVertexData::_set_color_pcollector("Cull:Munge:Set color"); //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexData::Default Constructor @@ -219,7 +222,7 @@ convert_to(const qpGeomVertexFormat *new_format) const { gobj_cat.debug() << "Converting " << num_vertices << " vertices.\n"; } - PStatTimer timer(_munge_data_pcollector); + PStatTimer timer(_convert_pcollector); PT(qpGeomVertexData) new_data = new qpGeomVertexData(new_format, get_usage_hint()); @@ -287,6 +290,159 @@ convert_to(const qpGeomVertexFormat *new_format) const { return new_data; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::scale_color +// Access: Published +// Description: Returns a new GeomVertexData object with the color +// table replaced with a new color table that has been +// scaled by the indicated value. The new color table +// will be added as a new array; if the old color table +// was interleaved with a previous array, the previous +// array will not be repacked. +//////////////////////////////////////////////////////////////////// +CPT(qpGeomVertexData) qpGeomVertexData:: +scale_color(const LVecBase4f &color_scale, int num_components, + qpGeomVertexDataType::NumericType numeric_type) const { + int old_color_array = _format->get_array_with(InternalName::get_color()); + if (old_color_array == -1) { + // Oops, no color anyway. + return this; + } + + int num_vertices = get_num_vertices(); + + if (gobj_cat.is_debug()) { + gobj_cat.debug() + << "Scaling color for " << num_vertices << " vertices by " + << color_scale << ".\n"; + } + PStatTimer timer(_scale_color_pcollector); + + PT(qpGeomVertexData) new_data = replace_data_type + (InternalName::get_color(), num_components, numeric_type); + + // Now go through and apply the scale, copying it to the new data. + qpGeomVertexIterator from(this, InternalName::get_color()); + qpGeomVertexIterator to(new_data, InternalName::get_color()); + + for (int i = 0; i < num_vertices; i++) { + Colorf color = from.get_data4(); + to.set_data4(color[0] * color_scale[0], + color[1] * color_scale[1], + color[2] * color_scale[2], + color[3] * color_scale[3]); + } + + return new_data; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::set_color +// Access: Published +// Description: Returns a new GeomVertexData object with the color +// table replaced with a new color table for which each +// vertex has the indicated value. The new color table +// will be added as a new array; if the old color table +// was interleaved with a previous array, the previous +// array will not be repacked. +//////////////////////////////////////////////////////////////////// +CPT(qpGeomVertexData) qpGeomVertexData:: +set_color(const Colorf &color, int num_components, + qpGeomVertexDataType::NumericType numeric_type) const { + int num_vertices = get_num_vertices(); + + if (gobj_cat.is_debug()) { + gobj_cat.debug() + << "Setting color for " << num_vertices << " vertices to " + << color << ".\n"; + } + PStatTimer timer(_set_color_pcollector); + + PT(qpGeomVertexData) new_data = replace_data_type + (InternalName::get_color(), num_components, numeric_type); + + // Now go through and set the new color value. + qpGeomVertexIterator to(new_data, InternalName::get_color()); + + for (int i = 0; i < num_vertices; i++) { + to.set_data4(color); + } + + return new_data; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexData::replace_data_type +// Access: Published +// Description: Returns a new GeomVertexData object, suitable for +// modification, with the indicated data type replaced +// with a new table filled with undefined values. The +// new table will be added as a new array; if the old +// table was interleaved with a previous array, the +// previous array will not be repacked. +//////////////////////////////////////////////////////////////////// +PT(qpGeomVertexData) qpGeomVertexData:: +replace_data_type(const InternalName *name, int num_components, + qpGeomVertexDataType::NumericType numeric_type) const { + PT(qpGeomVertexFormat) new_format = new qpGeomVertexFormat(*_format); + + // Remove the old description of the type from the format. + bool removed_type_array = false; + int old_type_array = _format->get_array_with(name); + if (old_type_array != -1) { + qpGeomVertexArrayFormat *array_format = new_format->modify_array(old_type_array); + if (array_format->get_num_data_types() == 1) { + // Actually, this array didn't have any other data types, so + // just drop the whole array. + new_format->remove_array(old_type_array); + removed_type_array = true; + + } else { + // Remove the description for the type, but don't bother to + // repack the array. + array_format->remove_data_type(name); + } + } + + // Now define a new array to contain just the type. + PT(qpGeomVertexArrayFormat) type_array_format = + new qpGeomVertexArrayFormat(name, num_components, numeric_type); + int new_type_array = new_format->add_array(type_array_format); + + PT(qpGeomVertexData) new_data = + new qpGeomVertexData(qpGeomVertexFormat::register_format(new_format), + get_usage_hint()); + + int j = 0; + int num_arrays = get_num_arrays(); + for (int i = 0; i < num_arrays; ++i) { + if (i == old_type_array) { + if (!removed_type_array) { + // Pointer-copy the original array that includes the type + // (since it also includes other data). + new_data->set_array(j, get_array(i)); + ++j; + } + + } else { + // Just pointer-copy any arrays other than type. + new_data->set_array(j, get_array(i)); + ++j; + } + } + + nassertr(j == new_type_array, new_data); + + // For the new type array, we set up a temporary array that has + // room for the right number of vertices. + PT(qpGeomVertexArrayData) new_array = new qpGeomVertexArrayData + (new_format->get_array(j), get_usage_hint()); + new_array->set_num_vertices(get_num_vertices()); + new_data->set_array(j, new_array); + + return new_data; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexData::output // Access: Published diff --git a/panda/src/gobj/qpgeomVertexData.h b/panda/src/gobj/qpgeomVertexData.h index 351622df4e..f8d26e9f77 100644 --- a/panda/src/gobj/qpgeomVertexData.h +++ b/panda/src/gobj/qpgeomVertexData.h @@ -85,6 +85,16 @@ PUBLISHED: INLINE UpdateSeq get_modified() const; CPT(qpGeomVertexData) convert_to(const qpGeomVertexFormat *new_format) const; + CPT(qpGeomVertexData) + scale_color(const LVecBase4f &color_scale, int num_components, + qpGeomVertexDataType::NumericType numeric_type) const; + CPT(qpGeomVertexData) + set_color(const Colorf &color, int num_components, + qpGeomVertexDataType::NumericType numeric_type) const; + + PT(qpGeomVertexData) + replace_data_type(const InternalName *name, int num_components, + qpGeomVertexDataType::NumericType numeric_type) const; void output(ostream &out) const; void write(ostream &out, int indent_level = 0) const; @@ -135,7 +145,9 @@ private: private: bool do_set_num_vertices(int n, CDWriter &cdata); - static PStatCollector _munge_data_pcollector; + static PStatCollector _convert_pcollector; + static PStatCollector _scale_color_pcollector; + static PStatCollector _set_color_pcollector; public: static void register_with_read_factory(); diff --git a/panda/src/gobj/qpgeomVertexFormat.cxx b/panda/src/gobj/qpgeomVertexFormat.cxx index b933d27478..c460dff99b 100644 --- a/panda/src/gobj/qpgeomVertexFormat.cxx +++ b/panda/src/gobj/qpgeomVertexFormat.cxx @@ -138,12 +138,16 @@ remove_array(int array) { // Access: Published // Description: Adds the indicated array definition to the list of // arrays included within this vertex format definition. +// The return value is the index number of the new +// array. //////////////////////////////////////////////////////////////////// -void qpGeomVertexFormat:: +int qpGeomVertexFormat:: add_array(qpGeomVertexArrayFormat *array_format) { - nassertv(!_is_registered); + nassertr(!_is_registered, -1); + int new_array = (int)_arrays.size(); _arrays.push_back(array_format); + return new_array; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/qpgeomVertexFormat.h b/panda/src/gobj/qpgeomVertexFormat.h index f5b000aa4d..3e77e16ec9 100644 --- a/panda/src/gobj/qpgeomVertexFormat.h +++ b/panda/src/gobj/qpgeomVertexFormat.h @@ -71,7 +71,7 @@ PUBLISHED: qpGeomVertexArrayFormat *modify_array(int array); void set_array(int array, qpGeomVertexArrayFormat *format); void remove_array(int array); - void add_array(qpGeomVertexArrayFormat *array_format); + int add_array(qpGeomVertexArrayFormat *array_format); void clear_arrays(); int get_num_data_types() const; diff --git a/panda/src/gobj/qpgeomVertexIterator.I b/panda/src/gobj/qpgeomVertexIterator.I index 03ee9aab98..d3124179d3 100644 --- a/panda/src/gobj/qpgeomVertexIterator.I +++ b/panda/src/gobj/qpgeomVertexIterator.I @@ -26,6 +26,7 @@ INLINE qpGeomVertexIterator:: qpGeomVertexIterator(qpGeomVertexData *data) : _data(data), + _const_data(false), _array(0), _data_type(NULL), _start_vertex(0), @@ -44,6 +45,7 @@ qpGeomVertexIterator(qpGeomVertexData *data) : INLINE qpGeomVertexIterator:: qpGeomVertexIterator(qpGeomVertexData *data, const string &name) : _data(data), + _const_data(false), _array(0), _data_type(NULL), _start_vertex(0), @@ -63,6 +65,65 @@ qpGeomVertexIterator(qpGeomVertexData *data, const string &name) : INLINE qpGeomVertexIterator:: qpGeomVertexIterator(qpGeomVertexData *data, const InternalName *name) : _data(data), + _const_data(false), + _array(0), + _data_type(NULL), + _start_vertex(0), + _read_vertex(0), + _write_vertex(0) +{ + set_data_type(name); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexIterator::Constructor +// Access: Published +// Description: Constructs a new iterator to process the vertices of +// the indicated data object. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexIterator:: +qpGeomVertexIterator(const qpGeomVertexData *data) : + _data((qpGeomVertexData *)data), + _const_data(true), + _array(0), + _data_type(NULL), + _start_vertex(0), + _read_vertex(0), + _write_vertex(0) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexIterator::Constructor +// Access: Published +// Description: Constructs a new iterator to process the vertices of +// the indicated data object. This flavor creates the +// iterator specifically to process the named data type. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexIterator:: +qpGeomVertexIterator(const qpGeomVertexData *data, const string &name) : + _data((qpGeomVertexData *)data), + _const_data(true), + _array(0), + _data_type(NULL), + _start_vertex(0), + _read_vertex(0), + _write_vertex(0) +{ + set_data_type(name); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexIterator::Constructor +// Access: Published +// Description: Constructs a new iterator to process the vertices of +// the indicated data object. This flavor creates the +// iterator specifically to process the named data type. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexIterator:: +qpGeomVertexIterator(const qpGeomVertexData *data, const InternalName *name) : + _data((qpGeomVertexData *)data), + _const_data(true), _array(0), _data_type(NULL), _start_vertex(0), @@ -78,7 +139,7 @@ qpGeomVertexIterator(qpGeomVertexData *data, const InternalName *name) : // Description: Returns the current data object that the iterator is // processing. //////////////////////////////////////////////////////////////////// -INLINE qpGeomVertexData *qpGeomVertexIterator:: +INLINE const qpGeomVertexData *qpGeomVertexIterator:: get_data() const { return _data; } @@ -237,6 +298,7 @@ get_write_vertex() const { //////////////////////////////////////////////////////////////////// INLINE void qpGeomVertexIterator:: set_data1(float data) { + nassertv(!_const_data); _data->set_data(_array, _data_type, _write_vertex, &data, 1); ++_write_vertex; } @@ -260,6 +322,7 @@ set_data2(float x, float y) { //////////////////////////////////////////////////////////////////// INLINE void qpGeomVertexIterator:: set_data2(const LVecBase2f &data) { + nassertv(!_const_data); _data->set_data(_array, _data_type, _write_vertex, data.get_data(), 2); ++_write_vertex; } @@ -283,6 +346,7 @@ set_data3(float x, float y, float z) { //////////////////////////////////////////////////////////////////// INLINE void qpGeomVertexIterator:: set_data3(const LVecBase3f &data) { + nassertv(!_const_data); _data->set_data(_array, _data_type, _write_vertex, data.get_data(), 3); ++_write_vertex; } @@ -306,6 +370,7 @@ set_data4(float x, float y, float z, float w) { //////////////////////////////////////////////////////////////////// INLINE void qpGeomVertexIterator:: set_data4(const LVecBase4f &data) { + nassertv(!_const_data); _data->set_data(_array, _data_type, _write_vertex, data.get_data(), 4); ++_write_vertex; } diff --git a/panda/src/gobj/qpgeomVertexIterator.h b/panda/src/gobj/qpgeomVertexIterator.h index ed61e8f235..03444d5360 100644 --- a/panda/src/gobj/qpgeomVertexIterator.h +++ b/panda/src/gobj/qpgeomVertexIterator.h @@ -41,8 +41,13 @@ PUBLISHED: const string &name); INLINE qpGeomVertexIterator(qpGeomVertexData *data, const InternalName *name); + INLINE qpGeomVertexIterator(const qpGeomVertexData *data); + INLINE qpGeomVertexIterator(const qpGeomVertexData *data, + const string &name); + INLINE qpGeomVertexIterator(const qpGeomVertexData *data, + const InternalName *name); - INLINE qpGeomVertexData *get_data() const; + INLINE const qpGeomVertexData *get_data() const; INLINE void set_data_type(int data_type); INLINE void set_data_type(const string &name); @@ -73,6 +78,7 @@ PUBLISHED: private: PT(qpGeomVertexData) _data; + bool _const_data; int _array; const qpGeomVertexDataType *_data_type; diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index d3219c2730..74a5abe93f 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -184,7 +184,9 @@ public: virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc)=0; virtual void draw_sphere(GeomSphere *geom, GeomContext *gc)=0; - virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data)=0; + virtual bool begin_draw_primitives(const qpGeom *geom, + const qpGeomMunger *munger, + const qpGeomVertexData *vertex_data)=0; virtual void draw_triangles(const qpGeomTriangles *primitive)=0; virtual void draw_tristrips(const qpGeomTristrips *primitive)=0; virtual void draw_trifans(const qpGeomTrifans *primitive)=0; diff --git a/panda/src/pgraph/cullableObject.I b/panda/src/pgraph/cullableObject.I index 8abdacc9bd..23aad9dd03 100644 --- a/panda/src/pgraph/cullableObject.I +++ b/panda/src/pgraph/cullableObject.I @@ -124,7 +124,7 @@ munge_geom(GraphicsStateGuardianBase *gsg) { //////////////////////////////////////////////////////////////////// INLINE void CullableObject:: draw(GraphicsStateGuardianBase *gsg) { - _geom->draw(gsg, _munged_data); + _geom->draw(gsg, _munger, _munged_data); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/cullableObject.cxx b/panda/src/pgraph/cullableObject.cxx index 49f890154f..eaeb2f4b05 100644 --- a/panda/src/pgraph/cullableObject.cxx +++ b/panda/src/pgraph/cullableObject.cxx @@ -35,6 +35,7 @@ munge_geom(const qpGeomMunger *munger) { // Temporary test and dcast until the experimental Geom rewrite // becomes the actual Geom rewrite. if (_geom->is_exact_type(qpGeom::get_class_type())) { + _munger = munger; CPT(qpGeom) qpgeom = DCAST(qpGeom, _geom); qpgeom->munge_geom(munger, qpgeom, _munged_data); _geom = qpgeom; diff --git a/panda/src/pgraph/cullableObject.h b/panda/src/pgraph/cullableObject.h index eedd56db29..ffc6a32c92 100644 --- a/panda/src/pgraph/cullableObject.h +++ b/panda/src/pgraph/cullableObject.h @@ -74,6 +74,7 @@ PUBLISHED: public: CPT(Geom) _geom; + CPT(qpGeomMunger) _munger; CPT(qpGeomVertexData) _munged_data; CPT(RenderState) _state; CPT(TransformState) _transform;