#pragma once #include "RcPtr.hpp" #include #include #include class ShaderDetails : public RefCounted { public: }; class Shader : public RefCounted { private: 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); struct ShaderFilePaths { const char* vertex = nullptr; const char* geometry = nullptr; const char* tessControl = nullptr; const char* tessEval = nullptr; const char* fragment = nullptr; }; /// Create shader by loading each specified file and combining them together to form a shader object. /// Use the mental model that this function simply loads the files from disk (synchronously) and then /// passing them to `FromSource(const ShaderSources& source)`. ErrorCode InitFromFiles(const ShaderFilePaths& files); /// 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); /// Create shader by loading the file at the `file`, and then giving the contents to /// `FromSource(std::string_view source)`. ErrorCode InitFromFile(const char* file); GLuint GetProgram() const; bool IsValid() const; };