From ca92d8c90f7103db6d7cae4cef49b278d804b474 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 20 Dec 2017 20:55:05 +0100 Subject: Create shader using c++ code --- src/RenderBackend/OpenGL/VertexShader.cpp | 110 ++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/RenderBackend/OpenGL/VertexShader.cpp (limited to 'src/RenderBackend/OpenGL/VertexShader.cpp') diff --git a/src/RenderBackend/OpenGL/VertexShader.cpp b/src/RenderBackend/OpenGL/VertexShader.cpp new file mode 100644 index 0000000..b869624 --- /dev/null +++ b/src/RenderBackend/OpenGL/VertexShader.cpp @@ -0,0 +1,110 @@ +#include "../../../include/RenderBackend/OpenGL/VertexShader.hpp" +#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp" +#include "../../../include/RenderBackend/OpenGL/opengl.hpp" +#include + +using namespace std; + +namespace amalgine +{ + VertexShaderTooManyAttributes::VertexShaderTooManyAttributes(i32 maxVertexAttributes) : + runtime_error(string("Attempting to define more than ") + to_string(maxVertexAttributes) + " vertex attributes") + { + + } + + VertexShaderAttributeAlreadyDefined::VertexShaderAttributeAlreadyDefined(const std::string &attributeName) : + runtime_error(string("A vertex attribute with the name ") + attributeName + " has already been defined") + { + + } + + VertexShaderInvalidAttributeName::VertexShaderInvalidAttributeName(const std::string &attributeName) : + runtime_error(string("Vertex attribute name ") + attributeName + " is invalid") + { + + } + + VertexShaderFunctionAlreadyDefined::VertexShaderFunctionAlreadyDefined(const std::string &funcName) : + runtime_error(string("Vertex shader function already defined: ") + funcName) + { + + } + + VertexShader::VertexShader() : locationCounter(0), mainFuncDefined(false) + { + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); + writeHeader("#version 330 core\n\n"); + } + + const string& VertexShader::getInputAttributeName(i32 attributeIndex) + { + assert(attributeIndex < vertexAttributeNames.size()); + return vertexAttributeNames[attributeIndex]; + } + + ShaderInputVec2 VertexShader::defineInputVec2(const std::string &name) + { + i32 attributeIndex = defineInputVariable(name, "vec2"); + return ShaderInputVec2(this, attributeIndex); + } + + void VertexShader::defineMain(VertexShaderMainFunc mainFunc) + { + if(mainFuncDefined) + throw VertexShaderFunctionAlreadyDefined("main"); + + writeBody("void main() {\n"); + ShaderVec4 glPosition = mainFunc(); + mainFuncDefined = true; + writeBody("gl_Position = "); + writeBody(glPosition.getOutput()); + writeBody(";\n}\n\n"); + } + + i32 VertexShader::defineInputVariable(const string &variableName, const char *typeName) + { + if(!isShaderVariableNameValid(variableName.c_str())) + throw VertexShaderInvalidAttributeName(variableName); + + if(locationCounter + 1 > maxVertexAttribs) + throw VertexShaderTooManyAttributes(maxVertexAttribs); + + if(vertexAttributes.find(variableName) != vertexAttributes.end()) + throw VertexShaderAttributeAlreadyDefined(variableName); + + i32 attributeIndex = locationCounter; + vertexAttributes[variableName] = locationCounter; + vertexAttributeNames.push_back(variableName); + + writeHeader("layout(location = "); + writeHeader(to_string(locationCounter)); + ++locationCounter; + writeHeader(") in "); + writeHeader(typeName); + writeHeader(" "); + writeHeader(variableName); + writeHeader(";\n"); + return attributeIndex; + } + + string VertexShader::build() + { + std::string result; + result.reserve(header.size() + 2 + body.size()); + result += header; + result += "\n"; + result += body; + return result; + } + + void VertexShader::writeHeader(const string &code) + { + header += code; + } + + void VertexShader::writeBody(const string &code) + { + body += code; + } +} -- cgit v1.2.3