diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/RenderBackend/OpenGL/CommonShader.hpp | 11 | ||||
-rw-r--r-- | include/RenderBackend/OpenGL/CompiledShader.hpp | 30 | ||||
-rw-r--r-- | include/RenderBackend/OpenGL/DeviceMemory.hpp | 7 | ||||
-rw-r--r-- | include/RenderBackend/OpenGL/PixelShader.hpp | 23 | ||||
-rw-r--r-- | include/RenderBackend/OpenGL/ShaderProgram.hpp | 40 | ||||
-rw-r--r-- | include/RenderBackend/OpenGL/ShaderVec.hpp | 8 | ||||
-rw-r--r-- | include/RenderBackend/OpenGL/VertexShader.hpp | 9 | ||||
-rw-r--r-- | include/Result.hpp | 11 |
8 files changed, 110 insertions, 29 deletions
diff --git a/include/RenderBackend/OpenGL/CommonShader.hpp b/include/RenderBackend/OpenGL/CommonShader.hpp index a67aa68..80e63a9 100644 --- a/include/RenderBackend/OpenGL/CommonShader.hpp +++ b/include/RenderBackend/OpenGL/CommonShader.hpp @@ -1,7 +1,16 @@ #pragma once +#include "../../types.hpp" +#include <string> + namespace amalgine { + struct ShaderAttribute + { + std::string name; + const char *typeName; + }; + static bool isAlpha(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); @@ -30,4 +39,6 @@ namespace amalgine return false; } + + std::string getShaderCompileLog(u32 shaderId); } diff --git a/include/RenderBackend/OpenGL/CompiledShader.hpp b/include/RenderBackend/OpenGL/CompiledShader.hpp new file mode 100644 index 0000000..67e6418 --- /dev/null +++ b/include/RenderBackend/OpenGL/CompiledShader.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "../../types.hpp" + +namespace amalgine +{ + class CompiledVertexShader + { + friend class VertexShader; + public: + ~CompiledVertexShader(); + u32 getShaderId() const; + private: + CompiledVertexShader(u32 _shaderId); + private: + u32 shaderId; + }; + + class CompiledPixelShader + { + friend class PixelShader; + public: + ~CompiledPixelShader(); + u32 getShaderId() const; + private: + CompiledPixelShader(u32 _shaderId); + private: + u32 shaderId; + }; +} diff --git a/include/RenderBackend/OpenGL/DeviceMemory.hpp b/include/RenderBackend/OpenGL/DeviceMemory.hpp index 706529e..974c7cf 100644 --- a/include/RenderBackend/OpenGL/DeviceMemory.hpp +++ b/include/RenderBackend/OpenGL/DeviceMemory.hpp @@ -10,15 +10,16 @@ namespace amalgine DISABLE_COPY(DeviceMemory) public: DeviceMemory(); + ~DeviceMemory(); // Uploaded once, drawn many times - void copyStatic(const DataView<f32> &data); + void copyAsStatic(const DataView<f32> &data); // Created once, changed from time to time but drawn many times more than that - void copyDynamic(const DataView<f32> &data); + void copyAsDynamic(const DataView<f32> &data); // Uploaded once, drawn once (for example data that is changed every frame) - void copyStream(const DataView<f32> &data); + void copyAsStream(const DataView<f32> &data); private: void copy(const DataView<f32> &data, i32 storageType); private: diff --git a/include/RenderBackend/OpenGL/PixelShader.hpp b/include/RenderBackend/OpenGL/PixelShader.hpp index b869a8f..e025c6f 100644 --- a/include/RenderBackend/OpenGL/PixelShader.hpp +++ b/include/RenderBackend/OpenGL/PixelShader.hpp @@ -1,6 +1,9 @@ #pragma once #include "../../DataView.hpp" +#include "../../utils.hpp" +#include "../../Result.hpp" +#include "CommonShader.hpp" #include "ShaderVec.hpp" #include <string> #include <unordered_map> @@ -40,20 +43,38 @@ namespace amalgine * 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); - std::string build() const; + Result<CompiledPixelShader*> 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<std::string, i32> pixelAttributes; + std::vector<ShaderAttribute> pixelAttributeNames; bool mainFuncDefined; }; } diff --git a/include/RenderBackend/OpenGL/ShaderProgram.hpp b/include/RenderBackend/OpenGL/ShaderProgram.hpp index efeae5b..a3e8a0f 100644 --- a/include/RenderBackend/OpenGL/ShaderProgram.hpp +++ b/include/RenderBackend/OpenGL/ShaderProgram.hpp @@ -1,34 +1,38 @@ #pragma once -#include "VertexShader.hpp" -#include "PixelShader.hpp" #include "../../Result.hpp" #include "../../types.hpp" +#include "../../utils.hpp" #include <vector> +#include <stdexcept> namespace amalgine { + class CompiledVertexShader; + class CompiledPixelShader; + + class ShaderProgramUsedBeforeBuilt : public std::runtime_error + { + public: + // TODO: Add name to ShaderProgram so we know which shader has issue when + // an exception is thrown? + ShaderProgramUsedBeforeBuilt(); + }; + class ShaderProgram { + DISABLE_COPY(ShaderProgram) public: ShaderProgram(); + ~ShaderProgram(); - const std::string& getOutputAttributeName(i32 attributeIndex); - ShaderOutputVec4 defineOutputVec4(const std::string &name); - //Result<std::string> addVertexShader(const VertexShader &vertexShader); - //Result<std::string> addPixelShader(const PixelShader &pixelShader); - //void build(); - private: - /* - * 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); + bool addVertexShader(CompiledVertexShader *vertexShader); + bool addPixelShader(CompiledPixelShader *pixelShader); + + Result<bool> build(); + void use(); private: - int locationCounter; - i32 maxPixelAttribs; // Could make this static - std::unordered_map<std::string, i32> pixelAttributes; - std::vector<std::string> pixelAttributeNames; - std::vector<u32> shaderIds; + u32 shaderProgramId; + bool built; }; } diff --git a/include/RenderBackend/OpenGL/ShaderVec.hpp b/include/RenderBackend/OpenGL/ShaderVec.hpp index 0c0a88a..10e628c 100644 --- a/include/RenderBackend/OpenGL/ShaderVec.hpp +++ b/include/RenderBackend/OpenGL/ShaderVec.hpp @@ -6,7 +6,7 @@ namespace amalgine { class VertexShader; - class ShaderProgram; + class PixelShader; class ShaderInputVec2 { @@ -62,20 +62,20 @@ namespace amalgine class ShaderOutputVec4 { - friend class ShaderProgram; + friend class PixelShader; public: const std::string& getName() const; void operator=(const ShaderVec4 &shaderVec4); private: - ShaderOutputVec4(ShaderProgram *_pixelShader, i32 _attributeIndex) : + ShaderOutputVec4(PixelShader *_pixelShader, i32 _attributeIndex) : pixelShader(_pixelShader), attributeIndex(_attributeIndex) { } private: - ShaderProgram *shaderProgram; + PixelShader *pixelShader; i32 attributeIndex; }; } diff --git a/include/RenderBackend/OpenGL/VertexShader.hpp b/include/RenderBackend/OpenGL/VertexShader.hpp index 3239be2..43a5dd8 100644 --- a/include/RenderBackend/OpenGL/VertexShader.hpp +++ b/include/RenderBackend/OpenGL/VertexShader.hpp @@ -1,6 +1,8 @@ #pragma once #include "../../DataView.hpp" +#include "../../utils.hpp" +#include "../../Result.hpp" #include "ShaderVec.hpp" #include <string> #include <unordered_map> @@ -40,18 +42,23 @@ namespace amalgine * Using the same VertexShader instance in multiple threads to define data is not thread safe. * All get*** functions are thread safe. */ + class CompiledVertexShader; + class VertexShader { + DISABLE_COPY(VertexShader) + friend class ShaderProgram; public: VertexShader(); const std::string& getInputAttributeName(i32 attributeIndex); ShaderInputVec2 defineInputVec2(const std::string &name); void defineMain(VertexShaderMainFunc mainFunc); - std::string build() const; + Result<CompiledVertexShader*> compile(); private: void writeHeader(const std::string &code); void writeBody(const std::string &code); + std::string build() const; /* * Throws VertexShaderTooManyInputAttributes if too many vertex attributes are defined for the platform. diff --git a/include/Result.hpp b/include/Result.hpp index 316e45a..749d381 100644 --- a/include/Result.hpp +++ b/include/Result.hpp @@ -1,6 +1,7 @@ #pragma once #include <string> +#include <cassert> namespace amalgine { @@ -28,16 +29,22 @@ namespace amalgine static Result<T> Err(const Result<OtherType> &otherResult) { Result<T> result; - result.errorMsg = otherResult.errorMsg; - result.errorCode = otherResult.errorCode; + result.errorMsg = otherResult.getErrorMsg(); + result.errorCode = otherResult.getErrorCode(); return result; } bool isOk() const { return errorCode == 0; } bool isErr() const { return !isOk(); } operator bool() const { return isOk(); } + T& unwrap() + { + assert(isOk()); + return data; + } const std::string& getErrorMsg() const { return errorMsg; } + int getErrorCode() const { return errorCode; } private: Result(){} private: |