aboutsummaryrefslogtreecommitdiff
path: root/src/RenderBackend/OpenGL/PixelShader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/RenderBackend/OpenGL/PixelShader.cpp')
-rw-r--r--src/RenderBackend/OpenGL/PixelShader.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/RenderBackend/OpenGL/PixelShader.cpp b/src/RenderBackend/OpenGL/PixelShader.cpp
new file mode 100644
index 0000000..cbdc842
--- /dev/null
+++ b/src/RenderBackend/OpenGL/PixelShader.cpp
@@ -0,0 +1,114 @@
+#include "../../../include/RenderBackend/OpenGL/PixelShader.hpp"
+#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp"
+#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+#include <cassert>
+
+using namespace std;
+
+namespace amalgine
+{
+ PixelShaderTooManyAttributes::PixelShaderTooManyAttributes(i32 maxPixelAttributes) :
+ runtime_error(string("Attempting to define more than ") + to_string(maxPixelAttributes) + " pixel attributes")
+ {
+
+ }
+
+ PixelShaderAttributeAlreadyDefined::PixelShaderAttributeAlreadyDefined(const std::string &attributeName) :
+ runtime_error(string("A pixel attribute with the name ") + attributeName + " has already been defined")
+ {
+
+ }
+
+ PixelShaderInvalidAttributeName::PixelShaderInvalidAttributeName(const std::string &attributeName) :
+ runtime_error(string("Pixel attribute name ") + attributeName + " is invalid")
+ {
+
+ }
+
+ PixelShaderFunctionAlreadyDefined::PixelShaderFunctionAlreadyDefined(const std::string &funcName) :
+ runtime_error(string("Pixel shader function already defined: ") + funcName)
+ {
+
+ }
+
+ PixelShader::PixelShader() : locationCounter(0), 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)
+ throw PixelShaderFunctionAlreadyDefined("main");
+
+ writeBody("void main() {\n");
+ mainFunc();
+ mainFuncDefined = true;
+ writeBody("}\n\n");
+ }
+
+ void PixelShader::assign(const ShaderOutputVec4 &lhsVariable, const ShaderVec4 &rhsVariable)
+ {
+ writeBody(lhsVariable.getName());
+ writeBody(" = ");
+ writeBody(rhsVariable.getOutput());
+ 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()
+ {
+ std::string result;
+ result.reserve(header.size() + 2 + body.size());
+ result += header;
+ result += "\n";
+ result += body;
+ return result;
+ }
+
+ void PixelShader::writeHeader(const string &code)
+ {
+ header += code;
+ }
+
+ void PixelShader::writeBody(const string &code)
+ {
+ body += code;
+ }
+}