#pragma once #include "../../DataView.hpp" #include "../../utils.hpp" #include "../../Result.hpp" #include "CommonShader.hpp" #include "ShaderVec.hpp" #include #include #include #include #include namespace amalgine { class PixelShaderTooManyAttributes : public std::runtime_error { public: PixelShaderTooManyAttributes(i32 maxPixelAttributes); }; class PixelShaderAttributeAlreadyDefined : public std::runtime_error { public: PixelShaderAttributeAlreadyDefined(const std::string &attributeName); }; class PixelShaderInvalidAttributeName : public std::runtime_error { public: PixelShaderInvalidAttributeName(const std::string &attributeName); }; class PixelShaderFunctionAlreadyDefined : public std::runtime_error { public: PixelShaderFunctionAlreadyDefined(const std::string &funcName); }; using PixelShaderMainFunc = std::function; /* * Using the same PixelShader instance in multiple threads to define data is not thread safe. * All get*** functions are thread safe. */ class CompiledPixelShader; class PixelShader { DISABLE_COPY(PixelShader) friend class ShaderProgram; public: PixelShader(); const std::string& getOutputAttributeName(i32 attributeIndex); ShaderOutputVec4 defineOutputVec4(const std::string &name); void defineMain(PixelShaderMainFunc mainFunc); void assign(const ShaderOutputVec4 &lhsVariable, const ShaderVec4 &rhsVariable); Result compile(); private: void writeHeader(const std::string &code); void writeBody(const std::string &code); std::string build() const; /* * Throws PixelShaderTooManyAttributes if too many pixel attributes are defined for the platform. * Throws PixelShaderAttributeAlreadyDefined if a pixel attribute with the same name has already been defined. */ i32 defineOutputVariable(const std::string &variableName, const char *typeName); private: std::string header; std::string body; int locationCounter; i32 maxPixelAttribs; // Could make this static std::unordered_map pixelAttributes; std::vector pixelAttributeNames; bool mainFuncDefined; }; }