130 lines
3.6 KiB
C++
130 lines
3.6 KiB
C++
#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>& texture_handle,
|
|
const std::optional<surface_properties_handle>& surface_properties_handle,
|
|
const std::optional<alpha_handle>& alpha_handle,
|
|
std::optional<texture_data>&& 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<material_component::texture::value_type>& texture_opt,
|
|
const std::optional<material_component::surface_properties::value_type>& surface_properties_opt,
|
|
const std::optional<material_component::transparency::value_type>& transparency_opt,
|
|
const material_component::flags components,
|
|
material_data& dst_data
|
|
) {
|
|
|
|
auto texture_data_opt = std::optional<texture_data>{ std::nullopt };
|
|
auto texture_handle_opt = std::optional<texture_handle>{ 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<surface_properties_handle>{ 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<alpha_handle>{ 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 {};
|
|
}
|
|
}
|