fix some sprite issues

This commit is contained in:
David Rose 2009-03-02 23:11:27 +00:00
parent 3e35ee9a24
commit 0a6a6dcb3e
6 changed files with 133 additions and 61 deletions

View File

@ -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 "

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<CPT(GeomVertexFormat), CPT(GeomVertexFormat) > 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<SourceFormat, CPT(GeomVertexFormat) > FormatMap;
static FormatMap _format_map;
static LightMutex _format_lock;
static PStatCollector _munge_geom_pcollector;
static PStatCollector _munge_sprites_pcollector;

View File

@ -93,6 +93,10 @@ output(ostream &out) const {
break;
}
if (get_thickness() != 1.0f) {
out << ", thick " << get_thickness();
}
if (get_perspective()) {
out << ", perspective";
}