tried making naming more uniform and implemented most of the opengl managers

This commit is contained in:
ZY4N
2025-03-25 02:22:44 +01:00
parent c609d49f0d
commit 71ea2d9237
155 changed files with 4097 additions and 2434 deletions

View File

@@ -1,133 +1,115 @@
#include "opengl/data_managers/mesh_vertex_buffer_manager.hpp"
#include "util/logger.hpp"
#include "opengl/error.hpp"
#include "opengl/vertex_buffer_utils.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
if (not m_resource_manager.has_resource(id))
{
m_mesh_buffer.emplace_back(id, mesh);
}
}
}
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)
m_buffer_id_buffer.resize(m_mesh_buffer.size());
glGenBuffers(m_buffer_id_buffer.size(), m_buffer_id_buffer.data());
if (const auto e = get_error())
{
return std::apply(
[&](const auto&... component_buffer)
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_mesh_buffer, m_buffer_id_buffer))
{
auto [ store_id, mesh ] = entry;
m_byte_buffer.clear();
std::apply(
[&](const auto&... component_buffers)
{
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;
vertex_buffer_utils::interlace(m_byte_buffer, mesh.component_flags, component_buffers...);
},
m_component_buffers
mesh.vertex_component_arrays
);
};
component_count = 0;
component_types = for_all_components(
ztu::specialised_lambda
glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
if (const auto e = get_error())
{
[&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 }
);
ztu::logger::error("Error while binding vertex buffer %: %.", buffer_id, e.message());
continue;
}
const auto element_counts = for_all_components(
[]<class Component>(const std::vector<Component>& buffer, std::size_t)
glBufferData(
GL_ARRAY_BUFFER,
static_cast<GLsizeiptr>(m_byte_buffer.size()),
m_byte_buffer.data(),
GL_STATIC_DRAW
);
if (const auto e = get_error())
{
return buffer.size();
},
std::numeric_limits<std::size_t>::max()
);
ztu::logger::error("Error while setting vertex buffer data: %.", e.message());
continue;
}
const auto minimum_element_count = std::ranges::min(element_counts);
const auto meta = mesh_vertex_buffer_metadata{
.component_flags = mesh.component_flags,
.material_id = mesh.material_id
};
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 }
);
m_resource_manager.add_resource(store_id, buffer_id, meta);
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]);
buffer_id = {};
}
const auto total_size = minimum_element_count * std::accumulate(
component_sizes.begin(),
component_sizes.end(),
GLsizei{ 0 }
);
glBindBuffer(GL_ARRAY_BUFFER, 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;
},
const auto valid_buffer_ids = std::ranges::remove(
m_buffer_id_buffer,
0
);
// remove values of unused components
std::ignore = std::ranges::remove(component_lengths, 0);
std::ignore = std::ranges::remove(component_types, GL_INVALID_VALUE);
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::mesh_vertex_buffer_manager::handle_type> zgl::mesh_vertex_buffer_manager::get_handle(
const store_id_type id
) {
return m_resource_manager
.get_resource(id)
.transform(
[](auto& resource)
{
return *reinterpret_cast<handle_type*>(resource);
}
);
}
void zgl::mesh_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()
);
}
}