Program Listing for File Material.hpp

↰ Return to documentation for file (engine/include/Cacao/Material.hpp)

#pragma once

#include "Cacao/Exceptions.hpp"
#include "Cubemap.hpp"
#include "DllHelper.hpp"
#include "Resource.hpp"
#include "Shader.hpp"
#include "Tex2D.hpp"

#include "libcacaoasset.hpp"

#include "glm/glm.hpp"

#include <memory>
#include <variant>

template<typename T, typename Variant>
struct is_variant_alternative : std::false_type {};

template<typename T, typename... Ts>
struct is_variant_alternative<T, std::variant<Ts...>>
  : std::bool_constant<(std::same_as<T, Ts> || ...)> {};

template<typename T, typename Variant>
inline constexpr bool is_variant_alternative_v =
    is_variant_alternative<T, Variant>::value;

namespace Cacao {
    class CACAO_API Material : public Resource {
      public:
        using ParamValue = std::variant<int, unsigned int, float, bool, glm::ivec2, glm::ivec3, glm::ivec4,
            glm::uvec2, glm::uvec3, glm::uvec4, glm::vec2, glm::vec3, glm::vec4, glm::mat2, glm::mat3, glm::mat4, std::shared_ptr<Tex2D>, std::shared_ptr<Cubemap>>;

        static std::shared_ptr<Material> Create(std::shared_ptr<Shader> shader, const std::string& addr);

        Material(const Material&) = delete;
        Material(Material&&);
        Material& operator=(const Material&) = delete;
        Material& operator=(Material&&);

        std::shared_ptr<Shader> GetShader();

        template<typename T>
            requires is_variant_alternative_v<T, ParamValue>
        void SetParameter(const std::string& name, const T& value) {
            _SetParam(name, value);
        }

        template<typename T>
            requires is_variant_alternative_v<T, ParamValue>
        T GetParameter(const std::string& name) {
            ParamValue pv = _GetParam(name);
            Check<BadTypeException>(std::holds_alternative<T>(pv), "Cannot get parameter from material with wrong type!");
            return std::get<T>(pv);
        }

        void SetRenderMode(libcacaoasset::Material::RenderMode mode);

        libcacaoasset::Material::RenderMode GetRenderMode();

        class Impl;

        ~Material();

      private:
        Material(std::shared_ptr<Shader> shader, const std::string& addr);
        friend class ResourceManager;
        friend class PAL;

        void _SetParam(const std::string& name, const ParamValue& value);
        ParamValue _GetParam(const std::string& name);

        std::unique_ptr<Impl> impl;
        friend class ImplAccessor;
    };
}