100 lines
2.2 KiB
C++
100 lines
2.2 KiB
C++
#include "opengl/data/point_cloud_data.hpp"
|
|
|
|
#include "opengl/type_utils.hpp"
|
|
#include "opengl/error.hpp"
|
|
|
|
#include <algorithm>
|
|
#include "GL/glew.h"
|
|
|
|
std::error_code zgl::point_cloud_data::build_from(
|
|
std::span<const std::uint8_t> point_buffer,
|
|
std::span<const GLenum> component_types,
|
|
std::span<const GLint> component_lengths,
|
|
GLsizei stride,
|
|
point_cloud_data& data
|
|
) {
|
|
if (not std::ranges::all_of(component_types, type_utils::is_valid_type))
|
|
{
|
|
return std::make_error_code(std::errc::invalid_argument);
|
|
}
|
|
|
|
const auto points_byte_count = point_buffer.size() * sizeof(std::uint8_t);
|
|
if (points_byte_count > std::numeric_limits<GLsizeiptr>::max())
|
|
{
|
|
return std::make_error_code(std::errc::value_too_large);
|
|
}
|
|
|
|
auto error = std::error_code{};
|
|
|
|
auto check_error = [&error, ec = static_cast<GLenum>(GL_NO_ERROR)]() mutable -> const std::error_code&
|
|
{
|
|
ec = glGetError();
|
|
if (ec != GL_NO_ERROR) {
|
|
error = make_error_code(ec);
|
|
}
|
|
return error;
|
|
};
|
|
|
|
ztu::u32 vao_id;
|
|
glGenVertexArrays(1, &vao_id);
|
|
if (check_error()) return error;
|
|
|
|
glBindVertexArray(vao_id);
|
|
if (check_error()) return error;
|
|
|
|
ztu::u32 vertex_buffer_id;
|
|
glGenBuffers(1, &vertex_buffer_id);
|
|
if (check_error()) return error;
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id);
|
|
if (check_error()) return error;
|
|
|
|
glBufferData(
|
|
GL_ARRAY_BUFFER,
|
|
static_cast<GLsizeiptr>(points_byte_count),
|
|
point_buffer.data(),
|
|
GL_STATIC_DRAW
|
|
);
|
|
if (check_error()) return error;
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id);
|
|
if (check_error()) return error;
|
|
|
|
auto offset = GLsizei{ 0 };
|
|
|
|
for (std::size_t i{}; i != component_types.size(); ++i)
|
|
{
|
|
const auto type = component_types[i];
|
|
const auto length = component_lengths[i];
|
|
const auto byte_count = type_utils::size_of(type);
|
|
|
|
glVertexAttribPointer(
|
|
i,
|
|
length,
|
|
type,
|
|
GL_FALSE,
|
|
stride,
|
|
reinterpret_cast<GLvoid*>(offset)
|
|
);
|
|
if (check_error()) return error;
|
|
glEnableVertexAttribArray(i);
|
|
if (check_error()) return error;
|
|
|
|
offset += length * byte_count;
|
|
}
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
if (check_error()) return error;
|
|
glBindVertexArray(0);
|
|
if (check_error()) return error;
|
|
|
|
data = point_cloud_data(
|
|
vertex_buffer_id,
|
|
vao_id,
|
|
point_buffer.size()
|
|
);
|
|
|
|
return {};
|
|
}
|