#pragma once #include #include #include "../shading/model_geometry.hpp" #include "../shading/shader_stage.hpp" #include "../shading/features/mesh_features.hpp" #include "../shading/features/point_cloud_features.hpp" #include "../shading/features/generic_features.hpp" #include // TODO move implementation to .ipp file namespace zgl { template struct shader_features_set { T features, static_enable, dynamic_enable; template [[nodiscard]] shader_features_set cast() const noexcept { return { .features = static_cast(features), .static_enable = static_cast(static_enable), .dynamic_enable = static_cast(dynamic_enable) }; } // TODO this may not compile [[nodiscard]] bool operator==(const shader_features_set& other) const noexcept = default; }; struct shader_source_metadata { union combined_feature_set_type { shader_features_set mesh; shader_features_set point_cloud; }; using generic_feature_set_type = shader_features_set; shading::model_geometry::types geometry; combined_feature_set_type feature_set; shading::stage::types stage; [[nodiscard]] generic_feature_set_type generic_feature_set() const noexcept { switch (geometry) { case shading::model_geometry::types::mesh: return feature_set.mesh.cast(); case shading::model_geometry::types::point_cloud: return feature_set.point_cloud.cast(); default: std::unreachable(); } } void from_generic_feature_set(const generic_feature_set_type& generic_feature_set) noexcept { switch (geometry) { case shading::model_geometry::types::mesh: feature_set.mesh = generic_feature_set.cast(); case shading::model_geometry::types::point_cloud: feature_set.point_cloud = generic_feature_set.cast(); } std::unreachable(); } bool operator==(const shader_source_metadata& other) const noexcept { if (this->stage != other.stage) { return false; } if (this->geometry != other.geometry) { return false; } return this->generic_feature_set() == other.generic_feature_set(); } }; }