38PStatCollector CullableObject::_munge_geom_pcollector(
"*:Munge:Geom");
39PStatCollector CullableObject::_munge_sprites_pcollector(
"*:Munge:Sprites");
40PStatCollector CullableObject::_munge_sprites_verts_pcollector(
"*:Munge:Sprites:Verts");
41PStatCollector CullableObject::_munge_sprites_prims_pcollector(
"*:Munge:Sprites:Prims");
42PStatCollector 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();
199output(std::ostream &out)
const {
200 if (_geom !=
nullptr) {
214munge_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);
655get_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;
676get_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;
695CullableObject::SourceFormat::
698 _sprite_texcoord(sprite_texcoord)
700 _retransform_sprites = retransform_sprites;
get_frame_time
Returns the time in seconds as of the last time tick() was called (typically, this will be as of the ...
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Thread * get_current_thread() const
Returns the currently-executing thread object, as passed to the CullTraverser constructor.
SceneSetup * get_scene() const
Returns the SceneSetup object.
GraphicsStateGuardianBase * get_gsg() const
Returns the GraphicsStateGuardian in effect.
bool munge_geom(GraphicsStateGuardianBase *gsg, GeomMunger *munger, const CullTraverser *traverser, bool force)
Uses the indicated GeomMunger to transform the geom and/or its vertices.
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
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...
Encapsulates the data from a Geom, pre-fetched for one stage of the pipeline.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
int get_max_vertex() const
Returns the maximum vertex index number used by all the primitives in this object.
get_num_vertices
Returns the number of indices used by all the primitives in this object.
int get_first_vertex() const
Returns the first vertex number referenced by the primitive.
const GeomVertexArrayFormat * get_index_format() const
Returns a registered format appropriate for using to store the index table.
int get_min_vertex() const
Returns the minimum vertex index number used by all the primitives in this object.
bool is_indexed() const
Returns true if the primitive is indexed, false otherwise.
Defines a series of disconnected triangles.
This is the data for one array of a GeomVertexData structure.
This defines how a single column is interleaved within a vertex array stored within a Geom.
int get_start() const
Returns the byte within the array record at which this column starts.
NumericType get_numeric_type() const
Returns the token representing the numeric type of the data storage.
const InternalName * get_name() const
Returns the name of this particular data field, e.g.
Contents get_contents() const
Returns the token representing the semantic meaning of the stored value.
int get_total_bytes() const
Returns the number of bytes used by each element of the column: component_bytes * num_components.
int get_num_components() const
Returns the number of components of the column: the number of instances of the NumericType in each el...
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
A container for geometry primitives.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
Encodes a string name in a hash table, mapping it to a pointer.
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.
get_coordinate_system
Returns the coordinate system that all 3-d computations are performed within for this Lens.
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,...
Similar to MutexHolder, but for a light mutex.
This is a standard, non-reentrant mutex, similar to the Mutex class.
A lightweight class that represents a single element that may be timed and/or counted via stats.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Specifies how polygons are to be drawn.
get_perspective
Returns the perspective flag.
get_thickness
Returns the line width or point thickness.
get_mode
Returns the render mode.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
This object holds the camera position, etc., and other general setup information for rendering a part...
const Lens * get_lens() const
Returns the particular Lens used for rendering.
int get_viewport_width() const
Returns the width of the viewport (display region) in pixels.
int get_viewport_height() const
Returns the height of the viewport (display region) in pixels.
bool auto_shader() const
If true, then this ShaderAttrib does not contain an explicit shader - instead, it requests the automa...
This is just a simple derivative of GeomMunger that adds the ability to munge states.
bool should_munge_state() const
Returns true if this munger has something interesting to do to the state.
Computes texture coordinates for geometry automatically based on vertex position and/or normal.
get_default
Returns the default TextureStage that will be used for all texturing that does not name a particular ...
A thread; that is, a lightweight process.
TypeHandle is the identifier used to differentiate C++ class types.
This is our own Panda specialization on the default STL map.
This is our own Panda specialization on the default STL vector.
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.
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.
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.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.