#pragma once #include "EditorAttachment.hpp" #include "EditorInspector.hpp" #include "RcPtr.hpp" #include #include #include #include class ShaderDetails : public EditorAttachment, public IEditorInspectorTarget { public: std::string fileName; public: virtual void ShowInspector() override; }; class Shader : public RefCounted { private: std::unique_ptr mDetails; std::unique_ptr mEditorAttachment; GLuint mHandle = 0; public: Shader() = default; ~Shader(); Shader(const Shader&) = delete; Shader& operator=(const Shader&) = delete; Shader(Shader&&) = default; Shader& operator=(Shader&&) = default; enum ErrorCode { Success, /// Generated when Init*() functions are called on an already initialized Shader object. ShaderAlreadyCreated, /// Generated when the one-source-file text contains invalid or duplicate shader variants. InvalidShaderVariant, FileIOFailed, CompilationFailed, LinkingFailed, }; struct ShaderSources { std::string_view vertex; std::string_view geometry; std::string_view tessControl; std::string_view tessEval; std::string_view fragment; }; /// Create shader by compiling each shader source file separately and then combining them together /// into a Shader object. ErrorCode InitFromSources(const ShaderSources& sources); /// The given text will be split into different shader sections according to #type directives, /// and combined to form a Shader object. /// For OpenGL, this process involves compililng each section separately and then linking them /// together. /// /// There are a directive for each shader type /// - `#type vertex`: Vertex shader /// - `#type geometry`: Geometry shader /// - `#type tessellation_control`: Tessellation control shader /// - `#type tessellation_evaluation`: Tessellation evaluation shader /// - `#type fragment`: Fragment shader ErrorCode InitFromSource(std::string_view source); EditorAttachment* GetEditorAttachment() const { return mEditorAttachment.get(); } void SetEditorAttachment(EditorAttachment* attachment) { mEditorAttachment.reset(attachment); } void GatherDetailsIfAbsent(); const ShaderDetails* GetDetails() const; GLuint GetProgram() const; bool IsValid() const; }; class ShaderManager { public: static inline ShaderManager* instance = nullptr; private: tsl::array_map> mShaders; public: void DiscoverShaders(); const tsl::array_map>& GetShaders() const { return mShaders; } Shader* FindShader(std::string_view name); };