Program Listing for File Shader.hpp

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

#pragma once

#include "DllHelper.hpp"
#include "Asset.hpp"

namespace Cacao {
    struct CACAO_API ShaderDescription {
        enum class Type {
            Opaque3D,
            NonOpaque3D,
            Surface2D
        } type;

        enum class VertexInputBits : uint32_t {
            Position = 1 << 0,
            TexCoords = 1 << 1,
            Normal = 1 << 2,
            Tangent = 1 << 3,
            Bitangent = 1 << 4,
        };

        VertexInputBits vertexInputs;

        bool transformUsed;
        bool globalsUsed;

        struct CACAO_API MaterialParamInfo {
            enum class DataType {
                Int,
                UInt,
                Float,
                Bool,
                Float2,
                Float3,
                Float4,
                Int2,
                Int3,
                Int4,
                UInt2,
                UInt3,
                UInt4,
                Float2x2,
                Float3x3,
                Float4x4,

                Tex2D,
                TexCube,
            } type;

            std::string name;

            unsigned int bufferOffset;
            unsigned int binding;
        };

        std::vector<MaterialParamInfo> materialParams;
    };

    //This is to allow for VertexInputBits to work as a bitmask
    constexpr ShaderDescription::VertexInputBits operator|(ShaderDescription::VertexInputBits a, ShaderDescription::VertexInputBits b) noexcept {
        using U = std::underlying_type_t<ShaderDescription::VertexInputBits>;
        return static_cast<ShaderDescription::VertexInputBits>(
            static_cast<U>(a) | static_cast<U>(b));
    }

    constexpr ShaderDescription::VertexInputBits operator&(ShaderDescription::VertexInputBits a, ShaderDescription::VertexInputBits b) noexcept {
        using U = std::underlying_type_t<ShaderDescription::VertexInputBits>;
        return static_cast<ShaderDescription::VertexInputBits>(
            static_cast<U>(a) & static_cast<U>(b));
    }

    constexpr ShaderDescription::VertexInputBits operator~(ShaderDescription::VertexInputBits a) noexcept {
        using U = std::underlying_type_t<ShaderDescription::VertexInputBits>;
        return static_cast<ShaderDescription::VertexInputBits>(
            static_cast<U>(~static_cast<U>(a)));
    }

    constexpr ShaderDescription::VertexInputBits& operator|=(ShaderDescription::VertexInputBits& a, ShaderDescription::VertexInputBits b) noexcept {
        return a = a | b;
    }

    constexpr ShaderDescription::VertexInputBits& operator&=(ShaderDescription::VertexInputBits& a, ShaderDescription::VertexInputBits b) noexcept {
        return a = a & b;
    }

    class CACAO_API Shader : public Asset {
      public:
        static std::shared_ptr<Shader> Create(std::vector<unsigned char>&& shaderIR, ShaderDescription desc, const std::string& addr) {
            return std::shared_ptr<Shader>(new Shader(std::move(shaderIR), desc, addr));
        }

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

        void Realize();

        void DropRealized();

        class Impl;

        ~Shader();

      private:
        Shader(std::vector<unsigned char>&& shaderIR, ShaderDescription desc, const std::string& addr);
        friend class ResourceManager;
        friend class PAL;

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