133 lines
3.4 KiB
C++
133 lines
3.4 KiB
C++
#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<typename C, typename... Ts>
|
|
void dynamic_vertex_buffer<C, Ts...>::build_vertex_buffer(
|
|
std::vector<ztu::u8>& vertex_buffer,
|
|
std::size_t& component_count,
|
|
std::array<GLenum, sizeof...(Ts)>& component_types,
|
|
std::array<GLint, sizeof...(Ts)>& component_lengths,
|
|
GLsizei& stride
|
|
) const {
|
|
const auto for_all_components = [&]<typename T>(auto&& f, const T default_value)
|
|
{
|
|
return std::apply(
|
|
[&](const auto&... component_buffer)
|
|
{
|
|
std::array<T, sizeof...(component_buffer)> 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]<numeric_type Component, std::size_t Count>(const std::vector<std::array<Component, Count>>&, std::size_t)
|
|
{
|
|
++component_count;
|
|
return zgl::type_utils::to_gl_type<Component>();
|
|
},
|
|
[&component_count]<numeric_type Component>(const std::vector<Component>&, std::size_t)
|
|
{
|
|
++component_count;
|
|
return zgl::type_utils::to_gl_type<Component>();
|
|
}
|
|
},
|
|
GLenum{ GL_INVALID_VALUE }
|
|
);
|
|
|
|
const auto element_counts = for_all_components(
|
|
[]<class Component>(const std::vector<Component>& buffer, std::size_t)
|
|
{
|
|
return buffer.size();
|
|
},
|
|
std::numeric_limits<std::size_t>::max()
|
|
);
|
|
|
|
const auto minimum_element_count = std::ranges::min(element_counts);
|
|
|
|
component_lengths = for_all_components(
|
|
ztu::specialised_lambda
|
|
{
|
|
[]<class Component>(const std::vector<Component>&, std::size_t)
|
|
{
|
|
return 1;
|
|
},
|
|
[]<class Component, std::size_t Count>(const std::vector<std::array<Component, Count>>&, std::size_t)
|
|
{
|
|
return Count;
|
|
}
|
|
},
|
|
GLsizei{ 0 }
|
|
);
|
|
|
|
auto component_sizes = std::array<GLsizei, sizeof...(Ts)>{};
|
|
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(
|
|
[&]<class Component>(const std::vector<Component>& 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);
|
|
} |