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) {
257 sprite_texcoord =
true;
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);
370 new_data->unclean_set_num_rows(new_verts);
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) {
541 unsigned int v = index.get_data1i();
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;