114 lines
2.7 KiB
C++
114 lines
2.7 KiB
C++
#include "opengl/data_managers/mesh_vertex_buffer_manager.hpp"
|
|
|
|
#include "util/logger.hpp"
|
|
#include "opengl/error.hpp"
|
|
#include "opengl/type_utils.hpp"
|
|
|
|
|
|
void zgl::mesh_vertex_buffer_manager::process(const store_type& meshes)
|
|
{
|
|
for (const auto& [ id, mesh ] : meshes)
|
|
{
|
|
if (not m_resource_manager.has_resource(id))
|
|
{
|
|
m_mesh_buffer.emplace_back(id, mesh);
|
|
}
|
|
}
|
|
|
|
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())
|
|
{
|
|
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();
|
|
|
|
type_utils::interlace_vertex_buffer(
|
|
m_byte_buffer,
|
|
mesh.component_flags,
|
|
mesh.vertex_count,
|
|
mesh.vertex_component_arrays
|
|
);
|
|
|
|
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<GLsizeiptr>(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;
|
|
}
|
|
|
|
auto meta = mesh_vertex_buffer_metadata{
|
|
.component_flags = mesh.component_flags,
|
|
.material = stores.materials.find(mesh.material_id)
|
|
};
|
|
|
|
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::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()
|
|
);
|
|
}
|
|
} |