diff --git a/application/editormodeinfra.cpp b/application/editormodeinfra.cpp index 1840ffe7..db6e4f3b 100644 --- a/application/editormodeinfra.cpp +++ b/application/editormodeinfra.cpp @@ -292,6 +292,7 @@ void move_traction(TTraction *Traction, std::array const &Points) Traction->location(glm::mix(Points[1], Points[0], 0.5)); Traction->m_area.radius = -1.f; simulation::Region->insert_and_register(Traction); + GfxRenderer->Erase(Traction->m_geometry); Traction->m_geometry = gfx::geometry_handle{}; auto §ion{simulation::Region->section(Traction->location())}; if (section.m_geometrycreated) diff --git a/rendering/geometrybank.cpp b/rendering/geometrybank.cpp index f801c450..2a1ff5ee 100644 --- a/rendering/geometrybank.cpp +++ b/rendering/geometrybank.cpp @@ -318,6 +318,20 @@ geometry_bank::append( gfx::vertex_array &Vertices, userdata_array &Userdata, gf return replace( Vertices, Userdata, Geometry, gfx::geometry_bank::chunk( Geometry ).vertices.size() ); } +void +geometry_bank::erase( gfx::geometry_handle const &Geometry ) { + + if( ( Geometry.chunk == 0 ) || ( Geometry.chunk > m_chunks.size() ) ) { return; } + + auto &chunk = gfx::geometry_bank::chunk( Geometry ); + if( chunk.vertices.empty() && chunk.indices.empty() ) { return; } + + gfx::vertex_array().swap( chunk.vertices ); + gfx::index_array().swap( chunk.indices ); + gfx::userdata_array().swap( chunk.userdata ); + replace_( Geometry ); +} + // draws geometry stored in specified chunk std::size_t geometry_bank::draw( gfx::geometry_handle const &Geometry, gfx::stream_units const &Units, unsigned int const Streams ) { @@ -425,6 +439,14 @@ geometrybank_manager::append( gfx::vertex_array &Vertices, userdata_array &Userd return bank( Geometry ).first->append( Vertices, Userdata, Geometry ); } + +void +geometrybank_manager::erase( gfx::geometry_handle const &Geometry ) { + + if( ( Geometry.bank == 0 ) || ( Geometry.bank > m_geometrybanks.size() ) ) { return; } + + bank( Geometry ).first->erase( Geometry ); +} // draws geometry stored in specified chunk void geometrybank_manager::draw( gfx::geometry_handle const &Geometry, unsigned int const Streams ) { diff --git a/rendering/geometrybank.h b/rendering/geometrybank.h index 47e7afc7..537c79ba 100644 --- a/rendering/geometrybank.h +++ b/rendering/geometrybank.h @@ -117,6 +117,7 @@ public: auto replace( gfx::vertex_array &Vertices, gfx::userdata_array& Userdata, gfx::geometry_handle const &Geometry, std::size_t const Offset = 0 ) -> bool; // adds supplied vertex data at the end of specified chunk auto append( gfx::vertex_array &Vertices, gfx::userdata_array& Userdata, gfx::geometry_handle const &Geometry ) -> bool; + void erase( gfx::geometry_handle const &Geometry ); // draws geometry stored in specified chunk auto draw( gfx::geometry_handle const &Geometry, gfx::stream_units const &Units, unsigned int const Streams = basic_streams ) -> std::size_t; // draws geometry stored in specified chunk N times via glDrawElementsInstanced* @@ -222,6 +223,7 @@ public: auto replace( gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometry_handle const &Geometry, std::size_t const Offset = 0 ) -> bool; // adds supplied vertex data at the end of specified chunk auto append( gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometry_handle const &Geometry ) -> bool; + void erase( gfx::geometry_handle const &Geometry ); // draws geometry stored in specified chunk void draw( gfx::geometry_handle const &Geometry, unsigned int const Streams = basic_streams ); // draws geometry stored in specified chunk InstanceCount times via GPU instancing. diff --git a/rendering/opengl33geometrybank.cpp b/rendering/opengl33geometrybank.cpp index 4713ec69..978a1b75 100644 --- a/rendering/opengl33geometrybank.cpp +++ b/rendering/opengl33geometrybank.cpp @@ -33,7 +33,8 @@ opengl33_vaogeometrybank::replace_( gfx::geometry_handle const &Geometry ) { auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ]; chunkrecord.is_good = false; // if the overall length of the chunk didn't change we can get away with reusing the old buffer... - if( geometry_bank::chunk( Geometry ).vertices.size() != chunkrecord.vertex_count ) { + if( ( geometry_bank::chunk( Geometry ).vertices.size() != chunkrecord.vertex_count ) + || ( geometry_bank::chunk( Geometry ).userdata.empty() == chunkrecord.has_userdata ) ) { // ...but otherwise we'll need to allocate a new one // TBD: we could keep and reuse the old buffer also if the new chunk is smaller than the old one, // but it'd require some extra tracking and work to keep all chunks up to date; also wasting vram; may be not worth it? diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index b77731cf..b1f9e56d 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -2217,6 +2217,11 @@ bool opengl33_renderer::Append(gfx::vertex_array &Vertices, gfx::userdata_array return m_geometry.append(Vertices, Userdata, Geometry); } +void opengl33_renderer::Erase(gfx::geometry_handle const &Geometry) +{ + m_geometry.erase(Geometry); +} + // provides direct access to index data of specfied chunk gfx::index_array const & opengl33_renderer::Indices(gfx::geometry_handle const &Geometry) const { diff --git a/rendering/opengl33renderer.h b/rendering/opengl33renderer.h index a7bd46d6..d7adfb9e 100644 --- a/rendering/opengl33renderer.h +++ b/rendering/opengl33renderer.h @@ -67,6 +67,7 @@ class opengl33_renderer : public gfx_renderer { bool Replace(gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometry_handle const &Geometry, int const Type, const std::size_t Offset = 0) override; // adds supplied vertex data at the end of specified chunk bool Append(gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometry_handle const &Geometry, int const Type) override; + void Erase( gfx::geometry_handle const &Geometry ) override; // provides direct access to index data of specfied chunk gfx::index_array const & Indices( gfx::geometry_handle const &Geometry ) const override; diff --git a/rendering/openglrenderer.cpp b/rendering/openglrenderer.cpp index c4351b9e..d20626e3 100644 --- a/rendering/openglrenderer.cpp +++ b/rendering/openglrenderer.cpp @@ -1767,6 +1767,11 @@ bool opengl_renderer::Append(gfx::vertex_array &Vertices, gfx::userdata_array &U return m_geometry.append( Vertices, Userdata, Geometry ); } +void opengl_renderer::Erase( gfx::geometry_handle const &Geometry ) +{ + m_geometry.erase( Geometry ); +} + // provides direct access to vertex data of specfied chunk gfx::index_array const & opengl_renderer::Indices( gfx::geometry_handle const &Geometry ) const { diff --git a/rendering/openglrenderer.h b/rendering/openglrenderer.h index 78fffa40..da3faad0 100644 --- a/rendering/openglrenderer.h +++ b/rendering/openglrenderer.h @@ -65,6 +65,7 @@ public: bool Replace(gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometry_handle const &Geometry, int const Type, const std::size_t Offset = 0) override; // adds supplied vertex data at the end of specified chunk bool Append(gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometry_handle const &Geometry, int const Type) override; + void Erase( gfx::geometry_handle const &Geometry ) override; // provides direct access to index data of specfied chunk gfx::index_array const & Indices( gfx::geometry_handle const &Geometry ) const override; diff --git a/rendering/renderer.h b/rendering/renderer.h index 649dd795..2c302a75 100644 --- a/rendering/renderer.h +++ b/rendering/renderer.h @@ -59,6 +59,7 @@ public: virtual auto Replace(gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometry_handle const &Geometry, int const Type, const std::size_t Offset = 0) -> bool = 0; // adds supplied vertex data at the end of specified chunk virtual auto Append(gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometry_handle const &Geometry, int const Type) -> bool = 0; + virtual void Erase( gfx::geometry_handle const &Geometry ) {} // provides direct access to index data of specfied chunk virtual auto Indices( gfx::geometry_handle const &Geometry ) const->gfx::index_array const & = 0; // provides direct access to vertex data of specfied chunk diff --git a/world/Track.cpp b/world/Track.cpp index ba24fa9d..ae071220 100644 --- a/world/Track.cpp +++ b/world/Track.cpp @@ -1471,12 +1471,27 @@ glm::vec3 TTrack::get_nearest_point(const glm::dvec3 &point) const void TTrack::rebuild_geometry( gfx::geometrybank_handle const &Bank ) { track_rails::forget(); + auto const erase = [ this ]( gfx::geometry_handle const &Chunk ) { + if( SwitchExtension + && std::any_of( SwitchExtension->m_nosechunks.begin(), SwitchExtension->m_nosechunks.end(), [ & ]( auto const &Pooled ) { return Pooled.handle == Chunk; } ) ) { + return; + } + GfxRenderer->Erase( Chunk ); + }; + for( auto const *geometry : { &Geometry1, &Geometry2, &GeometryCut1, &GeometryCut2 } ) { + std::for_each( geometry->begin(), geometry->end(), erase ); + } + for( auto const &tread : GeometryTreads ) { + std::for_each( tread.geometry.begin(), tread.geometry.end(), erase ); + std::for_each( tread.cuts.begin(), tread.cuts.end(), erase ); + } Geometry1.clear(); Geometry2.clear(); GeometryCut1.clear(); GeometryCut2.clear(); GeometryTreads.clear(); if( SwitchExtension ) { + erase( SwitchExtension->Geometry3 ); SwitchExtension->Geometry3 = gfx::geometry_handle{}; } m_sleeper_local_transforms.clear();