#include "opengl/data_managers/point_cloud_vertex_buffer_manager.hpp" #include "util/logger.hpp" #include "opengl/error.hpp" #include "opengl/vertex_buffer_utils.hpp" void zgl::point_cloud_vertex_buffer_manager::process(store_type& store) { for (const auto& [ id, point_cloud ] : store) { if (not m_resource_manager.has_resource(id)) { m_point_cloud_buffer.emplace_back(id, point_cloud); } } m_buffer_id_buffer.resize(m_point_cloud_buffer.size()); glGenBuffers(m_buffer_id_buffer.size(), m_buffer_id_buffer.data()); if (const auto e = get_error()) { ztu::logger::error("Error while creating % vertex buffers: %.", m_buffer_id_buffer.size(), e.message()); return; } for (auto [ entry, buffer_id ] : std::ranges::views::zip(m_point_cloud_buffer, m_buffer_id_buffer)) { auto [ store_id, point_cloud ] = entry; const auto& [ components, buffers ] = point_cloud; m_byte_buffer.clear(); const auto meta = std::apply( [&](const auto&... component_buffers) { vertex_buffer_utils::interlace(m_byte_buffer, components, component_buffers...); return vertex_buffer_utils::generate_metadata(components, component_buffers...); }, buffers ); glBindBuffer(GL_ARRAY_BUFFER, buffer_id); if (const auto e = get_error()) { ztu::logger::error("Error while binding vertex buffer %: %.", buffer_id, e.message()); continue; } glBufferData( GL_ARRAY_BUFFER, static_cast(m_byte_buffer.size()), m_byte_buffer.data(), GL_STATIC_DRAW ); if (const auto e = get_error()) { ztu::logger::error("Error while setting vertex buffer data: %.", e.message()); continue; } m_resource_manager.add_resource(store_id, buffer_id, meta); buffer_id = {}; } glBindBuffer(GL_ARRAY_BUFFER, 0); const auto valid_buffer_ids = std::ranges::remove( m_buffer_id_buffer, 0 ); const auto invalid_buffer_count = m_buffer_id_buffer.size() - valid_buffer_ids.size(); glDeleteBuffers( invalid_buffer_count, m_buffer_id_buffer.data() ); if (const auto e = get_error()) { ztu::logger::error("Error while deleting % buffers: %.", invalid_buffer_count, e.message()); } } std::optional zgl::point_cloud_vertex_buffer_manager::get_handle( const store_id_type id ) { return m_resource_manager .get_resource(id) .transform( [](auto& resource) { return *reinterpret_cast(resource); } ); } void zgl::point_cloud_vertex_buffer_manager::collect_garbage(const bool force) { m_resource_manager.collect_garbage(); if (force or m_resource_manager.count_garbage() >= min_garbage_collection_count) { m_buffer_id_buffer.clear(); m_resource_manager.extract_garbage(m_buffer_id_buffer); glDeleteBuffers( m_buffer_id_buffer.size(), m_buffer_id_buffer.data() ); } }