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()) {
227 reader.check_array_readers();
229 PStatTimer timer(_munge_sprites_pcollector, current_thread);
230 _sw_sprites_pcollector.add_level(reader.get_num_rows());
240 bool has_normal = (normal.has_column());
241 bool has_color = (reader.has_column(InternalName::get_color()));
242 bool has_texcoord = (reader.has_column(InternalName::get_texcoord()));
243 bool has_rotate = (rotate.has_column());
244 bool has_size = (size.has_column());
245 bool has_aspect_ratio = (aspect_ratio.has_column());
247 bool sprite_texcoord =
false;
249 if (tex_gen !=
nullptr) {
251 sprite_texcoord =
true;
258 PN_stdfloat point_size = 1;
259 bool perspective =
false;
261 if (render_mode !=
nullptr) {
265 if (render_mode->
get_mode() != RenderModeAttrib::M_filled_flat) {
268 _state = _state->set_attrib(RenderModeAttrib::make(RenderModeAttrib::M_filled_flat));
277 SourceFormat sformat(reader.get_format(), sprite_texcoord);
278 FormatMap::iterator fmi = _format_map.find(sformat);
279 if (fmi != _format_map.end()) {
280 new_format = (*fmi).second;
285 if (sformat._retransform_sprites) {
302 new_array_format->add_column
308 new_array_format->add_column
312 if (sprite_texcoord) {
313 new_array_format->add_column
314 (InternalName::get_texcoord(), 2,
318 }
else if (has_texcoord) {
319 const GeomVertexColumn *c = reader.get_format()->get_column(InternalName::get_texcoord());
320 new_array_format->add_column
326 for (
size_t ai = 0; ai < sformat._format->get_num_arrays(); ++ai) {
332 if (name != InternalName::get_vertex() &&
333 name != InternalName::get_normal() &&
334 name != InternalName::get_color() &&
335 name != InternalName::get_texcoord() &&
336 name != InternalName::get_rotate() &&
337 name != InternalName::get_size() &&
338 name != InternalName::get_aspect_ratio()) {
340 new_array_format->add_column(name,
347 new_format = GeomVertexFormat::register_format(new_array_format);
348 _format_map[sformat] = new_format;
352 CoordinateSystem internal_cs = gsg->get_internal_coordinate_system();
353 LMatrix4
internal = _internal_transform->get_mat();
354 PN_stdfloat scale = _internal_transform->get_scale()[1];
358 LMatrix4 projection =
367 LMatrix4 height_projection;
374 LMatrix4 render_transform =
internal * projection;
375 LMatrix4 inv_render_transform;
376 inv_render_transform.invert_from(render_transform);
381 int orig_verts = reader.get_num_rows();
382 int new_verts = 4 * orig_verts;
385 (source_data->get_name(), new_format, Geom::UH_stream);
386 new_data->unclean_set_num_rows(new_verts);
392 nassertr(new_vertex.has_column(),
false);
393 unsigned char *write_ptr = new_vertex.get_array_handle()->get_write_pointer();
397 unsigned char *_to_pointer;
398 const unsigned char *_from_pointer;
408 if (name != InternalName::get_vertex() &&
409 (retransform_sprites || name != InternalName::get_normal()) &&
410 (!sprite_texcoord || name != InternalName::get_texcoord())) {
414 if (reader.get_format()->get_array_info(name, source_array, source_column)) {
416 copy._to_pointer = write_ptr + (size_t)column->
get_start();
417 copy._from_pointer = reader.get_array_reader(source_array)->get_read_pointer(
true) + (size_t)source_column->
get_start();
419 copy._from_stride = reader.get_format()->get_array(source_array)->get_stride();
421 if (!copies.empty() &&
422 (copy._to_pointer == copies.back()._to_pointer + copies.back()._num_bytes) &&
423 (copy._from_pointer == copies.back()._from_pointer + copies.back()._num_bytes)) {
425 copies.back()._num_bytes += copy._num_bytes;
427 copies.push_back(copy);
439 PStatTimer t2(_munge_sprites_verts_pcollector, current_thread);
440 points = (PointData *)alloca(orig_verts *
sizeof(PointData));
442 while (!vertex.is_at_end()) {
444 LPoint3 eye =
internal.xform_point(vertex.get_data3());
445 PN_stdfloat dist = gsg->compute_distance_to(eye);
446 points[vi]._dist = dist;
449 LPoint4 p4 = LPoint4(eye[0], eye[1], eye[2], 1.0f) * projection;
452 point_size = size.get_data1();
455 PN_stdfloat scale_y = point_size;
460 LVector3 height(0.0f, point_size * scale, scale);
461 height = height * height_projection;
462 scale_y = height[1] * viewport_height;
475 PN_stdfloat scale_x = scale_y;
476 if (has_aspect_ratio) {
477 scale_x *= aspect_ratio.get_data1();
481 LPoint2 c0(scale_x, scale_y);
482 LPoint2 c1(-scale_x, scale_y);
486 PN_stdfloat r = rotate.get_data1();
487 LMatrix3 mat = LMatrix3::rotate_mat(r);
494 PN_stdfloat rx = 1.0f / viewport_width;
495 PN_stdfloat ry = 1.0f / viewport_height;
496 c0.set(c0[0] * rx, c0[1] * ry);
497 c1.set(c1[0] * rx, c1[1] * ry);
499 if (retransform_sprites) {
502 new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] + c0[0], p4[1] + c0[1], p4[2], p4[3])));
503 new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] + c1[0], p4[1] + c1[1], p4[2], p4[3])));
504 new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3])));
505 new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3])));
510 new_vertex.set_data4(p4[0] + c0[0], p4[1] + c0[1], p4[2], p4[3]);
511 new_vertex.set_data4(p4[0] + c1[0], p4[1] + c1[1], p4[2], p4[3]);
512 new_vertex.set_data4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3]);
513 new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]);
517 LNormal c = render_transform.xform_vec(normal.get_data3());
518 new_normal.set_data3(c);
519 new_normal.set_data3(c);
520 new_normal.set_data3(c);
521 new_normal.set_data3(c);
524 if (sprite_texcoord) {
525 new_texcoord.set_data2(1.0f, 0.0f);
526 new_texcoord.set_data2(0.0f, 0.0f);
527 new_texcoord.set_data2(1.0f, 1.0f);
528 new_texcoord.set_data2(0.0f, 1.0f);
532 for (CopyOp © : copies) {
533 memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
534 copy._to_pointer += to_stride;
535 memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
536 copy._to_pointer += to_stride;
537 memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
538 copy._to_pointer += to_stride;
539 memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
540 copy._to_pointer += to_stride;
541 copy._from_pointer += copy._from_stride;
547 nassertr(vi == orig_verts,
false);
548 nassertr(new_data->get_num_rows() == new_verts,
false);
554 if (new_verts < 0xffff) {
561 PT(
Geom) new_geom =
new Geom(new_data);
576 PStatTimer t3(_munge_sprites_prims_pcollector, current_thread);
578 int num_primitives = geom_reader.get_num_primitives();
579 for (
int pi = 0; pi < num_primitives; ++pi) {
580 const GeomPrimitive *primitive = geom_reader.get_primitive(pi);
584 unsigned int *vertices = (
unsigned int *)alloca(num_vertices *
sizeof(
unsigned int));
585 unsigned int *vertices_end = vertices + num_vertices;
590 for (
unsigned int *vi = vertices; vi != vertices_end; ++vi) {
591 unsigned int v = index.get_data1i();
592 nassertr(v < (
unsigned int)orig_verts,
false);
598 for (
int i = 0; i < num_vertices; ++i) {
599 unsigned int v = i + first_vertex;
600 nassertr(v < (
unsigned int)orig_verts,
false);
607 std::sort(vertices, vertices_end, SortPoints(points));
615 int new_prim_verts = 6 * num_vertices;
619 new_index->unclean_set_num_rows(new_prim_verts);
622 nassertr(index.has_column(),
false);
623 for (
unsigned int *vi = vertices; vi != vertices_end; ++vi) {
624 int new_vi = (*vi) * 4;
625 nassertr(index.get_write_row() + 6 <= new_prim_verts,
false);
626 index.set_data1i(new_vi);
627 index.set_data1i(new_vi + 1);
628 index.set_data1i(new_vi + 2);
629 index.set_data1i(new_vi + 2);
630 index.set_data1i(new_vi + 1);
631 index.set_data1i(new_vi + 3);
633 new_primitive->set_vertices(new_index, new_prim_verts);
637 new_primitive->set_minmax(min_vi * 4, max_vi * 4 + 3,
nullptr,
nullptr);
639 new_geom->add_primitive(new_primitive);
644 _geom = new_geom.p();
645 _munged_data = std::move(new_data);
655 get_flash_cpu_state() {
656 static const LColor flash_cpu_color(0.8f, 0.2, 0.2, 1.0f);
661 if (flash_cpu_state ==
nullptr) {
662 flash_cpu_state = RenderState::make
663 (LightAttrib::make_all_off(),
664 TextureAttrib::make_off(),
665 ColorAttrib::make_flat(flash_cpu_color));
668 return flash_cpu_state;
676 get_flash_hardware_state() {
677 static const LColor flash_hardware_color(0.2, 0.2, 0.8, 1.0);
681 static CPT(
RenderState) flash_hardware_state =
nullptr;
682 if (flash_hardware_state ==
nullptr) {
683 flash_hardware_state = RenderState::make
684 (LightAttrib::make_all_off(),
685 TextureAttrib::make_off(),
686 ColorAttrib::make_flat(flash_hardware_color));
689 return flash_hardware_state;
695 CullableObject::SourceFormat::
698 _sprite_texcoord(sprite_texcoord)
700 _retransform_sprites = retransform_sprites;