aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-11-04 00:50:45 +0100
committerdec05eba <dec05eba@protonmail.com>2021-11-18 15:21:48 +0100
commit23a37b2cdd8ffde8bb85a4159888bf3a7ec35966 (patch)
tree83db7b81936621b6a2435e9b5db0de18496cd12f
parentfbd2e5d9a802db4fb5e056705ec599ac423e09be (diff)
Use external shaders instead of generating shader code from c++ code...
-rw-r--r--include/RenderBackend/OpenGL/CommonShader.hpp44
-rw-r--r--include/RenderBackend/OpenGL/CompiledShader.hpp37
-rw-r--r--include/RenderBackend/OpenGL/DeviceFrame.hpp3
-rw-r--r--include/RenderBackend/OpenGL/DeviceMemory.hpp20
-rw-r--r--include/RenderBackend/OpenGL/PixelShader.hpp20
-rw-r--r--include/RenderBackend/OpenGL/Shader.hpp81
-rw-r--r--include/RenderBackend/OpenGL/ShaderProgram.hpp43
-rw-r--r--include/RenderBackend/OpenGL/ShaderVec.hpp142
-rw-r--r--include/RenderBackend/OpenGL/VertexShader.hpp20
-rw-r--r--include/Result.hpp4
-rw-r--r--include/Vec.hpp14
-rw-r--r--include/types.hpp5
-rw-r--r--shaders/fragment.frag8
-rw-r--r--shaders/vertex.vert7
-rw-r--r--src/RenderBackend/OpenGL/CommonShader.cpp20
-rw-r--r--src/RenderBackend/OpenGL/CompiledShader.cpp40
-rw-r--r--src/RenderBackend/OpenGL/DeviceFrame.cpp9
-rw-r--r--src/RenderBackend/OpenGL/DeviceMemory.cpp10
-rw-r--r--src/RenderBackend/OpenGL/PixelShader.cpp47
-rw-r--r--src/RenderBackend/OpenGL/Shader.cpp198
-rw-r--r--src/RenderBackend/OpenGL/ShaderProgram.cpp116
-rw-r--r--src/RenderBackend/OpenGL/ShaderVec.cpp69
-rw-r--r--src/RenderBackend/OpenGL/VertexShader.cpp45
-rw-r--r--src/main.cpp116
24 files changed, 217 insertions, 901 deletions
diff --git a/include/RenderBackend/OpenGL/CommonShader.hpp b/include/RenderBackend/OpenGL/CommonShader.hpp
deleted file mode 100644
index 80e63a9..0000000
--- a/include/RenderBackend/OpenGL/CommonShader.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#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');
- }
-
- 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;
- }
-
- std::string getShaderCompileLog(u32 shaderId);
-}
diff --git a/include/RenderBackend/OpenGL/CompiledShader.hpp b/include/RenderBackend/OpenGL/CompiledShader.hpp
deleted file mode 100644
index 8d2ee84..0000000
--- a/include/RenderBackend/OpenGL/CompiledShader.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include "../../types.hpp"
-#include <unordered_map>
-#include <string>
-
-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;
- const auto& getPixelAttributes() const
- {
- return pixelAttributes;
- }
- private:
- CompiledPixelShader(u32 _shaderId, std::unordered_map<std::string, i32> &&_pixelAttributes);
- private:
- u32 shaderId;
- std::unordered_map<std::string, i32> pixelAttributes;
- };
-}
diff --git a/include/RenderBackend/OpenGL/DeviceFrame.hpp b/include/RenderBackend/OpenGL/DeviceFrame.hpp
index 12e578a..f10af4c 100644
--- a/include/RenderBackend/OpenGL/DeviceFrame.hpp
+++ b/include/RenderBackend/OpenGL/DeviceFrame.hpp
@@ -7,6 +7,7 @@
namespace amalgine
{
class DeviceMemory;
+ class ShaderProgram;
class DeviceFrame
{
@@ -16,7 +17,7 @@ namespace amalgine
~DeviceFrame();
DeviceMemory* alloc();
- void draw();
+ void draw(ShaderProgram *shader);
private:
u32 vertexArrayObjectId;
std::vector<DeviceMemory*> buffers;
diff --git a/include/RenderBackend/OpenGL/DeviceMemory.hpp b/include/RenderBackend/OpenGL/DeviceMemory.hpp
index c37acfb..c9c8b23 100644
--- a/include/RenderBackend/OpenGL/DeviceMemory.hpp
+++ b/include/RenderBackend/OpenGL/DeviceMemory.hpp
@@ -3,21 +3,19 @@
#include "../../DataView.hpp"
#include "../../utils.hpp"
#include "../../Triangle2D.hpp"
-#include <stdexcept>
-namespace amalgine
-{
- class DeviceMemoryEmpty : public std::runtime_error
- {
- public:
- DeviceMemoryEmpty(const std::string &errMsg) : std::runtime_error(errMsg) {}
+namespace amalgine {
+ enum class DeviceMemoryType {
+ NONE,
+ VEC2,
+ VEC3
};
-
+
class DeviceMemory
{
DISABLE_COPY(DeviceMemory)
friend class DeviceFrame;
- friend class ShaderInputVec2;
+ friend class ShaderProgram;
public:
enum class StorageType
{
@@ -40,13 +38,15 @@ namespace amalgine
//void copy(const DataView<f32> &data, StorageType storageType, PrimitiveType primitiveType = PrimitiveType::TRIANGLE);
void copy(const DataView<Triangle2D> &triangles, StorageType storageType);
void draw();
+
+ DeviceMemoryType get_type() const { return type; }
private:
DeviceMemory();
- void operator delete(void *data);
void use() const;
private:
u32 vertexBufferObjectId;
u32 primitiveType;
u32 numVertices;
+ DeviceMemoryType type;
};
}
diff --git a/include/RenderBackend/OpenGL/PixelShader.hpp b/include/RenderBackend/OpenGL/PixelShader.hpp
deleted file mode 100644
index ebe5a12..0000000
--- a/include/RenderBackend/OpenGL/PixelShader.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include "Shader.hpp"
-
-namespace amalgine {
- class CompiledPixelShader;
-
- using PixelShaderMainFunc = std::function<void()>;
-
- class PixelShader : public Shader
- {
- DISABLE_COPY(PixelShader)
- friend class ShaderProgram;
- public:
- PixelShader();
-
- void defineMain(PixelShaderMainFunc mainFunc);
- Result<CompiledPixelShader*> compile();
- };
-}
diff --git a/include/RenderBackend/OpenGL/Shader.hpp b/include/RenderBackend/OpenGL/Shader.hpp
index 7aecc4e..0f802ec 100644
--- a/include/RenderBackend/OpenGL/Shader.hpp
+++ b/include/RenderBackend/OpenGL/Shader.hpp
@@ -1,79 +1,26 @@
#pragma once
-#include "../../DataView.hpp"
-#include "../../utils.hpp"
#include "../../Result.hpp"
-#include "CommonShader.hpp"
-#include "ShaderVec.hpp"
-#include <string>
-#include <unordered_map>
-#include <vector>
-#include <stdexcept>
-#include <functional>
+#include "../../utils.hpp"
+#include "../../types.hpp"
+#include <memory>
namespace amalgine {
- class ShaderTooManyAttributes : public std::runtime_error
- {
- public:
- ShaderTooManyAttributes(i32 maxAttributes);
- };
-
- class ShaderAttributeAlreadyDefined : public std::runtime_error
- {
- public:
- ShaderAttributeAlreadyDefined(const std::string &attributeName);
- };
-
- class ShaderInvalidAttributeName : public std::runtime_error
- {
- public:
- ShaderInvalidAttributeName(const std::string &attributeName);
- };
-
- class ShaderFunctionAlreadyDefined : public std::runtime_error
- {
- public:
- ShaderFunctionAlreadyDefined(const std::string &funcName);
- };
-
class Shader
{
DISABLE_COPY(Shader)
friend class ShaderProgram;
public:
- Shader();
-
- const std::string& getOutputAttributeName(i32 attributeIndex);
- const std::string& getInputAttributeName(i32 attributeIndex) const;
- AttributeType getInputAttributeType(i32 attributeIndex) const;
- ShaderOutputVec4 defineOutputVec4(const std::string &name);
- ShaderGlobalVec3 defineGlobalVec3(const std::string &name);
- ShaderInputVec2 defineInputVec2(const std::string &name);
- i32 defineInputVariable(const std::string &variableName, const char *typeName);
-
- void assign(const ShaderOutputVec4 &lhsVariable, const ShaderVec4 &rhsVariable);
- protected:
- void writeHeader(const std::string &code);
- void writeBody(const std::string &code);
- std::string build() const;
-
- /*
- * Throws ShaderTooManyAttributes if too many attributes are defined for the platform.
- * Throws ShaderAttributeAlreadyDefined if a attribute with the same name has already been defined.
- */
- i32 defineOutputVariable(const std::string &variableName, const char *typeName);
- protected:
- std::string header;
- std::string body;
- int inputLocationCounter;
- int outputLocationCounter;
- // TOOD: Verify if this is correct. This same variable is used for both output and input variables
- i32 maxAttribs; // Could make this static
- std::unordered_map<std::string, i32> inputAttributes;
- std::vector<ShaderAttribute> inputAttributeNames;
- std::unordered_map<std::string, i32> outputAttributes;
- std::vector<ShaderAttribute> outputAttributeNames;
- std::unordered_map<std::string, ShaderGlobalVec> uniforms;
- bool mainFuncDefined;
+ enum class Type {
+ VERTEX,
+ PIXEL
+ };
+
+ ~Shader();
+
+ static Result<std::unique_ptr<Shader>> compile(Type type, const char *str, int size);
+ const u32 id;
+ private:
+ Shader(u32 shader_id);
};
}
diff --git a/include/RenderBackend/OpenGL/ShaderProgram.hpp b/include/RenderBackend/OpenGL/ShaderProgram.hpp
index c8740f8..ca96d0c 100644
--- a/include/RenderBackend/OpenGL/ShaderProgram.hpp
+++ b/include/RenderBackend/OpenGL/ShaderProgram.hpp
@@ -3,44 +3,27 @@
#include "../../Result.hpp"
#include "../../types.hpp"
#include "../../utils.hpp"
-#include "ShaderVec.hpp"
+#include "../../Vec.hpp"
+#include "DeviceMemory.hpp"
#include <vector>
-#include <stdexcept>
+#include <memory>
+
+namespace amalgine {
+ class Shader;
-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 ShaderProgramNonExistingGlobalVariable : public std::runtime_error
- {
- public:
- ShaderProgramNonExistingGlobalVariable(const char *variableName);
- };
-
class ShaderProgram
{
DISABLE_COPY(ShaderProgram)
public:
- ShaderProgram();
~ShaderProgram();
-
- bool setVertexShader(CompiledVertexShader *vertexShader);
- bool setPixelShader(CompiledPixelShader *pixelShader);
-
- Result<bool> build();
+ static Result<std::unique_ptr<ShaderProgram>> build(const std::vector<Shader*> &shaders);
+ int set_uniform(const char *name, const vec3f &value);
+ int set_vertex_input(const char *name, const DeviceMemory &data);
+
void use();
- ShaderProgramGlobalVec3 getGlobalVec3(const char *name);
private:
- u32 shaderProgramId;
- bool built;
+ ShaderProgram(u32 shader_program_id);
+ private:
+ u32 program_id;
};
}
diff --git a/include/RenderBackend/OpenGL/ShaderVec.hpp b/include/RenderBackend/OpenGL/ShaderVec.hpp
deleted file mode 100644
index 4353dd7..0000000
--- a/include/RenderBackend/OpenGL/ShaderVec.hpp
+++ /dev/null
@@ -1,142 +0,0 @@
-#pragma once
-
-#include "../../types.hpp"
-#include "../../RenderBackend/OpenGL/DeviceMemory.hpp"
-#include <string>
-
-namespace amalgine
-{
- class Shader;
- class ShaderProgram;
-
- enum class AttributeType
- {
- NONE,
- VEC2,
- VEC3,
- VEC4
- };
-
- AttributeType getAttributeTypeByName(const char *attributeName);
-
- class ShaderGlobalVec
- {
- friend class Shader;
- friend class ShaderGlobalVec3;
- public:
- ShaderGlobalVec() : attributeType(AttributeType::NONE) {}
- const std::string& getName() const { return name; }
- AttributeType getAttributeType() const { return attributeType; }
- protected:
- ShaderGlobalVec(const std::string &_name, AttributeType _attributeType) : name(_name), attributeType(_attributeType) {}
- private:
- std::string name;
- AttributeType attributeType;
- };
-
- class ShaderGlobalVec3
- {
- friend class Shader;
- public:
- const std::string& getName() const { return globalVec.getName(); }
- AttributeType getAttributeType() const { return globalVec.getAttributeType(); }
- ShaderGlobalVec getVecObject() const { return globalVec; }
- private:
- ShaderGlobalVec3(const std::string &_name) : globalVec(_name, AttributeType::VEC3) {}
- private:
- ShaderGlobalVec globalVec;
- };
-
- class ShaderProgramGlobalVec3
- {
- friend class ShaderProgram;
- public:
- void set(f32 x = 0.0f, f32 y = 0.0f, f32 z = 0.0f);
- private:
- ShaderProgramGlobalVec3(ShaderProgram *_shaderProgram, i32 _uniformId) : shaderProgram(_shaderProgram), uniformId(_uniformId){}
- private:
- ShaderProgram *shaderProgram;
- i32 uniformId;
- };
-
- class ShaderInputVec2
- {
- friend class Shader;
- public:
- const std::string& getName() const;
- void setData(const DeviceMemory &data);
- private:
- ShaderInputVec2(Shader *_shader, i32 _attributeIndex) :
- shader(_shader),
- attributeIndex(_attributeIndex)
- {
-
- }
- private:
- Shader *shader;
- 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 += ")";
- }
-
- ShaderVec4(const ShaderGlobalVec3 &vec3, f32 w = 0.0f)
- {
- result = "vec4(";
- result += vec3.getName();
- result += ", ";
- result += std::to_string(w);
- result += ")";
- }
-
- const std::string& getOutput() const
- {
- return result;
- }
- private:
- std::string result;
- };
-
- class ShaderOutputVec4
- {
- friend class Shader;
- public:
- const std::string& getName() const;
-
- void operator=(const ShaderVec4 &shaderVec4);
- private:
- ShaderOutputVec4(Shader *_shader, i32 _attributeIndex) :
- shader(_shader),
- attributeIndex(_attributeIndex)
- {
-
- }
- private:
- Shader *shader;
- i32 attributeIndex;
- };
-}
diff --git a/include/RenderBackend/OpenGL/VertexShader.hpp b/include/RenderBackend/OpenGL/VertexShader.hpp
deleted file mode 100644
index 6fdd6a4..0000000
--- a/include/RenderBackend/OpenGL/VertexShader.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include "Shader.hpp"
-
-namespace amalgine {
- class CompiledVertexShader;
-
- using VertexShaderMainFunc = std::function<ShaderVec4()>;
-
- class VertexShader : public Shader
- {
- DISABLE_COPY(VertexShader)
- friend class ShaderProgram;
- public:
- VertexShader();
-
- void defineMain(VertexShaderMainFunc mainFunc);
- Result<CompiledVertexShader*> compile();
- };
-}
diff --git a/include/Result.hpp b/include/Result.hpp
index 749d381..50a0d0c 100644
--- a/include/Result.hpp
+++ b/include/Result.hpp
@@ -9,10 +9,10 @@ namespace amalgine
class Result
{
public:
- static Result<T> Ok(const T &data)
+ static Result<T> Ok(T data)
{
Result<T> result;
- result.data = data;
+ result.data = std::move(data);
result.errorCode = 0;
return result;
}
diff --git a/include/Vec.hpp b/include/Vec.hpp
new file mode 100644
index 0000000..339a98b
--- /dev/null
+++ b/include/Vec.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "types.hpp"
+
+namespace amalgine {
+ struct vec3f {
+ f32 x;
+ f32 y;
+ f32 z;
+
+ vec3f() : x(0.0f), y(0.0f) {}
+ vec3f(f32 x, f32 y, f32 z) : x(x), y(y), z(z) {}
+ };
+} \ No newline at end of file
diff --git a/include/types.hpp b/include/types.hpp
index 4f95730..924dd67 100644
--- a/include/types.hpp
+++ b/include/types.hpp
@@ -1,9 +1,8 @@
#pragma once
-#include <cstdint>
+#include <stdint.h>
-namespace amalgine
-{
+namespace amalgine {
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
diff --git a/shaders/fragment.frag b/shaders/fragment.frag
new file mode 100644
index 0000000..ea1ca7d
--- /dev/null
+++ b/shaders/fragment.frag
@@ -0,0 +1,8 @@
+#version 330 core
+
+uniform vec3 triangle_color;
+out vec4 out_color;
+
+void main() {
+ out_color = vec4(triangle_color, 1.0);
+} \ No newline at end of file
diff --git a/shaders/vertex.vert b/shaders/vertex.vert
new file mode 100644
index 0000000..d1cc433
--- /dev/null
+++ b/shaders/vertex.vert
@@ -0,0 +1,7 @@
+#version 330 core
+
+in vec2 position;
+
+void main() {
+ gl_Position = vec4(position, 0.0, 1.0);
+} \ No newline at end of file
diff --git a/src/RenderBackend/OpenGL/CommonShader.cpp b/src/RenderBackend/OpenGL/CommonShader.cpp
deleted file mode 100644
index ea88f62..0000000
--- a/src/RenderBackend/OpenGL/CommonShader.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-
-using namespace std;
-
-namespace amalgine
-{
- string getShaderCompileLog(u32 shaderId)
- {
- string result;
- GLint shaderLogLength;
- glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &shaderLogLength);
- if(shaderLogLength > 0)
- {
- result.resize(shaderLogLength);
- glGetShaderInfoLog(shaderId, shaderLogLength, NULL, &result[0]);
- }
- return result;
- }
-}
diff --git a/src/RenderBackend/OpenGL/CompiledShader.cpp b/src/RenderBackend/OpenGL/CompiledShader.cpp
deleted file mode 100644
index f4a1fec..0000000
--- a/src/RenderBackend/OpenGL/CompiledShader.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-
-using namespace std;
-
-namespace amalgine
-{
- CompiledVertexShader::CompiledVertexShader(u32 _shaderId) :
- shaderId(_shaderId)
- {
-
- }
-
- CompiledVertexShader::~CompiledVertexShader()
- {
- glDeleteShader(shaderId);
- }
-
- u32 CompiledVertexShader::getShaderId() const
- {
- return shaderId;
- }
-
- CompiledPixelShader::CompiledPixelShader(u32 _shaderId, unordered_map<string, i32> &&_pixelAttributes) :
- shaderId(_shaderId),
- pixelAttributes(_pixelAttributes)
- {
-
- }
-
- CompiledPixelShader::~CompiledPixelShader()
- {
- glDeleteShader(shaderId);
- }
-
- u32 CompiledPixelShader::getShaderId() const
- {
- return shaderId;
- }
-}
diff --git a/src/RenderBackend/OpenGL/DeviceFrame.cpp b/src/RenderBackend/OpenGL/DeviceFrame.cpp
index e79dfa1..2132f83 100644
--- a/src/RenderBackend/OpenGL/DeviceFrame.cpp
+++ b/src/RenderBackend/OpenGL/DeviceFrame.cpp
@@ -1,6 +1,7 @@
#include "../../../include/RenderBackend/OpenGL/DeviceFrame.hpp"
#include "../../../include/RenderBackend/OpenGL/DeviceMemory.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
namespace amalgine
{
@@ -26,13 +27,13 @@ namespace amalgine
return deviceMemory;
}
- void DeviceFrame::draw()
- {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ void DeviceFrame::draw(ShaderProgram *shader) {
+ shader->use();
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
for(DeviceMemory *deviceMemory : buffers)
{
deviceMemory->draw();
}
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
}
diff --git a/src/RenderBackend/OpenGL/DeviceMemory.cpp b/src/RenderBackend/OpenGL/DeviceMemory.cpp
index 0dd3e89..2d40569 100644
--- a/src/RenderBackend/OpenGL/DeviceMemory.cpp
+++ b/src/RenderBackend/OpenGL/DeviceMemory.cpp
@@ -33,7 +33,7 @@ namespace amalgine
}
}
- DeviceMemory::DeviceMemory() : primitiveType(0), numVertices(0)
+ DeviceMemory::DeviceMemory() : primitiveType(0), numVertices(0), type(DeviceMemoryType::NONE)
{
glGenBuffers(1, &vertexBufferObjectId);
}
@@ -43,11 +43,6 @@ namespace amalgine
glDeleteBuffers(1, &vertexBufferObjectId);
}
- void DeviceMemory::operator delete(void *data)
- {
- free(data);
- }
-
void DeviceMemory::use() const
{
// TODO: Bind vao here?
@@ -68,12 +63,11 @@ namespace amalgine
glBufferData(GL_ARRAY_BUFFER, triangles.getByteSize(), triangles.data, getOpenglStorageType(storageType));
primitiveType = GL_TRIANGLES;
numVertices = triangles.size * 3;
+ type = DeviceMemoryType::VEC2;
}
void DeviceMemory::draw()
{
- if(primitiveType == 0)
- throw DeviceMemoryEmpty("Unable to draw buffer as no data has been copied to device memory");
glDrawArrays(primitiveType, 0, numVertices);
}
}
diff --git a/src/RenderBackend/OpenGL/PixelShader.cpp b/src/RenderBackend/OpenGL/PixelShader.cpp
deleted file mode 100644
index e6006f2..0000000
--- a/src/RenderBackend/OpenGL/PixelShader.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "../../../include/RenderBackend/OpenGL/PixelShader.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
-
-namespace amalgine
-{
- PixelShader::PixelShader()
- {
- glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxAttribs);
- }
-
- void PixelShader::defineMain(PixelShaderMainFunc mainFunc)
- {
- if(mainFuncDefined)
- throw ShaderFunctionAlreadyDefined("main");
-
- writeBody("void main() {\n");
- mainFunc();
- mainFuncDefined = true;
- writeBody("}\n\n");
- }
-
- Result<CompiledPixelShader*> PixelShader::compile()
- {
- if(!mainFuncDefined)
- return Result<CompiledPixelShader*>::Err("main function not defined (defineMain not called)");
-
- GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
- std::string verterShaderSource = build();
- const char *verterShaderSourcePtr = verterShaderSource.c_str();
- printf("Vertex shader:\n%s\n", verterShaderSourcePtr);
- glShaderSource(fragmentShaderId, 1, &verterShaderSourcePtr, NULL);
- glCompileShader(fragmentShaderId);
-
- GLint status;
- glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &status);
- std::string compileLog = getShaderCompileLog((u32)fragmentShaderId);
- if(status == GL_TRUE)
- {
- if(!compileLog.empty())
- printf("Pixel shader compile log:\n%s", compileLog.c_str());
- return Result<CompiledPixelShader*>::Ok(new CompiledPixelShader(fragmentShaderId, move(inputAttributes)));
- }
- else
- return Result<CompiledPixelShader*>::Err(compileLog);
- }
-}
diff --git a/src/RenderBackend/OpenGL/Shader.cpp b/src/RenderBackend/OpenGL/Shader.cpp
index fad1702..3b6563f 100644
--- a/src/RenderBackend/OpenGL/Shader.cpp
+++ b/src/RenderBackend/OpenGL/Shader.cpp
@@ -1,169 +1,55 @@
#include "../../../include/RenderBackend/OpenGL/Shader.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
-#include <cassert>
-
-using namespace std;
namespace amalgine {
- ShaderTooManyAttributes::ShaderTooManyAttributes(i32 maxAttributes) :
- runtime_error(string("Attempting to define more than ") + to_string(maxAttributes) + " attributes")
- {
-
- }
-
- ShaderAttributeAlreadyDefined::ShaderAttributeAlreadyDefined(const std::string &attributeName) :
- runtime_error(string("An attribute with the name ") + attributeName + " has already been defined")
- {
-
- }
-
- ShaderInvalidAttributeName::ShaderInvalidAttributeName(const std::string &attributeName) :
- runtime_error(string("Attribute name ") + attributeName + " is invalid")
- {
-
- }
-
- ShaderFunctionAlreadyDefined::ShaderFunctionAlreadyDefined(const std::string &funcName) :
- runtime_error(string("Shader function already defined: ") + funcName)
- {
-
- }
-
- Shader::Shader() : inputLocationCounter(0), outputLocationCounter(0), mainFuncDefined(false)
- {
- writeHeader("#version 330 core\n\n");
- }
-
- const string& Shader::getOutputAttributeName(i32 attributeIndex)
- {
- assert(attributeIndex < (i32)outputAttributeNames.size());
- return outputAttributeNames[attributeIndex].name;
+ static GLuint to_opengl_shader_type(Shader::Type type) {
+ switch(type) {
+ case Shader::Type::VERTEX:
+ return GL_VERTEX_SHADER;
+ case Shader::Type::PIXEL:
+ return GL_FRAGMENT_SHADER;
+ }
+ assert(false);
}
- const string& Shader::getInputAttributeName(i32 attributeIndex) const
- {
- assert(attributeIndex < (i32)inputAttributeNames.size());
- return inputAttributeNames[attributeIndex].name;
- }
-
- AttributeType Shader::getInputAttributeType(i32 attributeIndex) const
- {
- assert(attributeIndex < (i32)inputAttributeNames.size());
- return getAttributeTypeByName(inputAttributeNames[attributeIndex].typeName);
- }
-
- ShaderOutputVec4 Shader::defineOutputVec4(const std::string &name)
- {
- i32 attributeIndex = defineOutputVariable(name, "vec4");
- return ShaderOutputVec4(this, attributeIndex);
- }
-
- // TODO: Generate warning if global variable is defined but not assigned to?
- ShaderGlobalVec3 Shader::defineGlobalVec3(const std::string &name)
- {
- if(!isShaderVariableNameValid(name.c_str()))
- throw ShaderInvalidAttributeName(name);
-
- if(uniforms.find(name) != uniforms.end())
- throw ShaderAttributeAlreadyDefined(name);
-
- writeHeader("uniform vec3 ");
- writeHeader(name);
- writeHeader(";\n");
-
- ShaderGlobalVec3 globalVec(name);
- uniforms[name] = globalVec.getVecObject();
- return ShaderGlobalVec3(globalVec);
- }
-
- i32 Shader::defineOutputVariable(const string &variableName, const char *typeName)
- {
- if(!isShaderVariableNameValid(variableName.c_str()))
- throw ShaderInvalidAttributeName(variableName);
-
- if(outputLocationCounter + 1 > maxAttribs)
- throw ShaderTooManyAttributes(maxAttribs);
-
- if(outputAttributes.find(variableName) != outputAttributes.end())
- throw ShaderAttributeAlreadyDefined(variableName);
-
- i32 attributeIndex = outputLocationCounter;
- outputAttributes[variableName] = outputLocationCounter;
- writeHeader("out ");
- writeHeader(typeName);
- writeHeader(" ");
- writeHeader(variableName);
- writeHeader(";\n");
-
- ShaderAttribute shaderAttribute;
- shaderAttribute.name = variableName;
- shaderAttribute.typeName = typeName;
- outputAttributeNames.push_back(shaderAttribute);
- ++outputLocationCounter;
- return attributeIndex;
- }
-
- ShaderInputVec2 Shader::defineInputVec2(const std::string &name)
- {
- i32 attributeIndex = defineInputVariable(name, "vec2");
- return ShaderInputVec2(this, attributeIndex);
- }
-
- i32 Shader::defineInputVariable(const string &variableName, const char *typeName)
- {
- if(!isShaderVariableNameValid(variableName.c_str()))
- throw ShaderInvalidAttributeName(variableName);
-
- if(inputLocationCounter + 1 > maxAttribs)
- throw ShaderTooManyAttributes(maxAttribs);
-
- if(inputAttributes.find(variableName) != inputAttributes.end())
- throw ShaderAttributeAlreadyDefined(variableName);
-
- i32 attributeIndex = inputLocationCounter;
- inputAttributes[variableName] = inputLocationCounter;
- ShaderAttribute shaderAttribute;
- shaderAttribute.name = variableName;
- shaderAttribute.typeName = typeName;
- inputAttributeNames.push_back(shaderAttribute);
-
- writeHeader("layout(location = ");
- writeHeader(to_string(inputLocationCounter));
- ++inputLocationCounter;
- writeHeader(") in ");
- writeHeader(typeName);
- writeHeader(" ");
- writeHeader(variableName);
- writeHeader(";\n");
- return attributeIndex;
- }
-
- void Shader::assign(const ShaderOutputVec4 &lhsVariable, const ShaderVec4 &rhsVariable)
- {
- writeBody(lhsVariable.getName());
- writeBody(" = ");
- writeBody(rhsVariable.getOutput());
- writeBody(";\n");
- }
-
- string Shader::build() const
+ static std::string get_shader_compile_log(GLuint shaderId)
{
std::string result;
- result.reserve(header.size() + 2 + body.size());
- result += header;
- result += "\n";
- result += body;
+ GLint shaderLogLength;
+ glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &shaderLogLength);
+ if(shaderLogLength > 0) {
+ result.resize(shaderLogLength);
+ glGetShaderInfoLog(shaderId, shaderLogLength, NULL, &result[0]);
+ }
return result;
}
-
- void Shader::writeHeader(const string &code)
- {
- header += code;
+
+ Shader::Shader(u32 shader_id) : id(shader_id) {
+
}
-
- void Shader::writeBody(const string &code)
- {
- body += code;
+
+ Shader::~Shader() {
+ glDeleteShader(id);
+ }
+
+ // static
+ Result<std::unique_ptr<Shader>> Shader::compile(Type type, const char *str, int size) {
+ GLuint shader_id = glCreateShader(to_opengl_shader_type(type));
+ GLint shader_lengths[1] = { size };
+ glShaderSource(shader_id, 1, &str, shader_lengths);
+ glCompileShader(shader_id);
+
+ GLint status;
+ glGetShaderiv(shader_id, GL_COMPILE_STATUS, &status);
+ std::string compileLog = get_shader_compile_log(shader_id);
+ if(status == GL_TRUE) {
+ if(!compileLog.empty())
+ fprintf(stderr, "Shader compile log:\n%s", compileLog.c_str());
+ std::unique_ptr<Shader> shader;
+ shader.reset(new Shader(shader_id));
+ return Result<std::unique_ptr<Shader>>::Ok(std::move(shader));
+ }
+ else
+ return Result<std::unique_ptr<Shader>>::Err(compileLog);
}
}
diff --git a/src/RenderBackend/OpenGL/ShaderProgram.cpp b/src/RenderBackend/OpenGL/ShaderProgram.cpp
index aceda3b..e613668 100644
--- a/src/RenderBackend/OpenGL/ShaderProgram.cpp
+++ b/src/RenderBackend/OpenGL/ShaderProgram.cpp
@@ -1,56 +1,34 @@
#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
+
+#include "../../../include/RenderBackend/OpenGL/Shader.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
using namespace std;
-namespace amalgine
-{
- ShaderProgramUsedBeforeBuilt::ShaderProgramUsedBeforeBuilt() :
- runtime_error("Shader program was used before it was built")
- {
+namespace amalgine {
+ ShaderProgram::ShaderProgram(u32 shader_program_id) : program_id(shader_program_id) {
}
- ShaderProgramNonExistingGlobalVariable::ShaderProgramNonExistingGlobalVariable(const char *variableName) :
- runtime_error(string("There is no shader global variable with the name '") + variableName + "'")
- {
-
- }
-
- ShaderProgram::ShaderProgram() : built(false)
- {
- shaderProgramId = glCreateProgram();
- }
-
ShaderProgram::~ShaderProgram()
{
GLint numAttachedShaders;
- glGetProgramiv(shaderProgramId, GL_ATTACHED_SHADERS, &numAttachedShaders);
+ glGetProgramiv(program_id, GL_ATTACHED_SHADERS, &numAttachedShaders);
GLuint *attachedShaders = new GLuint[numAttachedShaders];
- glGetAttachedShaders(shaderProgramId, numAttachedShaders, nullptr, attachedShaders);
+ glGetAttachedShaders(program_id, numAttachedShaders, nullptr, attachedShaders);
for(int i = 0; i < numAttachedShaders; ++i)
{
GLuint attachedShaderId = attachedShaders[i];
- glDetachShader(shaderProgramId, attachedShaderId);
+ glDetachShader(program_id, attachedShaderId);
}
- glDeleteProgram(shaderProgramId);
- }
-
- // TODO: Before adding shader to program, check if it has already been added
-
- bool ShaderProgram::setVertexShader(CompiledVertexShader *vertexShader)
- {
- if(!vertexShader) return false;
-
- // TODO: Do not allow adding shader if the program has already been built
- glAttachShader(shaderProgramId, vertexShader->getShaderId());
- return true;
+ glDeleteProgram(program_id);
+ delete []attachedShaders;
}
+ #if 0
bool ShaderProgram::setPixelShader(CompiledPixelShader *pixelShader)
{
if(!pixelShader) return false;
@@ -68,41 +46,55 @@ namespace amalgine
return true;
}
+ #endif
- Result<bool> ShaderProgram::build()
- {
- if(built)
- return Result<bool>::Err("Shader program already built");
+ // static
+ Result<std::unique_ptr<ShaderProgram>> ShaderProgram::build(const std::vector<Shader*> &shaders) {
+ u32 shader_program_id = glCreateProgram();
+ if(shader_program_id == 0)
+ return Result<std::unique_ptr<ShaderProgram>>::Err("Failed to create shader program");
- glLinkProgram(shaderProgramId);
- built = true;
- return Result<bool>::Ok(true);
- }
-
- void ShaderProgram::use()
- {
- if(built)
- {
- glUseProgram(shaderProgramId);
- }
- else
- {
- throw ShaderProgramUsedBeforeBuilt();
+ for(Shader *shader : shaders) {
+ glAttachShader(shader_program_id, shader->id);
}
+
+ glLinkProgram(shader_program_id);
+ std::unique_ptr<ShaderProgram> shader_program;
+ shader_program.reset(new ShaderProgram(shader_program_id));
+ return Result<std::unique_ptr<ShaderProgram>>::Ok(std::move(shader_program));
}
-
- ShaderProgramGlobalVec3 ShaderProgram::getGlobalVec3(const char *name)
- {
- if(built)
- {
- GLint uniformId = glGetUniformLocation(shaderProgramId, name);
- if(uniformId == -1)
- throw ShaderProgramNonExistingGlobalVariable(name);
- return ShaderProgramGlobalVec3(this, uniformId);
+
+ int ShaderProgram::set_uniform(const char *name, const vec3f &value) {
+ GLint uniformId = glGetUniformLocation(program_id, name);
+ if(uniformId == -1)
+ return -1;
+ use();
+ glUniform3f(uniformId, value.x, value.y, value.z);
+ return 0;
+ }
+
+ int ShaderProgram::set_vertex_input(const char *name, const DeviceMemory &data) {
+ GLint attrib_location = glGetAttribLocation(program_id, name);
+ if(attrib_location == -1) {
+ fprintf(stderr, "No such attribute in shader: %s\n", name);
+ return -1;
}
- else
- {
- throw ShaderProgramUsedBeforeBuilt();
+
+ data.use();
+ switch(data.get_type()) {
+ case DeviceMemoryType::NONE:
+ return -1;
+ case DeviceMemoryType::VEC2: {
+ glVertexAttribPointer(attrib_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
+ break;
+ }
+ case DeviceMemoryType::VEC3: assert(false); return -1;
}
+ glEnableVertexAttribArray(attrib_location);
+ return 0;
+ }
+
+ void ShaderProgram::use() {
+ glUseProgram(program_id);
}
}
diff --git a/src/RenderBackend/OpenGL/ShaderVec.cpp b/src/RenderBackend/OpenGL/ShaderVec.cpp
deleted file mode 100644
index 8897b84..0000000
--- a/src/RenderBackend/OpenGL/ShaderVec.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include "../../../include/RenderBackend/OpenGL/ShaderVec.hpp"
-#include "../../../include/RenderBackend/OpenGL/Shader.hpp"
-#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include <cstring>
-#include <cassert>
-
-using namespace std;
-
-namespace amalgine
-{
- AttributeType getAttributeTypeByName(const char *attributeName)
- {
- if(strncmp(attributeName, "vec2", 4) == 0)
- {
- return AttributeType::VEC2;
- }
- else if(strncmp(attributeName, "vec3", 4) == 0)
- {
- return AttributeType::VEC3;
- }
- else if(strncmp(attributeName, "vec4", 4) == 0)
- {
- return AttributeType::VEC4;
- }
-
- assert(false);
- return AttributeType::NONE;
- }
-
- void ShaderProgramGlobalVec3::set(f32 x, f32 y, f32 z)
- {
- shaderProgram->use();
- glUniform3f(uniformId, x, y, z);
- }
-
- const string& ShaderInputVec2::getName() const
- {
- return shader->getInputAttributeName(attributeIndex);
- }
-
- void ShaderInputVec2::setData(const DeviceMemory &data)
- {
- data.use();
- AttributeType attributeType = shader->getInputAttributeType(attributeIndex);
- switch(attributeType)
- {
- case AttributeType::VEC2:
- {
- glVertexAttribPointer(attributeIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
- break;
- }
- default:
- assert(false);
- break;
- }
- glEnableVertexAttribArray(attributeIndex);
- }
-
- const string& ShaderOutputVec4::getName() const
- {
- return shader->getOutputAttributeName(attributeIndex);
- }
-
- void ShaderOutputVec4::operator=(const ShaderVec4 &shaderVec4)
- {
- shader->assign(*this, shaderVec4);
- }
-}
diff --git a/src/RenderBackend/OpenGL/VertexShader.cpp b/src/RenderBackend/OpenGL/VertexShader.cpp
deleted file mode 100644
index 19705b6..0000000
--- a/src/RenderBackend/OpenGL/VertexShader.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "../../../include/RenderBackend/OpenGL/VertexShader.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
-
-namespace amalgine {
- VertexShader::VertexShader()
- {
- glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs);
- }
-
- void VertexShader::defineMain(VertexShaderMainFunc mainFunc)
- {
- if(mainFuncDefined)
- throw ShaderFunctionAlreadyDefined("main");
-
- writeBody("void main() {\n");
- ShaderVec4 glPosition = mainFunc();
- mainFuncDefined = true;
- writeBody("gl_Position = ");
- writeBody(glPosition.getOutput());
- writeBody(";\n}\n\n");
- }
-
- Result<CompiledVertexShader*> VertexShader::compile()
- {
- GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
- std::string verterShaderSource = build();
- const char *verterShaderSourcePtr = verterShaderSource.c_str();
- printf("Vertex shader:\n%s\n", verterShaderSourcePtr);
- glShaderSource(vertexShaderId, 1, &verterShaderSourcePtr, NULL);
- glCompileShader(vertexShaderId);
-
- GLint status;
- glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &status);
- std::string compileLog = getShaderCompileLog((u32)vertexShaderId);
- if(status == GL_TRUE)
- {
- if(!compileLog.empty())
- printf("Vertex shader compile log:\n%s", compileLog.c_str());
- return Result<CompiledVertexShader*>::Ok(new CompiledVertexShader(vertexShaderId));
- }
- else
- return Result<CompiledVertexShader*>::Err(compileLog);
- }
-}
diff --git a/src/main.cpp b/src/main.cpp
index 24ef4f8..f6f827f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,6 @@
#include <cstdio>
#include "../include/RenderBackend/OpenGL/opengl.hpp"
-#include "../include/RenderBackend/OpenGL/VertexShader.hpp"
-#include "../include/RenderBackend/OpenGL/PixelShader.hpp"
+#include "../include/RenderBackend/OpenGL/Shader.hpp"
#include "../include/RenderBackend/OpenGL/ShaderProgram.hpp"
#include "../include/RenderBackend/OpenGL/DeviceMemory.hpp"
#include "../include/RenderBackend/OpenGL/DeviceFrame.hpp"
@@ -16,13 +15,11 @@
using namespace amalgine;
using namespace std;
-void glfwErrorHandler(int errorCode, const char *errorDescription);
-void initGlfw();
-void initGlew();
-GLFWwindow *createWindow();
-
-CompiledVertexShader* createVertexShader(const DeviceMemory &inputData);
-CompiledPixelShader* createPixelShader();
+static void glfwErrorHandler(int errorCode, const char *errorDescription);
+static void initGlfw();
+static void initGlew();
+static GLFWwindow *createWindow();
+static std::unique_ptr<Shader> load_shader_from_file(const char *filepath, Shader::Type shader_type);
int main()
{
@@ -40,25 +37,19 @@ int main()
DataView<Triangle2D> cpuTriangles(&cpuTriangle, 1);
DeviceMemory *gpuTriangle = frame.alloc();
gpuTriangle->copy(cpuTriangles, DeviceMemory::StorageType::STATIC);
+
+ std::unique_ptr<Shader> vertex_shader = load_shader_from_file("shaders/vertex.vert", Shader::Type::VERTEX);
+ std::unique_ptr<Shader> pixel_shader = load_shader_from_file("shaders/fragment.frag", Shader::Type::PIXEL);
- CompiledVertexShader *vertexShader = createVertexShader(*gpuTriangle);
- CompiledPixelShader *pixelShader = createPixelShader();
-
- ShaderProgram shaderProgram;
- shaderProgram.setVertexShader(vertexShader);
- shaderProgram.setPixelShader(pixelShader);
- // Make ShaderProgram.build return an object which we can do things on? since some operations
- // require the shader to be built to be used
- Result<bool> shaderBuildResult = shaderProgram.build();
-
- ShaderProgramGlobalVec3 triangleColor = shaderProgram.getGlobalVec3("triangleColor");
- triangleColor.set(1.0f, 0.0f, 0.0f);
-
- if(!shaderBuildResult)
- {
- fprintf(stderr, "Failed to build shader program: %s\n", shaderBuildResult.getErrorMsg().c_str());
- exit(20);
+ Result<std::unique_ptr<ShaderProgram>> shader_program_result = ShaderProgram::build({ vertex_shader.get(), pixel_shader.get() });
+ if(!shader_program_result) {
+ fprintf(stderr, "Failed to link shaders, error: %s\n", shader_program_result.getErrorMsg().c_str());
+ exit(13);
}
+ std::unique_ptr<ShaderProgram> shader_program = std::move(shader_program_result.unwrap());
+
+ shader_program->set_vertex_input("position", *gpuTriangle);
+ shader_program->set_uniform("triangle_color", vec3f{ 1.0f, 0.0f, 0.0f });
while(!glfwWindowShouldClose(window))
{
@@ -70,8 +61,7 @@ int main()
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Do the actual screen clearing, using the color set using glClearColor
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- shaderProgram.use();
- frame.draw();
+ frame.draw(shader_program.get());
glfwSwapBuffers(window);
}
@@ -128,53 +118,31 @@ GLFWwindow* createWindow()
return window;
}
-CompiledVertexShader* createVertexShader(const DeviceMemory &inputData)
-{
- VertexShader vertexShader;
- ShaderInputVec2 inputPosition = vertexShader.defineInputVec2("position");
- inputPosition.setData(inputData);
- #if 0
- ShaderGlobalMat4x4 model = vertexShader.defineGlobalMat4x4("model");
- ShaderGlobalMat4x4 view = vertexShader.defineGlobalMat4x4("view");
- ShaderGlobalMat4x4 proj = vertexShader.defineGlobalMat4x4("proj");
-
- vertexShader.defineMain([&inputPosition, &model, &view, &proj]()
- {
- return proj * view * model * ShaderVec4(inputPosition, 0.0f, 1.0f);
- });
- #endif
- vertexShader.defineMain([&inputPosition]()
- {
- return ShaderVec4(inputPosition, 0.0f, 1.0f);
- });
-
- Result<CompiledVertexShader*> compiledVertexShader = vertexShader.compile();
- if(!compiledVertexShader)
- {
- fprintf(stderr, "Failed to compile vertex shader:\n%s", compiledVertexShader.getErrorMsg().c_str());
- exit(2);
+static int file_read_all(const char *filepath, std::string &result) {
+ FILE *file = fopen(filepath, "rb");
+ if(!file) {
+ perror("file_read_all");
+ return errno;
}
-
- return compiledVertexShader.unwrap();
+
+ fseek(file, 0, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ result.resize(file_size);
+ fread(&result[0], 1, result.size(), file);
+ fclose(file);
+ return 0;
}
-CompiledPixelShader* createPixelShader()
-{
- PixelShader pixelShader;
- ShaderGlobalVec3 triangleColor = pixelShader.defineGlobalVec3("triangleColor");
- ShaderOutputVec4 outColor = pixelShader.defineOutputVec4("outColor");
-
- pixelShader.defineMain([&triangleColor, &outColor]()
- {
- outColor = ShaderVec4(triangleColor, 1.0f);
- });
-
- Result<CompiledPixelShader*> compiledPixelShader = pixelShader.compile();
- if(!compiledPixelShader)
- {
- fprintf(stderr, "Failed to compile pixel shader:\n%s", compiledPixelShader.getErrorMsg().c_str());
- exit(2);
+std::unique_ptr<Shader> load_shader_from_file(const char *filepath, Shader::Type shader_type) {
+ std::string file_content;
+ if(file_read_all(filepath, file_content) != 0)
+ exit(13);
+
+ Result<std::unique_ptr<Shader>> vertex_shader_result = Shader::compile(shader_type, file_content.data(), file_content.size());
+ if(!vertex_shader_result) {
+ fprintf(stderr, "Failed to compile shader, error: %s\n", vertex_shader_result.getErrorMsg().c_str());
+ exit(12);
}
-
- return compiledPixelShader.unwrap();
-}
+ return std::move(vertex_shader_result.unwrap());
+} \ No newline at end of file