Fix issues with point rendering, both software and hardware.

This commit is contained in:
rdb 2014-10-11 01:28:32 +00:00
parent 3ed7ae0bd9
commit ab8ebe6e30
6 changed files with 116 additions and 55 deletions

View File

@ -538,7 +538,7 @@ reset() {
}
}
if (_supports_point_parameters) {
_supported_geom_rendering |= Geom::GR_point_perspective;
_supported_geom_rendering |= Geom::GR_point_perspective | Geom::GR_point_scale;
} else {
_glPointParameterfv = null_glPointParameterfv;
}
@ -2764,7 +2764,7 @@ end_frame(Thread *current_thread) {
// And deleted queries, too, unless we're using query timers
// in which case we'll need to reuse lots of them.
if (!_timer_queries_active && !_deleted_queries.empty()) {
if (!get_timer_queries_active() && !_deleted_queries.empty()) {
if (GLCAT.is_spam()) {
DeletedNames::iterator dqi;
for (dqi = _deleted_queries.begin();
@ -11335,6 +11335,7 @@ do_point_size() {
// matrix.
LVector3 height(0.0f, _point_size, 1.0f);
height = height * _projection_mat->get_mat();
height = height * _internal_transform->get_scale()[1];
PN_stdfloat s = height[1] * _viewport_height / _point_size;
if (_current_lens->is_orthographic()) {

View File

@ -429,6 +429,17 @@ add_vertices(int v1, int v2, int v3, int v4) {
add_vertex(v4);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_index_format
// Access: Public
// Description: Returns a registered format appropriate for using to
// store the index table.
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayFormat *GeomPrimitive::
get_index_format() const {
return get_index_format(get_index_type());
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::make_index_data
// Access: Public
@ -439,6 +450,22 @@ make_index_data() const {
return new GeomVertexArrayData(get_index_format(), get_usage_hint());
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::make_index_format
// Access: Private, Static
// Description: Returns a registered format appropriate for using to
// store the index table.
////////////////////////////////////////////////////////////////////
INLINE CPT(GeomVertexArrayFormat) GeomPrimitive::
make_index_format(NumericType index_type) {
PT(GeomVertexArrayFormat) format = new GeomVertexArrayFormat;
// It's important that the index format *not* respect the global
// setting of vertex-column-alignment. It needs to be tightly
// packed, so we specify an explict column_alignment of 1.
format->add_column(InternalName::get_index(), 1, index_type, C_index, 0, 1);
return GeomVertexArrayFormat::register_format(format);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::CData::Constructor
// Access: Public

View File

@ -1233,6 +1233,11 @@ set_vertices(const GeomVertexArrayData *vertices, int num_vertices) {
cdata->_vertices = (GeomVertexArrayData *)vertices;
cdata->_num_vertices = num_vertices;
// Validate the format and make sure to copy its numeric type.
const GeomVertexArrayFormat *format = vertices->get_array_format();
nassertv(format->get_num_columns() == 1);
cdata->_index_type = format->get_column(0)->get_numeric_type();
cdata->_modified = Geom::get_next_modified();
cdata->_got_minmax = false;
}
@ -1564,18 +1569,41 @@ release_all() {
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_index_format
// Access: Public
// Description: Returns a registered format appropriate for using to
// store the index table.
// Access: Public, Static
// Description: Returns a registered GeomVertexArrayFormat of the
// indicated unsigned integer numeric type for storing
// index values.
////////////////////////////////////////////////////////////////////
CPT(GeomVertexArrayFormat) GeomPrimitive::
get_index_format() const {
PT(GeomVertexArrayFormat) format = new GeomVertexArrayFormat;
// It's important that the index format *not* respect the global
// setting of vertex-column-alignment. It needs to be tightly
// packed, so we specify an explict column_alignment of 1.
format->add_column(InternalName::get_index(), 1, get_index_type(), C_index, 0, 1);
return GeomVertexArrayFormat::register_format(format);
const GeomVertexArrayFormat *GeomPrimitive::
get_index_format(NumericType index_type) {
switch (index_type) {
case NT_uint8:
{
static CPT(GeomVertexArrayFormat) cformat = NULL;
if (cformat == NULL) {
cformat = make_index_format(NT_uint8);
}
return cformat;
}
case NT_uint16:
{
static CPT(GeomVertexArrayFormat) cformat = NULL;
if (cformat == NULL) {
cformat = make_index_format(NT_uint16);
}
return cformat;
}
case NT_uint32:
{
static CPT(GeomVertexArrayFormat) cformat = NULL;
if (cformat == NULL) {
cformat = make_index_format(NT_uint32);
}
return cformat;
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////

View File

@ -185,15 +185,18 @@ public:
void prepare(PreparedGraphicsObjects *prepared_objects);
bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
IndexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
IndexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
GraphicsStateGuardianBase *gsg);
bool release(PreparedGraphicsObjects *prepared_objects);
int release_all();
CPT(GeomVertexArrayFormat) get_index_format() const;
static const GeomVertexArrayFormat *get_index_format(NumericType index_type);
INLINE const GeomVertexArrayFormat *get_index_format() const;
INLINE PT(GeomVertexArrayData) make_index_data() const;
private:
static CPT(GeomVertexArrayFormat) make_index_format(NumericType index_type);
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
static int get_highest_index_value(NumericType index_type);
static int get_strip_cut_index(NumericType index_type);
@ -204,7 +207,7 @@ public:
bool force) const=0;
void calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point,
bool &found_any,
bool &found_any,
const GeomVertexData *vertex_data,
bool got_mat, const LMatrix4 &mat,
const InternalName *column_name,
@ -216,7 +219,7 @@ protected:
virtual CPT(GeomPrimitive) doubleside_impl() const;
virtual CPT(GeomPrimitive) reverse_impl() const;
virtual bool requires_unused_vertices() const;
virtual void append_unused_vertices(GeomVertexArrayData *vertices,
virtual void append_unused_vertices(GeomVertexArrayData *vertices,
int vertex);
private:

View File

@ -76,11 +76,11 @@ munge_geom(GraphicsStateGuardianBase *gsg,
nassertr(geom_reader.check_valid(&data_reader), false);
}
#endif // _DEBUG
geom_rendering = geom_reader.get_geom_rendering();
geom_rendering = _state->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) {
@ -90,7 +90,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
}
}
}
GraphicsStateGuardianBase *gsg = traverser->get_gsg();
int gsg_bits = gsg->get_supported_geom_rendering();
if (!hardware_point_sprites) {
@ -113,7 +113,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
// _munged_data, and might also replace _state.
if (pgraph_cat.is_spam()) {
pgraph_cat.spam()
<< "munge_points_to_quads() for geometry with bits: "
<< "munge_points_to_quads() for geometry with bits: "
<< hex << geom_rendering << ", unsupported: "
<< (unsupported_bits & Geom::GR_point_bits) << dec << "\n";
}
@ -128,7 +128,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
// If we have to compute the light vector, we have to animate
// the vertices in the CPU--and we have to do it before we call
// munge_geom(), which might lose the tangent and binormal.
CPT(GeomVertexData) animated_vertices =
CPT(GeomVertexData) animated_vertices =
_munged_data->animate_vertices(force, current_thread);
if (animated_vertices != _munged_data) {
cpu_animated = true;
@ -154,7 +154,7 @@ munge_geom(GraphicsStateGuardianBase *gsg,
// has been munged--that is, we couldn't arrange to handle the
// animation in hardware--then we have to calculate that
// animation now.
CPT(GeomVertexData) animated_vertices =
CPT(GeomVertexData) animated_vertices =
_munged_data->animate_vertices(force, current_thread);
if (animated_vertices != _munged_data) {
cpu_animated = true;
@ -238,7 +238,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
// Better get the animated vertices, in case we're showing sprites
// on an animated model for some reason.
CPT(GeomVertexData) source_data =
CPT(GeomVertexData) source_data =
_munged_data->animate_vertices(force, current_thread);
if (!force && !source_data->request_resident()) {
@ -306,22 +306,22 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
FormatMap::iterator fmi = _format_map.find(sformat);
if (fmi != _format_map.end()) {
new_format = (*fmi).second;
} else {
// 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,
new_array_format =
new GeomVertexArrayFormat(InternalName::get_vertex(), 3,
Geom::NT_stdfloat,
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,
new_array_format =
new GeomVertexArrayFormat(InternalName::get_vertex(), 4,
Geom::NT_stdfloat,
Geom::C_clip_point);
}
@ -342,14 +342,14 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
(InternalName::get_texcoord(), 2,
Geom::NT_stdfloat,
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;
}
@ -406,7 +406,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
LPoint3 eye = modelview.xform_point(vertex.get_data3());
points[vi]._eye = eye;
points[vi]._dist = gsg->compute_distance_to(points[vi]._eye);
// The point in clip coordinates.
LPoint4 p4 = LPoint4(eye[0], eye[1], eye[2], 1.0f) * projection;
@ -431,7 +431,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
scale_y /= gsg->compute_distance_to(eye);
}
}
// Also factor in the homogeneous scale for being in clip
// coordinates still.
scale_y *= p4[3];
@ -445,7 +445,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
LPoint2 c0(scale_x, scale_y);
LPoint2 c1(-scale_x, scale_y);
if (has_rotate) {
if (has_rotate) {
// If we have a rotate factor, apply it to those two corners.
PN_stdfloat r = rotate.get_data1f();
LMatrix3 mat = LMatrix3::rotate_mat(r);
@ -459,7 +459,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
PN_stdfloat ry = 1.0f / viewport_height;
c0.set(c0[0] * rx, c0[1] * ry);
c1.set(c1[0] * rx, c1[1] * ry);
if (retransform_sprites) {
// With retransform_sprites in effect, we must reconvert the
// resulting quad back into the original 3-D space.
@ -467,7 +467,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] + c1[0], p4[1] + c1[1], p4[2], p4[3])));
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3])));
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3])));
if (has_normal) {
const LNormal &c = normal.get_data3();
new_normal.set_data3(c);
@ -475,7 +475,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
new_normal.set_data3(c);
new_normal.set_data3(c);
}
} else {
// Without retransform_sprites, we can simply load the
// clip-space coordinates.
@ -483,7 +483,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
new_vertex.set_data4(p4[0] + c1[0], p4[1] + c1[1], p4[2], p4[3]);
new_vertex.set_data4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3]);
new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]);
if (has_normal) {
LNormal c = render_transform.xform_vec(normal.get_data3());
new_normal.set_data3(c);
@ -519,18 +519,20 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
nassertr(new_data->get_num_rows() == new_verts, false);
}
PT(Geom) new_geom = new Geom(new_data);
// Create an appropriate GeomVertexArrayFormat for the primitive
// index.
static CPT(GeomVertexArrayFormat) new_prim_format;
if (new_prim_format == (GeomVertexArrayFormat *)NULL) {
new_prim_format =
GeomVertexArrayFormat::register_format
(new GeomVertexArrayFormat(InternalName::get_index(), 1,
GeomEnums::NT_uint16, GeomEnums::C_index));
// Determine the format we should use to store the indices.
const GeomVertexArrayFormat *new_prim_format = NULL;
if (new_verts < 0xff) {
new_prim_format = GeomPrimitive::get_index_format(GeomEnums::NT_uint8);
} else if (new_verts < 0xffff) {
new_prim_format = GeomPrimitive::get_index_format(GeomEnums::NT_uint16);
} else {
new_prim_format = GeomPrimitive::get_index_format(GeomEnums::NT_uint32);
}
PT(Geom) new_geom = new Geom(new_data);
// Replace each primitive in the Geom (it's presumably a GeomPoints
// primitive, although it might be some other kind of primitive if
// we got here because RenderModeAttrib::M_point is enabled) with a
@ -573,11 +575,11 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
vertices[i] = v;
}
}
// Now sort the points in order from back-to-front so they will
// render properly with transparency, at least with each other.
sort(vertices, vertices_end, SortPoints(points));
// Go through the points, now in sorted order, and generate a pair
// of triangles for each one. We generate indexed triangles
// instead of two-triangle strips, since this seems to be
@ -587,7 +589,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
PT(GeomPrimitive) new_primitive = new GeomTriangles(Geom::UH_stream);
int new_prim_verts = 6 * num_vertices; // two triangles per point.
PT(GeomVertexArrayData) new_index
PT(GeomVertexArrayData) new_index
= new GeomVertexArrayData(new_prim_format, GeomEnums::UH_stream);
new_index->unclean_set_num_rows(new_prim_verts);
@ -667,14 +669,14 @@ munge_texcoord_light_vector(const CullTraverser *traverser, bool force) {
string source_name = tex_gen->get_source_name(stage);
Light *light_obj = light.node()->as_light();
nassertr(light_obj != (Light *)NULL, false);
// Determine the names of the tangent and binormal columns
// associated with the stage's texcoord name.
PT(InternalName) tangent_name = InternalName::get_tangent_name(source_name);
PT(InternalName) binormal_name = InternalName::get_binormal_name(source_name);
PT(InternalName) texcoord_name = stage->get_texcoord_name();
if (_munged_data->has_column(tangent_name) &&
_munged_data->has_column(binormal_name)) {

View File

@ -2322,7 +2322,7 @@ do_calc_components() {
_hpr.set(0.0f, 0.0f, 0.0f);
_quat = LQuaternion::ident_quat();
_pos.set(0.0f, 0.0f, 0.0f);
_flags |= F_has_components | F_components_known | F_hpr_known | F_quat_known | F_uniform_scale;
_flags |= F_has_components | F_components_known | F_hpr_known | F_quat_known | F_uniform_scale | F_identity_scale;
} else {
// If we don't have components and we're not identity, the only