#include "opengl/data_managers/mesh_vertex_buffer_manager.hpp" void zgl::mesh_vertex_buffer_manager::process(store_type& store) { for (const auto& [ id, mesh ] : store) { // The ireator must reutrn a pair containing the components and a tuple of spans } } template void dynamic_vertex_buffer::build_vertex_buffer( std::vector& vertex_buffer, std::size_t& component_count, std::array& component_types, std::array& component_lengths, GLsizei& stride ) const { const auto for_all_components = [&](auto&& f, const T default_value) { return std::apply( [&](const auto&... component_buffer) { std::array results{}; auto i = std::size_t{}; ( ( results[i] = [&](const auto& buffer, const auto index) -> T { if ((m_components & C{ 1 << index }) != C{}) { return f(buffer, index); } return default_value; }(component_buffer, i), ++i ), ... ); return results; }, m_component_buffers ); }; component_count = 0; component_types = for_all_components( ztu::specialised_lambda { [&component_count](const std::vector>&, std::size_t) { ++component_count; return zgl::type_utils::to_gl_type(); }, [&component_count](const std::vector&, std::size_t) { ++component_count; return zgl::type_utils::to_gl_type(); } }, GLenum{ GL_INVALID_VALUE } ); const auto element_counts = for_all_components( [](const std::vector& buffer, std::size_t) { return buffer.size(); }, std::numeric_limits::max() ); const auto minimum_element_count = std::ranges::min(element_counts); component_lengths = for_all_components( ztu::specialised_lambda { [](const std::vector&, std::size_t) { return 1; }, [](const std::vector>&, std::size_t) { return Count; } }, GLsizei{ 0 } ); auto component_sizes = std::array{}; for (std::size_t i{}; i != component_sizes.size(); ++i) { component_sizes[i] = component_lengths[i] * zgl::type_utils::size_of(component_types[i]); } const auto total_size = minimum_element_count * std::accumulate( component_sizes.begin(), component_sizes.end(), GLsizei{ 0 } ); vertex_buffer.resize(total_size); // Calculate offsets and stride auto component_offsets = component_sizes; stride = 0; for (std::size_t i{}; i != component_offsets.size(); ++i) { component_offsets[i] = stride; stride += component_sizes[i]; } // Copy all the components over one by one for_all_components( [&](const std::vector& buffer, std::size_t index) { std::size_t pos = component_offsets[index]; for (std::size_t i{}; i != minimum_element_count; ++i) { std::memcpy( &vertex_buffer[pos], buffer[i].data(), component_sizes[index] ); pos += stride; } return 0; }, 0 ); // remove values of unused components std::ignore = std::ranges::remove(component_lengths, 0); std::ignore = std::ranges::remove(component_types, GL_INVALID_VALUE); }