#ifndef INCLUDE_MATERIAL_DATA_IMPLEMENTATION # error Never include this file directly include 'material_data.hpp' #endif namespace zgl { inline material_data::material_data( const std::optional& texture_handle, const std::optional& surface_properties_handle, const std::optional& alpha_handle, std::optional&& texture_data, const material_component::flags components ) : m_handle{ .texture = texture_handle, .surface_properties = surface_properties_handle, .alpha = alpha_handle }, m_texture_data{ std::move(texture_data) }, m_component_types{ components } {} inline material_data::material_data(material_data&& other) noexcept { m_handle = other.m_handle; m_texture_data = std::move(other.m_texture_data); m_component_types = other.m_component_types; other.m_handle.texture = std::nullopt; other.m_handle.surface_properties = std::nullopt; other.m_handle.alpha = std::nullopt; other.m_component_types = material_component::flags::none; } inline material_data& material_data::operator=(material_data&& other) noexcept { if (&other != this) { this->~material_data(); m_handle = other.m_handle; m_texture_data = std::move(other.m_texture_data); m_component_types = other.m_component_types; other.m_handle.texture = std::nullopt; other.m_handle.surface_properties = std::nullopt; other.m_handle.alpha = std::nullopt; other.m_component_types = material_component::flags::none; } return *this; } inline material_handle material_data::handle() const { return m_handle; } inline material_component::flags material_data::components() const { return m_component_types; } inline std::error_code material_data::build_from( const std::optional& texture_opt, const std::optional& surface_properties_opt, const std::optional& transparency_opt, const material_component::flags components, material_data& dst_data ) { auto texture_data_opt = std::optional{ std::nullopt }; auto texture_handle_opt = std::optional{ std::nullopt }; if (texture_opt) { const auto& texture = *texture_opt; auto texture_data = zgl::texture_data{}; if (const auto e = texture_data::build_from( std::span(texture.cbegin(), texture.cend()), GL_RGBA, GL_UNSIGNED_BYTE, texture.width(), texture.height(), texture_data )) { return e; } texture_handle_opt.emplace(texture_data.handle()); texture_data_opt.emplace(std::move(texture_data)); } auto surface_properties_data_opt = std::optional{ std::nullopt }; if (surface_properties_opt) { const auto& [ ambient, diffuse, specular, shininess ] = *surface_properties_opt; surface_properties_data_opt.emplace( glm::vec3{ ambient[0], ambient[1], ambient[2] }, glm::vec3{ diffuse[0], diffuse[1], diffuse[2] }, glm::vec3{ specular[0], specular[1], specular[2] }, shininess ); } auto alpha_data_opt = std::optional{ std::nullopt }; if (transparency_opt) { alpha_data_opt.emplace(1.0f - *transparency_opt); } /*dst_data = material_data{ texture_handle_opt, surface_properties_data_opt, alpha_data_opt, std::move(texture_data_opt), components };*/ dst_data.m_handle.texture = texture_handle_opt; dst_data.m_handle.surface_properties = surface_properties_data_opt; dst_data.m_handle.alpha = alpha_data_opt; dst_data.m_texture_data = std::move(texture_data_opt); dst_data.m_component_types = components; return {}; } }