tried making naming more uniform and implemented most of the opengl managers
This commit is contained in:
127
include/opengl/vertex_buffer_utils.hpp
Normal file
127
include/opengl/vertex_buffer_utils.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#include "opengl/type_utils.hpp"
|
||||
#include "opengl/metadata/vertex_buffer_metadata.hpp"
|
||||
#include "util/specialised_lambda.hpp"
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <bits/ranges_algo.h>
|
||||
|
||||
namespace zgl::vertex_buffer_utils
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
concept numeric_type = std::integral<T> or std::floating_point<T>;
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
void for_enabled_components(
|
||||
const C components,
|
||||
auto&& f,
|
||||
std::span<Ts> buffers...
|
||||
) {
|
||||
(
|
||||
[&, index = std::size_t{}](const auto& buffer)
|
||||
{
|
||||
if ((components & static_cast<C>(1 << index)) != C{})
|
||||
{
|
||||
f(buffer, index);
|
||||
}
|
||||
++index;
|
||||
}(buffers),
|
||||
...
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
vertex_buffer_metadata generate_metadata(
|
||||
const C components,
|
||||
std::span<Ts> buffers...
|
||||
) {
|
||||
|
||||
auto meta = vertex_buffer_metadata{};
|
||||
|
||||
detail::for_enabled_components(
|
||||
components,
|
||||
ztu::specialised_lambda
|
||||
{
|
||||
// Visitor for scalar values
|
||||
[&]<detail::numeric_type Component>(const std::span<Component>&, std::size_t index)
|
||||
{
|
||||
auto& component = meta.components[index];
|
||||
component.type = type_utils::to_gl_type<Component>();
|
||||
component.count = 1;
|
||||
++meta.component_count;
|
||||
},
|
||||
// Visitor for numbers
|
||||
[&]<detail::numeric_type Component, std::size_t Count>(const std::span<std::array<Component, Count>>&, std::size_t index)
|
||||
{
|
||||
auto& component = meta.components[index];
|
||||
component.type = type_utils::to_gl_type<Component>();
|
||||
component.count = Count;
|
||||
++meta.component_count;
|
||||
}
|
||||
},
|
||||
buffers...
|
||||
);
|
||||
|
||||
for (const auto& component : std::span(meta.components).subspan(0, meta.component_count))
|
||||
{
|
||||
meta.stride += type_utils::size_of(component.type) * component.count;
|
||||
}
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
template<typename C, typename... Ts>
|
||||
void interlace(
|
||||
std::vector<ztu::u8>& vertex_buffer,
|
||||
const C components,
|
||||
std::span<Ts> buffers...
|
||||
) {
|
||||
std::array<std::size_t, sizeof...(buffers)> byte_offsets;
|
||||
auto stride = std::size_t{};
|
||||
|
||||
detail::for_enabled_components(
|
||||
components,
|
||||
[&]<class Component>(
|
||||
const std::span<Component>&,
|
||||
std::size_t index
|
||||
) {
|
||||
byte_offsets[index] = stride;
|
||||
stride += sizeof(Component);
|
||||
},
|
||||
buffers...
|
||||
);
|
||||
|
||||
const auto vertex_count = std::min({ buffers.size()... });
|
||||
const auto buffer_size = stride * vertex_count;
|
||||
|
||||
vertex_buffer.resize(buffer_size);
|
||||
|
||||
detail::for_enabled_components(
|
||||
components,
|
||||
[&]<class Component>(const std::span<Component>& buffer, std::size_t index)
|
||||
{
|
||||
const auto byte_offset = byte_offsets[index];
|
||||
for (const auto& value : buffer.subspan(0, vertex_count))
|
||||
{
|
||||
std::memcpy(
|
||||
&vertex_buffer[byte_offset],
|
||||
&value,
|
||||
sizeof(value)
|
||||
);
|
||||
byte_offset += stride;
|
||||
}
|
||||
},
|
||||
buffers...
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user