38 PStatCollector CullableObject::_munge_geom_pcollector(
"*:Munge:Geom");
39 PStatCollector CullableObject::_munge_sprites_pcollector(
"*:Munge:Sprites");
40 PStatCollector CullableObject::_munge_sprites_verts_pcollector(
"*:Munge:Sprites:Verts");
41 PStatCollector CullableObject::_munge_sprites_prims_pcollector(
"*:Munge:Sprites:Prims");
42 PStatCollector CullableObject::_sw_sprites_pcollector(
"SW Sprites");
56 nassertr(munger !=
nullptr,
false);
59 PStatTimer timer(_munge_pcollector, current_thread);
60 if (_geom !=
nullptr) {
62 int gsg_bits = gsg->get_supported_geom_rendering();
63 if (!hardware_point_sprites) {
66 gsg_bits &= ~(Geom::GR_point_perspective | Geom::GR_point_sprite);
68 if (!hardware_points) {
71 gsg_bits &= ~(Geom::GR_point_bits & ~
Geom::GR_point);
78 _munged_data = geom_reader.get_vertex_data();
83 data_reader.check_array_readers();
84 nassertr(geom_reader.check_valid(&data_reader),
false);
88 geom_rendering = geom_reader.get_geom_rendering();
89 geom_rendering = _state->get_geom_rendering(geom_rendering);
90 geom_rendering = _internal_transform->get_geom_rendering(geom_rendering);
91 unsupported_bits = geom_rendering & ~gsg_bits;
93 if (unsupported_bits & Geom::GR_per_point_size) {
97 if (_state->get_attrib(sattr) && sattr->get_flag(ShaderAttrib::F_shader_point_size)) {
98 unsupported_bits &= ~
Geom::GR_per_point_size;
102 if (geom_rendering & Geom::GR_point_bits) {
103 if (geom_reader.get_primitive_type() != Geom::PT_points) {
104 if (singular_points ||
105 (unsupported_bits & Geom::GR_render_mode_point) != 0) {
107 _geom = _geom->make_points();
111 if (unsupported_bits & Geom::GR_render_mode_wireframe) {
112 if (geom_reader.get_primitive_type() != Geom::PT_lines) {
113 _geom = _geom->make_lines();
118 if ((unsupported_bits & Geom::GR_point_bits) != 0) {
123 if (pgraph_cat.is_spam()) {
125 <<
"munge_points_to_quads() for geometry with bits: " 126 << std::hex << geom_rendering <<
", unsupported: " 127 << (unsupported_bits & Geom::GR_point_bits) << std::dec <<
"\n";
129 if (!munge_points_to_quads(traverser, force)) {
137 PStatTimer timer(_munge_geom_pcollector, current_thread);
138 if (!munger->
munge_geom(_geom, _munged_data, force, current_thread)) {
147 if (_state->get_attrib(sattr) && sattr->
auto_shader()) {
149 if (data_reader.get_format()->
get_animation().get_animation_type() == Geom::AT_hardware) {
151 DCAST(
ShaderAttrib, ShaderAttrib::make())->set_flag(ShaderAttrib::F_hardware_skinning,
true));
152 _state = _state->compose(state);
155 gsg->ensure_generated_shader(_state);
160 _state = state_munger->munge_state(_state);
167 bool cpu_animated =
false;
170 _munged_data->animate_vertices(force, current_thread);
171 if (animated_vertices != _munged_data) {
173 std::swap(_munged_data, animated_vertices);
177 if (show_vertex_animation) {
179 bool hardware_animated = (data_reader.get_format()->
get_animation().get_animation_type() == Geom::AT_hardware);
180 if (cpu_animated || hardware_animated) {
182 static const double flash_rate = 1.0;
184 if ((cycle & 1) == 0) {
185 _state = cpu_animated ? get_flash_cpu_state() : get_flash_hardware_state();
198 void CullableObject::
199 output(std::ostream &out)
const {
200 if (_geom !=
nullptr) {
213 bool CullableObject::
214 munge_points_to_quads(
const CullTraverser *traverser,
bool force) {
220 _munged_data->animate_vertices(force, current_thread);
222 if (!force && !source_data->request_resident()) {
226 PStatTimer timer(_munge_sprites_pcollector, current_thread);
227 _sw_sprites_pcollector.add_level(source_data->get_num_rows());
243 GeomVertexReader aspect_ratio(source_data, InternalName::get_aspect_ratio(),
246 bool has_normal = (normal.has_column());
247 bool has_color = (color.has_column());
248 bool has_texcoord = (texcoord.has_column());
249 bool has_rotate = (rotate.has_column());
250 bool has_size = (size.has_column());
251 bool has_aspect_ratio = (aspect_ratio.has_column());
253 bool sprite_texcoord =
false;
255 if (tex_gen !=
nullptr) {
256 if (tex_gen->get_mode(TextureStage::get_default()) == TexGenAttrib::M_point_sprite) {
257 sprite_texcoord =
true;
260 _state = _state->set_attrib(tex_gen->remove_stage(TextureStage::get_default()));
264 PN_stdfloat point_size = 1;
265 bool perspective =
false;
267 if (render_mode !=
nullptr) {
271 if (render_mode->
get_mode() != RenderModeAttrib::M_filled_flat) {
274 _state = _state->set_attrib(RenderModeAttrib::make(RenderModeAttrib::M_filled_flat));
283 SourceFormat sformat(source_data->get_format(), sprite_texcoord);
284 FormatMap::iterator fmi = _format_map.find(sformat);
285 if (fmi != _format_map.end()) {
286 new_format = (*fmi).second;
291 if (sformat._retransform_sprites) {
308 new_array_format->add_column
314 new_array_format->add_column
318 if (sprite_texcoord) {
319 new_array_format->add_column
320 (InternalName::get_texcoord(), 2,
324 }
else if (has_texcoord) {
326 new_array_format->add_column
331 new_format = GeomVertexFormat::register_format(new_array_format);
332 _format_map[sformat] = new_format;
336 CoordinateSystem internal_cs = gsg->get_internal_coordinate_system();
337 LMatrix4
internal = _internal_transform->get_mat();
338 PN_stdfloat scale = _internal_transform->get_scale()[1];
342 LMatrix4 projection =
351 LMatrix4 height_projection;
358 LMatrix4 render_transform =
internal * projection;
359 LMatrix4 inv_render_transform;
360 inv_render_transform.invert_from(render_transform);
365 int orig_verts = source_data->get_num_rows();
366 int new_verts = 4 * orig_verts;
369 (source_data->get_name(), new_format, Geom::UH_stream);
382 PStatTimer t2(_munge_sprites_verts_pcollector, current_thread);
383 points = (PointData *)alloca(orig_verts *
sizeof(PointData));
385 while (!vertex.is_at_end()) {
387 LPoint3 eye =
internal.xform_point(vertex.get_data3());
388 PN_stdfloat dist = gsg->compute_distance_to(eye);
389 points[vi]._dist = dist;
392 LPoint4 p4 = LPoint4(eye[0], eye[1], eye[2], 1.0f) * projection;
395 point_size = size.get_data1();
398 PN_stdfloat scale_y = point_size;
403 LVector3 height(0.0f, point_size * scale, scale);
404 height = height * height_projection;
405 scale_y = height[1] * viewport_height;
418 PN_stdfloat scale_x = scale_y;
419 if (has_aspect_ratio) {
420 scale_x *= aspect_ratio.get_data1();
424 LPoint2 c0(scale_x, scale_y);
425 LPoint2 c1(-scale_x, scale_y);
429 PN_stdfloat r = rotate.get_data1();
430 LMatrix3 mat = LMatrix3::rotate_mat(r);
437 PN_stdfloat rx = 1.0f / viewport_width;
438 PN_stdfloat ry = 1.0f / viewport_height;
439 c0.set(c0[0] * rx, c0[1] * ry);
440 c1.set(c1[0] * rx, c1[1] * ry);
442 if (retransform_sprites) {
445 new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] + c0[0], p4[1] + c0[1], p4[2], p4[3])));
446 new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] + c1[0], p4[1] + c1[1], p4[2], p4[3])));
447 new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3])));
448 new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3])));
451 const LNormal &c = normal.get_data3();
452 new_normal.set_data3(c);
453 new_normal.set_data3(c);
454 new_normal.set_data3(c);
455 new_normal.set_data3(c);
461 new_vertex.set_data4(p4[0] + c0[0], p4[1] + c0[1], p4[2], p4[3]);
462 new_vertex.set_data4(p4[0] + c1[0], p4[1] + c1[1], p4[2], p4[3]);
463 new_vertex.set_data4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3]);
464 new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]);
467 LNormal c = render_transform.xform_vec(normal.get_data3());
468 new_normal.set_data3(c);
469 new_normal.set_data3(c);
470 new_normal.set_data3(c);
471 new_normal.set_data3(c);
475 const LColor &c = color.get_data4();
476 new_color.set_data4(c);
477 new_color.set_data4(c);
478 new_color.set_data4(c);
479 new_color.set_data4(c);
481 if (sprite_texcoord) {
482 new_texcoord.set_data2(1.0f, 0.0f);
483 new_texcoord.set_data2(0.0f, 0.0f);
484 new_texcoord.set_data2(1.0f, 1.0f);
485 new_texcoord.set_data2(0.0f, 1.0f);
486 }
else if (has_texcoord) {
487 const LVecBase4 &c = texcoord.get_data4();
488 new_texcoord.set_data4(c);
489 new_texcoord.set_data4(c);
490 new_texcoord.set_data4(c);
491 new_texcoord.set_data4(c);
497 nassertr(vi == orig_verts,
false);
498 nassertr(new_data->get_num_rows() == new_verts,
false);
504 if (new_verts < 0xffff) {
511 PT(
Geom) new_geom =
new Geom(new_data);
526 PStatTimer t3(_munge_sprites_prims_pcollector, current_thread);
528 int num_primitives = geom_reader.get_num_primitives();
529 for (
int pi = 0; pi < num_primitives; ++pi) {
530 const GeomPrimitive *primitive = geom_reader.get_primitive(pi);
534 unsigned int *vertices = (
unsigned int *)alloca(num_vertices *
sizeof(
unsigned int));
535 unsigned int *vertices_end = vertices + num_vertices;
540 for (
unsigned int *vi = vertices; vi != vertices_end; ++vi) {
542 nassertr(v < (
unsigned int)orig_verts,
false);
548 for (
int i = 0; i < num_vertices; ++i) {
549 unsigned int v = i + first_vertex;
550 nassertr(v < (
unsigned int)orig_verts,
false);
557 std::sort(vertices, vertices_end, SortPoints(points));
565 int new_prim_verts = 6 * num_vertices;
569 new_index->unclean_set_num_rows(new_prim_verts);
572 nassertr(index.has_column(),
false);
573 for (
unsigned int *vi = vertices; vi != vertices_end; ++vi) {
574 int new_vi = (*vi) * 4;
575 nassertr(index.get_write_row() + 6 <= new_prim_verts,
false);
576 index.set_data1i(new_vi);
577 index.set_data1i(new_vi + 1);
578 index.set_data1i(new_vi + 2);
579 index.set_data1i(new_vi + 2);
580 index.set_data1i(new_vi + 1);
581 index.set_data1i(new_vi + 3);
583 new_primitive->set_vertices(new_index, new_prim_verts);
587 new_primitive->set_minmax(min_vi * 4, max_vi * 4 + 3,
nullptr,
nullptr);
589 new_geom->add_primitive(new_primitive);
594 _geom = new_geom.p();
595 _munged_data = std::move(new_data);
605 get_flash_cpu_state() {
606 static const LColor flash_cpu_color(0.8f, 0.2, 0.2, 1.0f);
611 if (flash_cpu_state ==
nullptr) {
612 flash_cpu_state = RenderState::make
613 (LightAttrib::make_all_off(),
614 TextureAttrib::make_off(),
615 ColorAttrib::make_flat(flash_cpu_color));
618 return flash_cpu_state;
626 get_flash_hardware_state() {
627 static const LColor flash_hardware_color(0.2, 0.2, 0.8, 1.0);
632 if (flash_hardware_state ==
nullptr) {
633 flash_hardware_state = RenderState::make
634 (LightAttrib::make_all_off(),
635 TextureAttrib::make_off(),
636 ColorAttrib::make_flat(flash_hardware_color));
639 return flash_hardware_state;
645 CullableObject::SourceFormat::
648 _sprite_texcoord(sprite_texcoord)
650 _retransform_sprites = retransform_sprites;
This is just a simple derivative of GeomMunger that adds the ability to munge states.
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
This is our own Panda specialization on the default STL map.
bool auto_shader() const
If true, then this ShaderAttrib does not contain an explicit shader - instead, it requests the automa...
const GeomVertexArrayFormat * get_index_format() const
Returns a registered format appropriate for using to store the index table.
Contents get_contents() const
Returns the token representing the semantic meaning of the stored value.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool unclean_set_num_rows(int n)
This method behaves like set_num_rows(), except the new data is not initialized.
A base class for any number of different kinds of lenses, linear and otherwise.
virtual bool is_orthographic() const
Returns true if the lens represents a orthographic projection (i.e.
int get_max_vertex() const
Returns the maximum vertex index number used by all the primitives in this object.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Thread * get_current_thread() const
Returns the currently-executing thread object, as passed to the CullTraverser constructor.
NumericType get_numeric_type() const
Returns the token representing the numeric type of the data storage.
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_num_vertices
Returns the number of indices used by all the primitives in this object.
const Lens * get_lens() const
Returns the particular Lens used for rendering.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_first_vertex() const
Returns the first vertex number referenced by the primitive.
This defines how a single column is interleaved within a vertex array stored within a Geom.
int get_viewport_height() const
Returns the height of the viewport (display region) in pixels.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight class that represents a single element that may be timed and/or counted via stats.
int get_min_vertex() const
Returns the minimum vertex index number used by all the primitives in this object.
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Similar to MutexHolder, but for a light mutex.
int get_viewport_width() const
Returns the width of the viewport (display region) in pixels.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool munge_geom(GraphicsStateGuardianBase *gsg, GeomMunger *munger, const CullTraverser *traverser, bool force)
Uses the indicated GeomMunger to transform the geom and/or its vertices.
A container for geometry primitives.
get_coordinate_system
Returns the coordinate system that all 3-d computations are performed within for this Lens.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_data1i()
Returns the data associated with the read row, expressed as a 1-component value, and advances the rea...
GraphicsStateGuardianBase * get_gsg() const
Returns the GraphicsStateGuardian in effect.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const LMatrix4 & get_projection_mat(StereoChannel channel=SC_mono) const
Returns the complete transformation matrix from a 3-d point in space to a point on the film,...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool should_munge_state() const
Returns true if this munger has something interesting to do to the state.
get_mode
Returns the render mode.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A thread; that is, a lightweight process.
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
SceneSetup * get_scene() const
Returns the SceneSetup object.
Defines a series of disconnected triangles.
get_thickness
Returns the line width or point thickness.
get_perspective
Returns the perspective flag.
Specifies how polygons are to be drawn.
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
TypeHandle is the identifier used to differentiate C++ class types.
This object holds the camera position, etc., and other general setup information for rendering a part...
This is a standard, non-reentrant mutex, similar to the Mutex class.
int get_num_components() const
Returns the number of components of the column: the number of instances of the NumericType in each el...
CPT(RenderState) CullableObject
Returns a RenderState for flashing the object red, to show it is animated by the CPU when show-vertex...
Computes texture coordinates for geometry automatically based on vertex position and/or normal.
bool munge_geom(CPT(Geom) &geom, CPT(GeomVertexData) &data, bool force, Thread *current_thread)
Applies the indicated munger to the geom and its data, and returns a (possibly different) geom and da...
bool is_indexed() const
Returns true if the primitive is indexed, false otherwise.
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
This is the data for one array of a GeomVertexData structure.