aboutsummaryrefslogtreecommitdiff
path: root/include/RenderBackend
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2017-12-20 20:55:05 +0100
committerdec05eba <dec05eba@protonmail.com>2021-11-18 15:21:46 +0100
commitca92d8c90f7103db6d7cae4cef49b278d804b474 (patch)
treebaf44e42fcc1cf7e871a7b2f1d3d92f680f3a845 /include/RenderBackend
parent3d7f123c0fc0af4b8df3ad791b264d22268bd423 (diff)
Create shader using c++ code
Diffstat (limited to 'include/RenderBackend')
-rw-r--r--include/RenderBackend/OpenGL/CommonShader.hpp33
-rw-r--r--include/RenderBackend/OpenGL/DeviceMemory.hpp27
-rw-r--r--include/RenderBackend/OpenGL/PixelShader.hpp71
-rw-r--r--include/RenderBackend/OpenGL/ShaderVec.hpp81
-rw-r--r--include/RenderBackend/OpenGL/VertexShader.hpp70
-rw-r--r--include/RenderBackend/OpenGL/opengl.hpp5
6 files changed, 287 insertions, 0 deletions
diff --git a/include/RenderBackend/OpenGL/CommonShader.hpp b/include/RenderBackend/OpenGL/CommonShader.hpp
new file mode 100644
index 0000000..a67aa68
--- /dev/null
+++ b/include/RenderBackend/OpenGL/CommonShader.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+namespace amalgine
+{
+ static bool isAlpha(char c)
+ {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+ }
+
+ static bool isDigit(char c)
+ {
+ return c >= '0' && c <= '9';
+ }
+
+ static bool isShaderVariableNameValid(const char *variableName)
+ {
+ const char *p = &variableName[0];
+ if(isAlpha(*p) || *p == '_')
+ {
+ ++p;
+ while(true)
+ {
+ char c = *p;
+ if(c == '\0')
+ return true;
+ else if(isAlpha(c) || isDigit(c) || c == '_')
+ ++p;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/include/RenderBackend/OpenGL/DeviceMemory.hpp b/include/RenderBackend/OpenGL/DeviceMemory.hpp
new file mode 100644
index 0000000..706529e
--- /dev/null
+++ b/include/RenderBackend/OpenGL/DeviceMemory.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "../../DataView.hpp"
+#include "../../utils.hpp"
+
+namespace amalgine
+{
+ class DeviceMemory
+ {
+ DISABLE_COPY(DeviceMemory)
+ public:
+ DeviceMemory();
+
+ // Uploaded once, drawn many times
+ void copyStatic(const DataView<f32> &data);
+
+ // Created once, changed from time to time but drawn many times more than that
+ void copyDynamic(const DataView<f32> &data);
+
+ // Uploaded once, drawn once (for example data that is changed every frame)
+ void copyStream(const DataView<f32> &data);
+ private:
+ void copy(const DataView<f32> &data, i32 storageType);
+ private:
+ u32 vertexBufferObjectId;
+ };
+}
diff --git a/include/RenderBackend/OpenGL/PixelShader.hpp b/include/RenderBackend/OpenGL/PixelShader.hpp
new file mode 100644
index 0000000..3d33155
--- /dev/null
+++ b/include/RenderBackend/OpenGL/PixelShader.hpp
@@ -0,0 +1,71 @@
+#pragma once
+
+#include "../../DataView.hpp"
+#include "ShaderVec.hpp"
+#include <string>
+#include <unordered_map>
+#include <vector>
+#include <stdexcept>
+#include <functional>
+
+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<void()>;
+
+ /*
+ * Using the same PixelShader instance in multiple threads to define data is not thread safe.
+ * All get*** functions are thread safe.
+ */
+ class PixelShader
+ {
+ 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();
+ private:
+ void writeHeader(const std::string &code);
+ void writeBody(const std::string &code);
+
+ /*
+ * 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<std::string> pixelAttributeNames;
+ bool mainFuncDefined;
+ };
+}
diff --git a/include/RenderBackend/OpenGL/ShaderVec.hpp b/include/RenderBackend/OpenGL/ShaderVec.hpp
new file mode 100644
index 0000000..10e628c
--- /dev/null
+++ b/include/RenderBackend/OpenGL/ShaderVec.hpp
@@ -0,0 +1,81 @@
+#pragma once
+
+#include "../../types.hpp"
+#include <string>
+
+namespace amalgine
+{
+ class VertexShader;
+ class PixelShader;
+
+ class ShaderInputVec2
+ {
+ friend class VertexShader;
+ public:
+ const std::string& getName() const;
+ private:
+ ShaderInputVec2(VertexShader *_vertexShader, i32 _attributeIndex) :
+ vertexShader(_vertexShader),
+ attributeIndex(_attributeIndex)
+ {
+
+ }
+ private:
+ VertexShader *vertexShader;
+ i32 attributeIndex;
+ };
+
+ class ShaderVec4
+ {
+ public:
+ ShaderVec4(f32 x = 0.0f, f32 y = 0.0f, f32 z = 0.0f, f32 w = 0.0f)
+ {
+ result = "vec4(";
+ result += std::to_string(x);
+ result += ", ";
+ result += std::to_string(y);
+ result += ", ";
+ result += std::to_string(z);
+ result += ", ";
+ result += std::to_string(w);
+ result += ")";
+ }
+
+ ShaderVec4(const ShaderInputVec2 &vec2, f32 z = 0.0f, f32 w = 0.0f)
+ {
+ result = "vec4(";
+ result += vec2.getName();
+ result += ", ";
+ result += std::to_string(z);
+ result += ", ";
+ result += std::to_string(w);
+ result += ")";
+ }
+
+ const std::string& getOutput() const
+ {
+ return result;
+ }
+ private:
+ std::string result;
+ };
+
+ class ShaderOutputVec4
+ {
+ friend class PixelShader;
+ public:
+ const std::string& getName() const;
+
+ void operator=(const ShaderVec4 &shaderVec4);
+ private:
+ ShaderOutputVec4(PixelShader *_pixelShader, i32 _attributeIndex) :
+ pixelShader(_pixelShader),
+ attributeIndex(_attributeIndex)
+ {
+
+ }
+ private:
+ PixelShader *pixelShader;
+ i32 attributeIndex;
+ };
+}
diff --git a/include/RenderBackend/OpenGL/VertexShader.hpp b/include/RenderBackend/OpenGL/VertexShader.hpp
new file mode 100644
index 0000000..ec8be22
--- /dev/null
+++ b/include/RenderBackend/OpenGL/VertexShader.hpp
@@ -0,0 +1,70 @@
+#pragma once
+
+#include "../../DataView.hpp"
+#include "ShaderVec.hpp"
+#include <string>
+#include <unordered_map>
+#include <vector>
+#include <stdexcept>
+#include <functional>
+
+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<ShaderVec4()>;
+
+ /*
+ * 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();
+ 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<std::string, i32> vertexAttributes;
+ std::vector<std::string> vertexAttributeNames;
+ bool mainFuncDefined;
+ };
+}
diff --git a/include/RenderBackend/OpenGL/opengl.hpp b/include/RenderBackend/OpenGL/opengl.hpp
new file mode 100644
index 0000000..6ea8fcb
--- /dev/null
+++ b/include/RenderBackend/OpenGL/opengl.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <GL/glew.h>
+#include <GLFW/glfw3.h>
+#include <glm/glm.hpp>