#include "opengl/data/mesh_data.hpp" #include "opengl/type_utils.hpp" #include "opengl/error.hpp" #include "GL/glew.h" #include #include "util/logger.hpp" // TODO remove std::error_code zgl::mesh_data::build_from( const std::span vertex_buffer, const std::span component_types, const std::span component_lengths, const GLsizei stride, const std::span index_buffer, const ztu::u32 material_id, const components::mesh_vertex::flags components, mesh_data& data ) { if (not std::ranges::all_of(component_types, type_utils::is_valid_type)) { ztu::logger::debug("not all types valid."); return std::make_error_code(std::errc::invalid_argument); } const auto vertices_byte_count = vertex_buffer.size() * sizeof(std::uint8_t); if (vertices_byte_count > std::numeric_limits::max()) { return std::make_error_code(std::errc::value_too_large); } const auto indices_byte_count = index_buffer.size() * sizeof(ztu::u32); if (indices_byte_count > std::numeric_limits::max()) { return std::make_error_code(std::errc::value_too_large); } auto error = std::error_code{}; auto check_error = [&error, ec = static_cast(GL_NO_ERROR)]() mutable -> const std::error_code& { ec = glGetError(); if (ec != GL_NO_ERROR) { error = make_error_code(ec); } return error; }; GLuint vao_id; glGenVertexArrays(1, &vao_id); glBindVertexArray(vao_id); if (check_error()) return error; ztu::logger::debug("Created mesh vao: % valid: %", vao_id, (bool)glIsVertexArray(vao_id)); GLuint vertex_buffer_id; glGenBuffers(1, &vertex_buffer_id); glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id); glBufferData( GL_ARRAY_BUFFER, static_cast(vertices_byte_count), vertex_buffer.data(), GL_STATIC_DRAW ); if (check_error()) return error; GLuint index_buffer_id; glGenBuffers(1, &index_buffer_id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id); glBufferData( GL_ELEMENT_ARRAY_BUFFER, static_cast(indices_byte_count), index_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(offset) ); glEnableVertexAttribArray(i); if (check_error()) return error; offset += length * byte_count; } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); data = mesh_data( vertex_buffer_id, index_buffer_id, vao_id, material_id, components, index_buffer.size() ); return {}; }