diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx index a485851448..367533dd46 100644 --- a/panda/src/pgraph/geomNode.cxx +++ b/panda/src/pgraph/geomNode.cxx @@ -876,17 +876,36 @@ do_premunge(GraphicsStateGuardianBase *gsg, GeomTransformer &transformer) { Thread *current_thread = Thread::get_current_thread(); + // Cache munged vertex data, so that we don't duplicate vertex data + // unnecessarily. + std::map munged_vdata; + OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { CDStageWriter cdata(_cycler, pipeline_stage, current_thread); - GeomList::iterator gi; PT(GeomList) geoms = cdata->modify_geoms(); - for (gi = geoms->begin(); gi != geoms->end(); ++gi) { - GeomEntry &entry = (*gi); + for (GeomEntry &entry : *geoms) { CPT(RenderState) geom_state = node_state->compose(entry._state); CPT(Geom) geom = entry._geom.get_read_pointer(); PT(GeomMunger) munger = gsg->get_geom_munger(geom_state, current_thread); - entry._geom = transformer.premunge_geom(geom, munger); + + CPT(GeomVertexData) vdata = geom->get_vertex_data(); + + auto it = munged_vdata.find(vdata); + if (it != munged_vdata.end()) { + vdata = it->second; + } else { + CPT(GeomVertexData) old_vdata = std::move(vdata); + vdata = munger->premunge_data(old_vdata); + munged_vdata[std::move(old_vdata)] = vdata; + } + + CPT(Geom) pgeom = geom; + munger->premunge_geom(pgeom, vdata); + + PT(Geom) geom_copy = pgeom->make_copy(); + geom_copy->set_vertex_data(vdata); + entry._geom = std::move(geom_copy); } } CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);