#pragma once #include #include #include #include #include namespace kuiper { namespace gl { enum class shader_type : std::uint8_t { none = 0, vertex, fragment, compute }; class shader { public: using s_ptr = std::shared_ptr; explicit shader(GLuint id, GLenum type) : m_id(id), m_type(type) {} ~shader() { destroy(); } shader(const shader& other) = delete; shader& operator=(const shader& other) = delete; shader(shader&& other) noexcept = default; shader& operator=(shader&& other) noexcept = default; static s_ptr make(shader_type type) noexcept; static s_ptr from_path(const std::filesystem::path& shader_path, shader_type type = shader_type::none) noexcept; static s_ptr from_source(std::string_view source, shader_type type) noexcept; public: void destroy() noexcept; void attach_source(std::string_view source) noexcept; void compile() noexcept; GLuint id() const noexcept { return m_id; } private: GLuint m_id {0}; GLenum m_type {0}; }; } // namespace gl } // namespace kuiper