From 0a6a6dcb3e29fb9711ca5ac53c55871d2c12c60c Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 2 Mar 2009 23:11:27 +0000 Subject: [PATCH] fix some sprite issues --- panda/src/gobj/config_gobj.cxx | 6 + panda/src/gobj/config_gobj.h | 1 + panda/src/pgraph/cullableObject.I | 19 ++++ panda/src/pgraph/cullableObject.cxx | 151 ++++++++++++++++---------- panda/src/pgraph/cullableObject.h | 13 ++- panda/src/pgraph/renderModeAttrib.cxx | 4 + 6 files changed, 133 insertions(+), 61 deletions(-) diff --git a/panda/src/gobj/config_gobj.cxx b/panda/src/gobj/config_gobj.cxx index 93fb99db73..13024e019e 100644 --- a/panda/src/gobj/config_gobj.cxx +++ b/panda/src/gobj/config_gobj.cxx @@ -191,6 +191,12 @@ ConfigVariableBool hardware_point_sprites "computed in software, even if the hardware claims it can " "support them directly.")); +ConfigVariableBool hardware_points +("hardware-points", true, + PRC_DESC("Set this true to allow the use of hardware extensions when " + "rendering large points. When false, large points (even if " + "untextured) will be simulated via quads computed in software.")); + ConfigVariableBool matrix_palette ("matrix-palette", false, PRC_DESC("Set this true to allow the use of the matrix palette when " diff --git a/panda/src/gobj/config_gobj.h b/panda/src/gobj/config_gobj.h index 93fce7a909..f35d3fed6a 100644 --- a/panda/src/gobj/config_gobj.h +++ b/panda/src/gobj/config_gobj.h @@ -62,6 +62,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_arrays; extern EXPCL_PANDA_GOBJ ConfigVariableBool display_lists; extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_animated_vertices; extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_point_sprites; +extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_points; extern EXPCL_PANDA_GOBJ ConfigVariableBool matrix_palette; extern EXPCL_PANDA_GOBJ ConfigVariableBool display_list_animation; extern EXPCL_PANDA_GOBJ ConfigVariableBool connect_triangle_strips; diff --git a/panda/src/pgraph/cullableObject.I b/panda/src/pgraph/cullableObject.I index ec8f4cab4d..397247a921 100644 --- a/panda/src/pgraph/cullableObject.I +++ b/panda/src/pgraph/cullableObject.I @@ -177,3 +177,22 @@ INLINE bool CullableObject::SortPoints:: operator () (unsigned short a, unsigned short b) const { return _array[a]._dist > _array[b]._dist; } + +//////////////////////////////////////////////////////////////////// +// Function: CullableObject::SourceFormat::operator < +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool CullableObject::SourceFormat:: +operator < (const CullableObject::SourceFormat &other) const { + if (_format != other._format) { + return _format < other._format; + } + if (_sprite_texcoord != other._sprite_texcoord) { + return (int)_sprite_texcoord < (int)other._sprite_texcoord; + } + if (_retransform_sprites != other._retransform_sprites) { + return (int)_retransform_sprites < (int)other._retransform_sprites; + } + return false; +} diff --git a/panda/src/pgraph/cullableObject.cxx b/panda/src/pgraph/cullableObject.cxx index 4760be99e3..c6b1b00d79 100644 --- a/panda/src/pgraph/cullableObject.cxx +++ b/panda/src/pgraph/cullableObject.cxx @@ -27,8 +27,10 @@ #include "geomVertexReader.h" #include "geomTriangles.h" #include "light.h" +#include "lightMutexHolder.h" CullableObject::FormatMap CullableObject::_format_map; +LightMutex CullableObject::_format_lock; PStatCollector CullableObject::_munge_geom_pcollector("*:Munge:Geom"); PStatCollector CullableObject::_munge_sprites_pcollector("*:Munge:Sprites"); @@ -83,6 +85,11 @@ munge_geom(GraphicsStateGuardianBase *gsg, // supports them. gsg_bits &= ~(Geom::GR_point_perspective | Geom::GR_point_sprite); } + if (!hardware_points) { + // If hardware-points is off, we don't all any kind of point + // rendering, except plain old one-pixel points; + gsg_bits &= ~(Geom::GR_point_bits & ~Geom::GR_point); + } int unsupported_bits = geom_rendering & ~gsg_bits; if ((unsupported_bits & Geom::GR_point_bits) != 0) { @@ -205,29 +212,35 @@ output(ostream &out) const { //////////////////////////////////////////////////////////////////// bool CullableObject:: munge_points_to_quads(const CullTraverser *traverser, bool force) { - if (!force && !_munged_data->request_resident()) { + Thread *current_thread = traverser->get_current_thread(); + + // Better get the animated vertices, in case we're showing sprites + // on an animated model for some reason. + CPT(GeomVertexData) source_data = + _munged_data->animate_vertices(force, current_thread); + + if (!force && !source_data->request_resident()) { return false; } - Thread *current_thread = traverser->get_current_thread(); PStatTimer timer(_munge_sprites_pcollector, current_thread); - _sw_sprites_pcollector.add_level(_munged_data->get_num_rows()); + _sw_sprites_pcollector.add_level(source_data->get_num_rows()); GraphicsStateGuardianBase *gsg = traverser->get_gsg(); - GeomVertexReader vertex(_munged_data, InternalName::get_vertex(), + GeomVertexReader vertex(source_data, InternalName::get_vertex(), current_thread); - GeomVertexReader normal(_munged_data, InternalName::get_normal(), + GeomVertexReader normal(source_data, InternalName::get_normal(), current_thread); - GeomVertexReader color(_munged_data, InternalName::get_color(), + GeomVertexReader color(source_data, InternalName::get_color(), current_thread); - GeomVertexReader texcoord(_munged_data, InternalName::get_texcoord(), + GeomVertexReader texcoord(source_data, InternalName::get_texcoord(), current_thread); - GeomVertexReader rotate(_munged_data, InternalName::get_rotate(), + GeomVertexReader rotate(source_data, InternalName::get_rotate(), current_thread); - GeomVertexReader size(_munged_data, InternalName::get_size(), + GeomVertexReader size(source_data, InternalName::get_size(), current_thread); - GeomVertexReader aspect_ratio(_munged_data, InternalName::get_aspect_ratio(), + GeomVertexReader aspect_ratio(source_data, InternalName::get_aspect_ratio(), current_thread); bool has_normal = (normal.has_column()); @@ -244,7 +257,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { sprite_texcoord = true; // Turn off the TexGenAttrib, since we don't want it now. - _state = _state->add_attrib(tex_gen->remove_stage(TextureStage::get_default())); + _state = _state->set_attrib(tex_gen->remove_stage(TextureStage::get_default())); } } @@ -258,61 +271,66 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { if (render_mode->get_mode() != RenderModeAttrib::M_filled_flat) { // Render the new polygons with M_filled_flat, for a slight // performance advantage when software rendering. - _state = _state->add_attrib(RenderModeAttrib::make(RenderModeAttrib::M_filled_flat)); + _state = _state->set_attrib(RenderModeAttrib::make(RenderModeAttrib::M_filled_flat)); } } // Get the vertex format of the newly created geometry. CPT(GeomVertexFormat) new_format; - FormatMap::iterator fmi = _format_map.find(_munged_data->get_format()); - if (fmi != _format_map.end()) { - new_format = (*fmi).second; - } else { - // We have to construct the format now. - PT(GeomVertexArrayFormat) new_array_format; - if (retransform_sprites) { - // With retransform_sprites in effect, we will be sending ordinary - // 3-D points to the graphics API. - new_array_format = - new GeomVertexArrayFormat(InternalName::get_vertex(), 3, - Geom::NT_float32, - Geom::C_point); + { + LightMutexHolder holder(_format_lock); + SourceFormat sformat(source_data->get_format(), sprite_texcoord); + FormatMap::iterator fmi = _format_map.find(sformat); + if (fmi != _format_map.end()) { + new_format = (*fmi).second; + } else { - // Without retransform_sprites, we will be sending 4-component - // clip-space points. - new_array_format = - new GeomVertexArrayFormat(InternalName::get_vertex(), 4, - Geom::NT_float32, - Geom::C_clip_point); + // We have to construct the format now. + PT(GeomVertexArrayFormat) new_array_format; + if (sformat._retransform_sprites) { + // With retransform_sprites in effect, we will be sending ordinary + // 3-D points to the graphics API. + new_array_format = + new GeomVertexArrayFormat(InternalName::get_vertex(), 3, + Geom::NT_float32, + Geom::C_point); + } else { + // Without retransform_sprites, we will be sending 4-component + // clip-space points. + new_array_format = + new GeomVertexArrayFormat(InternalName::get_vertex(), 4, + Geom::NT_float32, + Geom::C_clip_point); + } + if (has_normal) { + const GeomVertexColumn *c = normal.get_column(); + new_array_format->add_column + (InternalName::get_normal(), c->get_num_components(), + c->get_numeric_type(), c->get_contents()); + } + if (has_color) { + const GeomVertexColumn *c = color.get_column(); + new_array_format->add_column + (InternalName::get_color(), c->get_num_components(), + c->get_numeric_type(), c->get_contents()); + } + if (sprite_texcoord) { + new_array_format->add_column + (InternalName::get_texcoord(), 2, + Geom::NT_float32, + Geom::C_texcoord); + + } else if (has_texcoord) { + const GeomVertexColumn *c = texcoord.get_column(); + new_array_format->add_column + (InternalName::get_texcoord(), c->get_num_components(), + c->get_numeric_type(), c->get_contents()); + } + + new_format = GeomVertexFormat::register_format(new_array_format); + _format_map[sformat] = new_format; } - if (has_normal) { - const GeomVertexColumn *c = normal.get_column(); - new_array_format->add_column - (InternalName::get_normal(), c->get_num_components(), - c->get_numeric_type(), c->get_contents()); - } - if (has_color) { - const GeomVertexColumn *c = color.get_column(); - new_array_format->add_column - (InternalName::get_color(), c->get_num_components(), - c->get_numeric_type(), c->get_contents()); - } - if (sprite_texcoord) { - new_array_format->add_column - (InternalName::get_texcoord(), 2, - Geom::NT_float32, - Geom::C_texcoord); - - } else if (has_texcoord) { - const GeomVertexColumn *c = texcoord.get_column(); - new_array_format->add_column - (InternalName::get_texcoord(), c->get_num_components(), - c->get_numeric_type(), c->get_contents()); - } - - new_format = GeomVertexFormat::register_format(new_array_format); - _format_map[_munged_data->get_format()] = new_format; } const LMatrix4f &modelview = _modelview_transform->get_mat(); @@ -341,11 +359,11 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) { // We always convert all the vertices, assuming all the vertices // will referenced by GeomPrimitives, because we want to optimize // for the most common case. - int orig_verts = _munged_data->get_num_rows(); + int orig_verts = source_data->get_num_rows(); int new_verts = 4 * orig_verts; // each vertex becomes four. PT(GeomVertexData) new_data = new GeomVertexData - (_munged_data->get_name(), new_format, Geom::UH_stream); + (source_data->get_name(), new_format, Geom::UH_stream); new_data->unclean_set_num_rows(new_verts); GeomVertexWriter new_vertex(new_data, InternalName::get_vertex()); @@ -730,3 +748,16 @@ get_flash_hardware_state() { return flash_hardware_state; } + +//////////////////////////////////////////////////////////////////// +// Function: CullableObject::SourceFormat::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +CullableObject::SourceFormat:: +SourceFormat(const GeomVertexFormat *format, bool sprite_texcoord) : + _format(format), + _sprite_texcoord(sprite_texcoord) +{ + _retransform_sprites = retransform_sprites; +} diff --git a/panda/src/pgraph/cullableObject.h b/panda/src/pgraph/cullableObject.h index 172ac82706..6a68f08193 100644 --- a/panda/src/pgraph/cullableObject.h +++ b/panda/src/pgraph/cullableObject.h @@ -29,6 +29,7 @@ #include "pStatCollector.h" #include "deletedChain.h" #include "graphicsStateGuardianBase.h" +#include "lightMutex.h" class CullTraverser; @@ -106,8 +107,18 @@ private: }; // This is a cache of converted vertex formats. - typedef pmap FormatMap; + class SourceFormat { + public: + SourceFormat(const GeomVertexFormat *format, bool sprite_texcoord); + INLINE bool operator < (const SourceFormat &other) const; + + CPT(GeomVertexFormat) _format; + bool _sprite_texcoord; + bool _retransform_sprites; + }; + typedef pmap FormatMap; static FormatMap _format_map; + static LightMutex _format_lock; static PStatCollector _munge_geom_pcollector; static PStatCollector _munge_sprites_pcollector; diff --git a/panda/src/pgraph/renderModeAttrib.cxx b/panda/src/pgraph/renderModeAttrib.cxx index 38bd658a93..54123e00a1 100644 --- a/panda/src/pgraph/renderModeAttrib.cxx +++ b/panda/src/pgraph/renderModeAttrib.cxx @@ -93,6 +93,10 @@ output(ostream &out) const { break; } + if (get_thickness() != 1.0f) { + out << ", thick " << get_thickness(); + } + if (get_perspective()) { out << ", perspective"; }