more fixes to point rendering

This commit is contained in:
David Rose 2009-03-03 23:15:10 +00:00
parent 9dad4e33d2
commit 7051a28f8e
9 changed files with 145 additions and 15 deletions

View File

@ -197,6 +197,14 @@ ConfigVariableBool hardware_points
"rendering large points. When false, large points (even if " "rendering large points. When false, large points (even if "
"untextured) will be simulated via quads computed in software.")); "untextured) will be simulated via quads computed in software."));
ConfigVariableBool singular_points
("singular-points", true,
PRC_DESC("Set this true to insist that when RenderModeAttrib::M_points is "
"used, each point appears only once in the result, even if "
"the vertex is referenced multiple times. This is particularly "
"important when rendering points from a triangle mesh and you "
"don't want the points to appear repeatedly."));
ConfigVariableBool matrix_palette ConfigVariableBool matrix_palette
("matrix-palette", false, ("matrix-palette", false,
PRC_DESC("Set this true to allow the use of the matrix palette when " PRC_DESC("Set this true to allow the use of the matrix palette when "

View File

@ -63,6 +63,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableBool display_lists;
extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_animated_vertices; extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_animated_vertices;
extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_point_sprites; extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_point_sprites;
extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_points; extern EXPCL_PANDA_GOBJ ConfigVariableBool hardware_points;
extern EXPCL_PANDA_GOBJ ConfigVariableBool singular_points;
extern EXPCL_PANDA_GOBJ ConfigVariableBool matrix_palette; extern EXPCL_PANDA_GOBJ ConfigVariableBool matrix_palette;
extern EXPCL_PANDA_GOBJ ConfigVariableBool display_list_animation; extern EXPCL_PANDA_GOBJ ConfigVariableBool display_list_animation;
extern EXPCL_PANDA_GOBJ ConfigVariableBool connect_triangle_strips; extern EXPCL_PANDA_GOBJ ConfigVariableBool connect_triangle_strips;

View File

@ -230,6 +230,19 @@ unify(int max_indices, bool preserve_order) const {
return new_geom; return new_geom;
} }
////////////////////////////////////////////////////////////////////
// Function: Geom::make_points
// Access: Published
// Description: Returns a new Geom with points at all the vertices.
// See GeomPrimitive::make_points().
////////////////////////////////////////////////////////////////////
INLINE PT(Geom) Geom::
make_points() const {
PT(Geom) new_geom = make_copy();
new_geom->make_points_in_place();
return new_geom;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Geom::get_modified // Function: Geom::get_modified
// Access: Published // Access: Published

View File

@ -737,6 +737,44 @@ unify_in_place(int max_indices, bool preserve_order) {
reset_geom_rendering(cdata); reset_geom_rendering(cdata);
} }
////////////////////////////////////////////////////////////////////
// Function: Geom::make_points_in_place
// Access: Published
// Description: Replaces the GeomPrimitives within this Geom with
// corresponding GeomPoints. See
// GeomPrimitive::make_points().
//
// Don't call this in a downstream thread unless you
// don't mind it blowing away other changes you might
// have recently made in an upstream thread.
////////////////////////////////////////////////////////////////////
void Geom::
make_points_in_place() {
Thread *current_thread = Thread::get_current_thread();
CDWriter cdata(_cycler, true, current_thread);
#ifndef NDEBUG
bool all_is_valid = true;
#endif
Primitives::iterator pi;
for (pi = cdata->_primitives.begin(); pi != cdata->_primitives.end(); ++pi) {
CPT(GeomPrimitive) new_prim = (*pi).get_read_pointer()->make_points();
(*pi) = (GeomPrimitive *)new_prim.p();
#ifndef NDEBUG
if (!new_prim->check_valid(cdata->_data.get_read_pointer())) {
all_is_valid = false;
}
#endif
}
cdata->_modified = Geom::get_next_modified();
reset_geom_rendering(cdata);
clear_cache_stage(current_thread);
nassertv(all_is_valid);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: Geom::copy_primitives_from // Function: Geom::copy_primitives_from

View File

@ -101,12 +101,14 @@ PUBLISHED:
INLINE PT(Geom) reverse() const; INLINE PT(Geom) reverse() const;
INLINE PT(Geom) rotate() const; INLINE PT(Geom) rotate() const;
INLINE PT(Geom) unify(int max_indices, bool preserve_order) const; INLINE PT(Geom) unify(int max_indices, bool preserve_order) const;
INLINE PT(Geom) make_points() const;
void decompose_in_place(); void decompose_in_place();
void doubleside_in_place(); void doubleside_in_place();
void reverse_in_place(); void reverse_in_place();
void rotate_in_place(); void rotate_in_place();
void unify_in_place(int max_indices, bool preserve_order); void unify_in_place(int max_indices, bool preserve_order);
void make_points_in_place();
virtual bool copy_primitives_from(const Geom *other); virtual bool copy_primitives_from(const Geom *other);

View File

@ -129,7 +129,7 @@ get_first_vertex() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_num_vertices // Function: GeomPrimitive::get_num_vertices
// Access: Published // Access: Published
// Description: Returns the number of vertex vertices used by all the // Description: Returns the number of vertices used by all the
// primitives in this object. // primitives in this object.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitive:: INLINE int GeomPrimitive::

View File

@ -20,6 +20,7 @@
#include "geomVertexReader.h" #include "geomVertexReader.h"
#include "geomVertexWriter.h" #include "geomVertexWriter.h"
#include "geomVertexRewriter.h" #include "geomVertexRewriter.h"
#include "geomPoints.h"
#include "preparedGraphicsObjects.h" #include "preparedGraphicsObjects.h"
#include "internalName.h" #include "internalName.h"
#include "bamReader.h" #include "bamReader.h"
@ -831,6 +832,59 @@ match_shade_model(GeomPrimitive::ShadeModel shade_model) const {
return NULL; return NULL;
} }
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::make_points
// Access: Published
// Description: Returns a new GeomPoints primitive that represents
// each of the vertices in the original primitive,
// rendered exactly once. If the original primitive is
// already a GeomPoints primitive, returns the original
// primitive unchanged.
////////////////////////////////////////////////////////////////////
CPT(GeomPrimitive) GeomPrimitive::
make_points() const {
if (is_exact_type(GeomPoints::get_class_type())) {
return this;
}
// First, get a list of all of the vertices referenced by the
// original primitive.
BitArray bits;
int num_vertices = get_num_vertices();
if (is_indexed()) {
CPT(GeomVertexArrayData) vertices = get_vertices();
GeomVertexReader index(vertices, 0);
for (int vi = 0; vi < num_vertices; ++vi) {
nassertr(!index.is_at_end(), NULL);
bits.set_bit(index.get_data1i());
}
} else {
int first_vertex = get_first_vertex();
bits.set_range(first_vertex, num_vertices);
}
// Now construct a new index array with just those bits.
PT(GeomVertexArrayData) new_vertices = make_index_data();
GeomVertexWriter new_index(new_vertices, 0);
int p = bits.get_lowest_on_bit();
while (p != -1) {
while (bits.get_bit(p)) {
new_index.add_data1i(p);
++p;
}
int q = bits.get_next_higher_different_bit(p);
if (q == p) {
break;
}
p = q;
}
PT(GeomPrimitive) points = new GeomPoints(UH_dynamic);
points->set_vertices(new_vertices);
return points;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_num_bytes // Function: GeomPrimitive::get_num_bytes
// Access: Published // Access: Published

View File

@ -130,6 +130,7 @@ PUBLISHED:
CPT(GeomPrimitive) doubleside() const; CPT(GeomPrimitive) doubleside() const;
CPT(GeomPrimitive) reverse() const; CPT(GeomPrimitive) reverse() const;
CPT(GeomPrimitive) match_shade_model(ShadeModel shade_model) const; CPT(GeomPrimitive) match_shade_model(ShadeModel shade_model) const;
CPT(GeomPrimitive) make_points() const;
int get_num_bytes() const; int get_num_bytes() const;
INLINE int get_data_size_bytes() const; INLINE int get_data_size_bytes() const;

View File

@ -62,6 +62,9 @@ munge_geom(GraphicsStateGuardianBase *gsg,
if (_geom != (Geom *)NULL) { if (_geom != (Geom *)NULL) {
_munger = munger; _munger = munger;
int geom_rendering;
{
GeomPipelineReader geom_reader(_geom, current_thread); GeomPipelineReader geom_reader(_geom, current_thread);
_munged_data = geom_reader.get_vertex_data(); _munged_data = geom_reader.get_vertex_data();
@ -73,10 +76,20 @@ munge_geom(GraphicsStateGuardianBase *gsg,
} }
#endif // _DEBUG #endif // _DEBUG
int geom_rendering = geom_reader.get_geom_rendering(); geom_rendering = geom_reader.get_geom_rendering();
geom_rendering = _state->get_geom_rendering(geom_rendering); geom_rendering = _state->get_geom_rendering(geom_rendering);
geom_rendering = _modelview_transform->get_geom_rendering(geom_rendering); geom_rendering = _modelview_transform->get_geom_rendering(geom_rendering);
if (geom_rendering & Geom::GR_point_bits) {
if (geom_reader.get_primitive_type() != Geom::PT_points) {
if (singular_points) {
// Isolate the points so there's no unneeded overlap.
_geom = _geom->make_points();
}
}
}
}
GraphicsStateGuardianBase *gsg = traverser->get_gsg(); GraphicsStateGuardianBase *gsg = traverser->get_gsg();
int gsg_bits = gsg->get_supported_geom_rendering(); int gsg_bits = gsg->get_supported_geom_rendering();
if (!hardware_point_sprites) { if (!hardware_point_sprites) {
@ -356,9 +369,9 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
inv_render_transform.invert_from(render_transform); inv_render_transform.invert_from(render_transform);
// Now convert all of the vertices in the GeomVertexData to quads. // Now convert all of the vertices in the GeomVertexData to quads.
// We always convert all the vertices, assuming all the vertices // We always convert all the vertices, assuming all the vertices are
// will referenced by GeomPrimitives, because we want to optimize // referenced by GeomPrimitives, because we want to optimize for the
// for the most common case. // most common case.
int orig_verts = source_data->get_num_rows(); int orig_verts = source_data->get_num_rows();
int new_verts = 4 * orig_verts; // each vertex becomes four. int new_verts = 4 * orig_verts; // each vertex becomes four.