#pragma once #include "../../DataView.hpp" #include "ShaderVec.hpp" #include #include #include #include #include namespace amalgine { class VertexShaderTooManyAttributes : public std::runtime_error { public: VertexShaderTooManyAttributes(i32 maxVertexAttributes); }; class VertexShaderAttributeAlreadyDefined : public std::runtime_error { public: VertexShaderAttributeAlreadyDefined(const std::string &attributeName); }; class VertexShaderInvalidAttributeName : public std::runtime_error { public: VertexShaderInvalidAttributeName(const std::string &attributeName); }; class VertexShaderFunctionAlreadyDefined : public std::runtime_error { public: VertexShaderFunctionAlreadyDefined(const std::string &funcName); }; using VertexShaderMainFunc = std::function; /* * Using the same VertexShader instance in multiple threads to define data is not thread safe. * All get*** functions are thread safe. */ class VertexShader { public: VertexShader(); const std::string& getInputAttributeName(i32 attributeIndex); ShaderInputVec2 defineInputVec2(const std::string &name); void defineMain(VertexShaderMainFunc mainFunc); std::string build() const; private: void writeHeader(const std::string &code); void writeBody(const std::string &code); /* * Throws VertexShaderTooManyInputAttributes if too many vertex attributes are defined for the platform. * Throws VertexShaderAttributeAlreadyDefined if a vertex attribute with the same name has already been defined. */ i32 defineInputVariable(const std::string &variableName, const char *typeName); private: std::string header; std::string body; int locationCounter; i32 maxVertexAttribs; // Could make this static std::unordered_map vertexAttributes; std::vector vertexAttributeNames; bool mainFuncDefined; }; }