aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/RenderBackend/OpenGL/PixelShader.hpp14
-rw-r--r--include/RenderBackend/OpenGL/ShaderProgram.hpp34
-rw-r--r--include/RenderBackend/OpenGL/ShaderVec.hpp8
-rw-r--r--include/RenderBackend/OpenGL/VertexShader.hpp2
-rw-r--r--include/Result.hpp48
-rw-r--r--src/RenderBackend/OpenGL/PixelShader.cpp44
-rw-r--r--src/RenderBackend/OpenGL/ShaderProgram.cpp103
-rw-r--r--src/RenderBackend/OpenGL/VertexShader.cpp3
-rw-r--r--src/main.cpp5
9 files changed, 198 insertions, 63 deletions
diff --git a/include/RenderBackend/OpenGL/PixelShader.hpp b/include/RenderBackend/OpenGL/PixelShader.hpp
index 3d33155..b869a8f 100644
--- a/include/RenderBackend/OpenGL/PixelShader.hpp
+++ b/include/RenderBackend/OpenGL/PixelShader.hpp
@@ -45,27 +45,15 @@ namespace amalgine
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();
+ std::string build() const;
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/ShaderProgram.hpp b/include/RenderBackend/OpenGL/ShaderProgram.hpp
new file mode 100644
index 0000000..efeae5b
--- /dev/null
+++ b/include/RenderBackend/OpenGL/ShaderProgram.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "VertexShader.hpp"
+#include "PixelShader.hpp"
+#include "../../Result.hpp"
+#include "../../types.hpp"
+#include <vector>
+
+namespace amalgine
+{
+ class ShaderProgram
+ {
+ public:
+ 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);
+ 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;
+ };
+}
diff --git a/include/RenderBackend/OpenGL/ShaderVec.hpp b/include/RenderBackend/OpenGL/ShaderVec.hpp
index 10e628c..0c0a88a 100644
--- a/include/RenderBackend/OpenGL/ShaderVec.hpp
+++ b/include/RenderBackend/OpenGL/ShaderVec.hpp
@@ -6,7 +6,7 @@
namespace amalgine
{
class VertexShader;
- class PixelShader;
+ class ShaderProgram;
class ShaderInputVec2
{
@@ -62,20 +62,20 @@ namespace amalgine
class ShaderOutputVec4
{
- friend class PixelShader;
+ friend class ShaderProgram;
public:
const std::string& getName() const;
void operator=(const ShaderVec4 &shaderVec4);
private:
- ShaderOutputVec4(PixelShader *_pixelShader, i32 _attributeIndex) :
+ ShaderOutputVec4(ShaderProgram *_pixelShader, i32 _attributeIndex) :
pixelShader(_pixelShader),
attributeIndex(_attributeIndex)
{
}
private:
- PixelShader *pixelShader;
+ ShaderProgram *shaderProgram;
i32 attributeIndex;
};
}
diff --git a/include/RenderBackend/OpenGL/VertexShader.hpp b/include/RenderBackend/OpenGL/VertexShader.hpp
index ec8be22..3239be2 100644
--- a/include/RenderBackend/OpenGL/VertexShader.hpp
+++ b/include/RenderBackend/OpenGL/VertexShader.hpp
@@ -48,7 +48,7 @@ namespace amalgine
const std::string& getInputAttributeName(i32 attributeIndex);
ShaderInputVec2 defineInputVec2(const std::string &name);
void defineMain(VertexShaderMainFunc mainFunc);
- std::string build();
+ std::string build() const;
private:
void writeHeader(const std::string &code);
void writeBody(const std::string &code);
diff --git a/include/Result.hpp b/include/Result.hpp
new file mode 100644
index 0000000..316e45a
--- /dev/null
+++ b/include/Result.hpp
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <string>
+
+namespace amalgine
+{
+ template <typename T>
+ class Result
+ {
+ public:
+ static Result<T> Ok(const T &data)
+ {
+ Result<T> result;
+ result.data = data;
+ result.errorCode = 0;
+ return result;
+ }
+
+ static Result<T> Err(const std::string &errorMsg, int errorCode = -1)
+ {
+ Result<T> result;
+ result.errorMsg = errorMsg;
+ result.errorCode = errorCode;
+ return result;
+ }
+
+ template <typename OtherType>
+ static Result<T> Err(const Result<OtherType> &otherResult)
+ {
+ Result<T> result;
+ result.errorMsg = otherResult.errorMsg;
+ result.errorCode = otherResult.errorCode;
+ return result;
+ }
+
+ bool isOk() const { return errorCode == 0; }
+ bool isErr() const { return !isOk(); }
+ operator bool() const { return isOk(); }
+
+ const std::string& getErrorMsg() const { return errorMsg; }
+ private:
+ Result(){}
+ private:
+ T data;
+ int errorCode;
+ std::string errorMsg;
+ };
+}
diff --git a/src/RenderBackend/OpenGL/PixelShader.cpp b/src/RenderBackend/OpenGL/PixelShader.cpp
index cbdc842..2a7c913 100644
--- a/src/RenderBackend/OpenGL/PixelShader.cpp
+++ b/src/RenderBackend/OpenGL/PixelShader.cpp
@@ -1,7 +1,4 @@
#include "../../../include/RenderBackend/OpenGL/PixelShader.hpp"
-#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include <cassert>
using namespace std;
@@ -31,24 +28,11 @@ namespace amalgine
}
- PixelShader::PixelShader() : locationCounter(0), mainFuncDefined(false)
+ PixelShader::PixelShader() : mainFuncDefined(false)
{
- glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxPixelAttribs);
writeHeader("#version 330 core\n\n");
}
- const string& PixelShader::getOutputAttributeName(i32 attributeIndex)
- {
- assert(attributeIndex < pixelAttributeNames.size());
- return pixelAttributeNames[attributeIndex];
- }
-
- ShaderOutputVec4 PixelShader::defineOutputVec4(const std::string &name)
- {
- i32 attributeIndex = defineOutputVariable(name, "vec4");
- return ShaderOutputVec4(this, attributeIndex);
- }
-
void PixelShader::defineMain(PixelShaderMainFunc mainFunc)
{
if(mainFuncDefined)
@@ -68,31 +52,7 @@ namespace amalgine
writeBody(";\n");
}
- i32 PixelShader::defineOutputVariable(const string &variableName, const char *typeName)
- {
- if(!isShaderVariableNameValid(variableName.c_str()))
- throw PixelShaderInvalidAttributeName(variableName);
-
- if(locationCounter + 1 > maxPixelAttribs)
- throw PixelShaderTooManyAttributes(maxPixelAttribs);
-
- if(pixelAttributes.find(variableName) != pixelAttributes.end())
- throw PixelShaderAttributeAlreadyDefined(variableName);
-
- i32 attributeIndex = locationCounter;
- pixelAttributes[variableName] = locationCounter;
- pixelAttributeNames.push_back(variableName);
-
- ++locationCounter;
- writeHeader("out ");
- writeHeader(typeName);
- writeHeader(" ");
- writeHeader(variableName);
- writeHeader(";\n");
- return attributeIndex;
- }
-
- string PixelShader::build()
+ string PixelShader::build() const
{
std::string result;
result.reserve(header.size() + 2 + body.size());
diff --git a/src/RenderBackend/OpenGL/ShaderProgram.cpp b/src/RenderBackend/OpenGL/ShaderProgram.cpp
new file mode 100644
index 0000000..892f45e
--- /dev/null
+++ b/src/RenderBackend/OpenGL/ShaderProgram.cpp
@@ -0,0 +1,103 @@
+#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
+#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp"
+#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+
+using namespace std;
+
+namespace amalgine
+{
+ string getShaderCompileLog(GLuint 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;
+ }
+
+ ShaderProgram::ShaderProgram() : locationCounter(0)
+ {
+ glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxPixelAttribs);
+ }
+
+ const string& ShaderProgram::getOutputAttributeName(i32 attributeIndex)
+ {
+ assert(attributeIndex < pixelAttributeNames.size());
+ return pixelAttributeNames[attributeIndex];
+ }
+
+ ShaderOutputVec4 ShaderProgram::defineOutputVec4(const std::string &name)
+ {
+ i32 attributeIndex = defineOutputVariable(name, "vec4");
+ return ShaderOutputVec4(this, attributeIndex);
+ }
+
+ i32 ShaderProgram::defineOutputVariable(const string &variableName, const char *typeName)
+ {
+ if(!isShaderVariableNameValid(variableName.c_str()))
+ throw PixelShaderInvalidAttributeName(variableName);
+
+ if(locationCounter + 1 > maxPixelAttribs)
+ throw PixelShaderTooManyAttributes(maxPixelAttribs);
+
+ if(pixelAttributes.find(variableName) != pixelAttributes.end())
+ throw PixelShaderAttributeAlreadyDefined(variableName);
+
+ i32 attributeIndex = locationCounter;
+ pixelAttributes[variableName] = locationCounter;
+ pixelAttributeNames.push_back(variableName);
+ ++locationCounter;
+ return attributeIndex;
+ }
+
+ /*
+ Result<string> ShaderProgram::addVertexShader(const VertexShader &vertexShader)
+ {
+ GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
+ string verterShaderSource = vertexShader.build();
+ const char *verterShaderSourcePtr = verterShaderSource.c_str();
+ glShaderSource(vertexShaderId, 1, &verterShaderSourcePtr, NULL);
+ glCompileShader(vertexShaderId);
+ shaderIds.push_back(vertexShaderId);
+
+ GLint status;
+ glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &status);
+ string compileLog = getShaderCompileLog(vertexShaderId);
+ if(status == GL_TRUE)
+ return Result<string>::Ok(compileLog);
+ else
+ return Result<string>::Err(compileLog);
+ }
+
+ Result<string> ShaderProgram::addPixelShader(const PixelShader &pixelShader)
+ {
+ GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
+ string fragmentShaderSource = pixelShader.build();
+ const char *fragmentShaderSourcePtr = fragmentShaderSource.c_str();
+ glShaderSource(fragmentShaderId, 1, &fragmentShaderSourcePtr, NULL);
+ glCompileShader(fragmentShaderId);
+ shaderIds.push_back(fragmentShaderId);
+
+ GLint status;
+ glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &status);
+ string compileLog = getShaderCompileLog(fragmentShaderId);
+ if(status == GL_TRUE)
+ return Result<string>::Ok(compileLog);
+ else
+ return Result<string>::Err(compileLog);
+ }
+
+ void ShaderProgram::build()
+ {
+ GLuint shaderProgramId = glCreateProgram();
+ for(u32 shaderId : shaderIds)
+ {
+ glAttachShader(shaderProgramId, shaderId);
+ }
+ }
+ */
+}
diff --git a/src/RenderBackend/OpenGL/VertexShader.cpp b/src/RenderBackend/OpenGL/VertexShader.cpp
index b869624..04bf863 100644
--- a/src/RenderBackend/OpenGL/VertexShader.cpp
+++ b/src/RenderBackend/OpenGL/VertexShader.cpp
@@ -1,7 +1,6 @@
#include "../../../include/RenderBackend/OpenGL/VertexShader.hpp"
#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include <cassert>
using namespace std;
@@ -88,7 +87,7 @@ namespace amalgine
return attributeIndex;
}
- string VertexShader::build()
+ string VertexShader::build() const
{
std::string result;
result.reserve(header.size() + 2 + body.size());
diff --git a/src/main.cpp b/src/main.cpp
index fe48ddf..03222f1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4,6 +4,7 @@
#include <glm/glm.hpp>
#include "../include/RenderBackend/OpenGL/VertexShader.hpp"
#include "../include/RenderBackend/OpenGL/PixelShader.hpp"
+#include "../include/RenderBackend/OpenGL/ShaderProgram.hpp"
#include "../include/RenderBackend/OpenGL/DeviceMemory.hpp"
using namespace amalgine;
@@ -54,6 +55,8 @@ int main()
DeviceMemory triangle;
triangle.copyStatic(vertices);
+ ShaderProgram shaderProgram;
+
VertexShader vertexShader;
ShaderInputVec2 inputPosition = vertexShader.defineInputVec2("position");
@@ -63,7 +66,7 @@ int main()
});
PixelShader pixelShader;
- ShaderOutputVec4 outColor = pixelShader.defineOutputVec4("outColor");
+ ShaderOutputVec4 outColor = shaderProgram.defineOutputVec4("outColor");
pixelShader.defineMain([&outColor]()
{