mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
pgraph: fix for additional columns in munge_points_to_quads()
Fixes #870
This commit is contained in:
parent
54cf7b9a5d
commit
18bb8a5559
@ -223,29 +223,23 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GeomVertexDataPipelineReader reader(source_data, current_thread);
|
||||||
|
reader.check_array_readers();
|
||||||
|
|
||||||
PStatTimer timer(_munge_sprites_pcollector, current_thread);
|
PStatTimer timer(_munge_sprites_pcollector, current_thread);
|
||||||
_sw_sprites_pcollector.add_level(source_data->get_num_rows());
|
_sw_sprites_pcollector.add_level(reader.get_num_rows());
|
||||||
|
|
||||||
GraphicsStateGuardianBase *gsg = traverser->get_gsg();
|
GraphicsStateGuardianBase *gsg = traverser->get_gsg();
|
||||||
|
|
||||||
GeomVertexReader vertex(source_data, InternalName::get_vertex(),
|
GeomVertexReader vertex(&reader, InternalName::get_vertex());
|
||||||
current_thread);
|
GeomVertexReader normal(&reader, InternalName::get_normal());
|
||||||
GeomVertexReader normal(source_data, InternalName::get_normal(),
|
GeomVertexReader rotate(&reader, InternalName::get_rotate());
|
||||||
current_thread);
|
GeomVertexReader size(&reader, InternalName::get_size());
|
||||||
GeomVertexReader color(source_data, InternalName::get_color(),
|
GeomVertexReader aspect_ratio(&reader, InternalName::get_aspect_ratio());
|
||||||
current_thread);
|
|
||||||
GeomVertexReader texcoord(source_data, InternalName::get_texcoord(),
|
|
||||||
current_thread);
|
|
||||||
GeomVertexReader rotate(source_data, InternalName::get_rotate(),
|
|
||||||
current_thread);
|
|
||||||
GeomVertexReader size(source_data, InternalName::get_size(),
|
|
||||||
current_thread);
|
|
||||||
GeomVertexReader aspect_ratio(source_data, InternalName::get_aspect_ratio(),
|
|
||||||
current_thread);
|
|
||||||
|
|
||||||
bool has_normal = (normal.has_column());
|
bool has_normal = (normal.has_column());
|
||||||
bool has_color = (color.has_column());
|
bool has_color = (reader.has_column(InternalName::get_color()));
|
||||||
bool has_texcoord = (texcoord.has_column());
|
bool has_texcoord = (reader.has_column(InternalName::get_texcoord()));
|
||||||
bool has_rotate = (rotate.has_column());
|
bool has_rotate = (rotate.has_column());
|
||||||
bool has_size = (size.has_column());
|
bool has_size = (size.has_column());
|
||||||
bool has_aspect_ratio = (aspect_ratio.has_column());
|
bool has_aspect_ratio = (aspect_ratio.has_column());
|
||||||
@ -280,7 +274,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
LightMutexHolder holder(_format_lock);
|
LightMutexHolder holder(_format_lock);
|
||||||
SourceFormat sformat(source_data->get_format(), sprite_texcoord);
|
SourceFormat sformat(reader.get_format(), sprite_texcoord);
|
||||||
FormatMap::iterator fmi = _format_map.find(sformat);
|
FormatMap::iterator fmi = _format_map.find(sformat);
|
||||||
if (fmi != _format_map.end()) {
|
if (fmi != _format_map.end()) {
|
||||||
new_format = (*fmi).second;
|
new_format = (*fmi).second;
|
||||||
@ -304,13 +298,13 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||||||
Geom::C_clip_point);
|
Geom::C_clip_point);
|
||||||
}
|
}
|
||||||
if (has_normal) {
|
if (has_normal) {
|
||||||
const GeomVertexColumn *c = normal.get_column();
|
const GeomVertexColumn *c = reader.get_format()->get_normal_column();
|
||||||
new_array_format->add_column
|
new_array_format->add_column
|
||||||
(InternalName::get_normal(), c->get_num_components(),
|
(InternalName::get_normal(), c->get_num_components(),
|
||||||
c->get_numeric_type(), c->get_contents());
|
c->get_numeric_type(), c->get_contents());
|
||||||
}
|
}
|
||||||
if (has_color) {
|
if (has_color) {
|
||||||
const GeomVertexColumn *c = color.get_column();
|
const GeomVertexColumn *c = reader.get_format()->get_color_column();
|
||||||
new_array_format->add_column
|
new_array_format->add_column
|
||||||
(InternalName::get_color(), c->get_num_components(),
|
(InternalName::get_color(), c->get_num_components(),
|
||||||
c->get_numeric_type(), c->get_contents());
|
c->get_numeric_type(), c->get_contents());
|
||||||
@ -322,12 +316,34 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||||||
Geom::C_texcoord);
|
Geom::C_texcoord);
|
||||||
|
|
||||||
} else if (has_texcoord) {
|
} else if (has_texcoord) {
|
||||||
const GeomVertexColumn *c = texcoord.get_column();
|
const GeomVertexColumn *c = reader.get_format()->get_column(InternalName::get_texcoord());
|
||||||
new_array_format->add_column
|
new_array_format->add_column
|
||||||
(InternalName::get_texcoord(), c->get_num_components(),
|
(InternalName::get_texcoord(), c->get_num_components(),
|
||||||
c->get_numeric_type(), c->get_contents());
|
c->get_numeric_type(), c->get_contents());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Go through the other columns and copy them from the original.
|
||||||
|
for (size_t ai = 0; ai < sformat._format->get_num_arrays(); ++ai) {
|
||||||
|
const GeomVertexArrayFormat *aformat = sformat._format->get_array(ai);
|
||||||
|
|
||||||
|
for (size_t ci = 0; ci < aformat->get_num_columns(); ++ci) {
|
||||||
|
const GeomVertexColumn *column = aformat->get_column(ci);
|
||||||
|
const InternalName *name = column->get_name();
|
||||||
|
if (name != InternalName::get_vertex() &&
|
||||||
|
name != InternalName::get_normal() &&
|
||||||
|
name != InternalName::get_color() &&
|
||||||
|
name != InternalName::get_texcoord() &&
|
||||||
|
name != InternalName::get_rotate() &&
|
||||||
|
name != InternalName::get_size() &&
|
||||||
|
name != InternalName::get_aspect_ratio()) {
|
||||||
|
|
||||||
|
new_array_format->add_column(name,
|
||||||
|
column->get_num_components(), column->get_numeric_type(),
|
||||||
|
column->get_contents());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new_format = GeomVertexFormat::register_format(new_array_format);
|
new_format = GeomVertexFormat::register_format(new_array_format);
|
||||||
_format_map[sformat] = new_format;
|
_format_map[sformat] = new_format;
|
||||||
}
|
}
|
||||||
@ -362,7 +378,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||||||
// Now convert all of the vertices in the GeomVertexData to quads. We
|
// Now convert all of the vertices in the GeomVertexData to quads. We
|
||||||
// always convert all the vertices, assuming all the vertices are referenced
|
// always convert all the vertices, assuming all the vertices are referenced
|
||||||
// by GeomPrimitives, because we want to optimize for the most common case.
|
// by GeomPrimitives, because we want to optimize for the most common case.
|
||||||
int orig_verts = source_data->get_num_rows();
|
int orig_verts = reader.get_num_rows();
|
||||||
int new_verts = 4 * orig_verts; // each vertex becomes four.
|
int new_verts = 4 * orig_verts; // each vertex becomes four.
|
||||||
|
|
||||||
PT(GeomVertexData) new_data = new GeomVertexData
|
PT(GeomVertexData) new_data = new GeomVertexData
|
||||||
@ -371,9 +387,50 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||||||
|
|
||||||
GeomVertexWriter new_vertex(new_data, InternalName::get_vertex());
|
GeomVertexWriter new_vertex(new_data, InternalName::get_vertex());
|
||||||
GeomVertexWriter new_normal(new_data, InternalName::get_normal());
|
GeomVertexWriter new_normal(new_data, InternalName::get_normal());
|
||||||
GeomVertexWriter new_color(new_data, InternalName::get_color());
|
|
||||||
GeomVertexWriter new_texcoord(new_data, InternalName::get_texcoord());
|
GeomVertexWriter new_texcoord(new_data, InternalName::get_texcoord());
|
||||||
|
|
||||||
|
nassertr(new_vertex.has_column(), false);
|
||||||
|
unsigned char *write_ptr = new_vertex.get_array_handle()->get_write_pointer();
|
||||||
|
|
||||||
|
// Collect all other columns that we just need to copy the data of.
|
||||||
|
struct CopyOp {
|
||||||
|
unsigned char *_to_pointer;
|
||||||
|
const unsigned char *_from_pointer;
|
||||||
|
size_t _num_bytes;
|
||||||
|
size_t _from_stride;
|
||||||
|
};
|
||||||
|
pvector<CopyOp> copies;
|
||||||
|
|
||||||
|
const GeomVertexArrayFormat *aformat = new_format->get_array(0);
|
||||||
|
for (size_t ci = 0; ci < aformat->get_num_columns(); ++ci) {
|
||||||
|
const GeomVertexColumn *column = aformat->get_column(ci);
|
||||||
|
const InternalName *name = column->get_name();
|
||||||
|
if (name != InternalName::get_vertex() &&
|
||||||
|
(retransform_sprites || name != InternalName::get_normal()) &&
|
||||||
|
(!sprite_texcoord || name != InternalName::get_texcoord())) {
|
||||||
|
|
||||||
|
int source_array;
|
||||||
|
const GeomVertexColumn *source_column;
|
||||||
|
if (reader.get_format()->get_array_info(name, source_array, source_column)) {
|
||||||
|
CopyOp copy;
|
||||||
|
copy._to_pointer = write_ptr + (size_t)column->get_start();
|
||||||
|
copy._from_pointer = reader.get_array_reader(source_array)->get_read_pointer(true) + (size_t)source_column->get_start();
|
||||||
|
copy._num_bytes = (size_t)column->get_total_bytes();
|
||||||
|
copy._from_stride = reader.get_format()->get_array(source_array)->get_stride();
|
||||||
|
|
||||||
|
if (!copies.empty() &&
|
||||||
|
(copy._to_pointer == copies.back()._to_pointer + copies.back()._num_bytes) &&
|
||||||
|
(copy._from_pointer == copies.back()._from_pointer + copies.back()._num_bytes)) {
|
||||||
|
// Merge with previous.
|
||||||
|
copies.back()._num_bytes += copy._num_bytes;
|
||||||
|
} else {
|
||||||
|
copies.push_back(copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t to_stride = aformat->get_stride();
|
||||||
|
|
||||||
// We'll keep an array of all of the points' eye-space coordinates, and
|
// We'll keep an array of all of the points' eye-space coordinates, and
|
||||||
// their distance from the camera, so we can sort the points for each
|
// their distance from the camera, so we can sort the points for each
|
||||||
// primitive, below.
|
// primitive, below.
|
||||||
@ -447,14 +504,6 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||||||
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3])));
|
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3])));
|
||||||
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3])));
|
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3])));
|
||||||
|
|
||||||
if (has_normal) {
|
|
||||||
const LNormal &c = normal.get_data3();
|
|
||||||
new_normal.set_data3(c);
|
|
||||||
new_normal.set_data3(c);
|
|
||||||
new_normal.set_data3(c);
|
|
||||||
new_normal.set_data3(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Without retransform_sprites, we can simply load the clip-space
|
// Without retransform_sprites, we can simply load the clip-space
|
||||||
// coordinates.
|
// coordinates.
|
||||||
@ -464,6 +513,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||||||
new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]);
|
new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]);
|
||||||
|
|
||||||
if (has_normal) {
|
if (has_normal) {
|
||||||
|
// We need to transform the normals to clip-space too, then.
|
||||||
LNormal c = render_transform.xform_vec(normal.get_data3());
|
LNormal c = render_transform.xform_vec(normal.get_data3());
|
||||||
new_normal.set_data3(c);
|
new_normal.set_data3(c);
|
||||||
new_normal.set_data3(c);
|
new_normal.set_data3(c);
|
||||||
@ -471,24 +521,24 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
|
|||||||
new_normal.set_data3(c);
|
new_normal.set_data3(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has_color) {
|
|
||||||
const LColor &c = color.get_data4();
|
|
||||||
new_color.set_data4(c);
|
|
||||||
new_color.set_data4(c);
|
|
||||||
new_color.set_data4(c);
|
|
||||||
new_color.set_data4(c);
|
|
||||||
}
|
|
||||||
if (sprite_texcoord) {
|
if (sprite_texcoord) {
|
||||||
new_texcoord.set_data2(1.0f, 0.0f);
|
new_texcoord.set_data2(1.0f, 0.0f);
|
||||||
new_texcoord.set_data2(0.0f, 0.0f);
|
new_texcoord.set_data2(0.0f, 0.0f);
|
||||||
new_texcoord.set_data2(1.0f, 1.0f);
|
new_texcoord.set_data2(1.0f, 1.0f);
|
||||||
new_texcoord.set_data2(0.0f, 1.0f);
|
new_texcoord.set_data2(0.0f, 1.0f);
|
||||||
} else if (has_texcoord) {
|
}
|
||||||
const LVecBase4 &c = texcoord.get_data4();
|
|
||||||
new_texcoord.set_data4(c);
|
// Other columns are simply duplicated for each vertex.
|
||||||
new_texcoord.set_data4(c);
|
for (CopyOp © : copies) {
|
||||||
new_texcoord.set_data4(c);
|
memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
|
||||||
new_texcoord.set_data4(c);
|
copy._to_pointer += to_stride;
|
||||||
|
memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
|
||||||
|
copy._to_pointer += to_stride;
|
||||||
|
memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
|
||||||
|
copy._to_pointer += to_stride;
|
||||||
|
memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
|
||||||
|
copy._to_pointer += to_stride;
|
||||||
|
copy._from_pointer += copy._from_stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
++vi;
|
++vi;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user