diff options
-rw-r--r-- | include/RenderBackend/OpenGL/PixelShader.hpp | 74 | ||||
-rw-r--r-- | include/RenderBackend/OpenGL/Shader.hpp | 79 | ||||
-rw-r--r-- | include/RenderBackend/OpenGL/ShaderVec.hpp | 25 | ||||
-rw-r--r-- | include/RenderBackend/OpenGL/VertexShader.hpp | 71 | ||||
-rw-r--r-- | src/RenderBackend/OpenGL/DeviceFrame.cpp | 2 | ||||
-rw-r--r-- | src/RenderBackend/OpenGL/PixelShader.cpp | 130 | ||||
-rw-r--r-- | src/RenderBackend/OpenGL/Shader.cpp | 169 | ||||
-rw-r--r-- | src/RenderBackend/OpenGL/ShaderVec.cpp | 20 | ||||
-rw-r--r-- | src/RenderBackend/OpenGL/VertexShader.cpp | 111 | ||||
-rw-r--r-- | src/main.cpp | 9 |
10 files changed, 314 insertions, 376 deletions
diff --git a/include/RenderBackend/OpenGL/PixelShader.hpp b/include/RenderBackend/OpenGL/PixelShader.hpp index 6794fb1..ebe5a12 100644 --- a/include/RenderBackend/OpenGL/PixelShader.hpp +++ b/include/RenderBackend/OpenGL/PixelShader.hpp @@ -1,82 +1,20 @@ #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 "Shader.hpp" -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. - */ +namespace amalgine { class CompiledPixelShader; + + using PixelShaderMainFunc = std::function<void()>; - class PixelShader + class PixelShader : public Shader { DISABLE_COPY(PixelShader) friend class ShaderProgram; public: PixelShader(); - - const std::string& getOutputAttributeName(i32 attributeIndex); - ShaderOutputVec4 defineOutputVec4(const std::string &name); - ShaderGlobalVec3 defineGlobalVec3(const std::string &name); - + void defineMain(PixelShaderMainFunc mainFunc); - void assign(const ShaderOutputVec4 &lhsVariable, const ShaderVec4 &rhsVariable); Result<CompiledPixelShader*> compile(); - private: - void writeHeader(const std::string &code); - void writeBody(const std::string &code); - std::string build() const; - - /* - * 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<ShaderAttribute> pixelAttributeNames; - std::unordered_map<std::string, ShaderGlobalVec> globalAttributes; - bool mainFuncDefined; }; } diff --git a/include/RenderBackend/OpenGL/Shader.hpp b/include/RenderBackend/OpenGL/Shader.hpp new file mode 100644 index 0000000..7aecc4e --- /dev/null +++ b/include/RenderBackend/OpenGL/Shader.hpp @@ -0,0 +1,79 @@ +#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> + +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; + }; +} diff --git a/include/RenderBackend/OpenGL/ShaderVec.hpp b/include/RenderBackend/OpenGL/ShaderVec.hpp index 7c14af1..4353dd7 100644 --- a/include/RenderBackend/OpenGL/ShaderVec.hpp +++ b/include/RenderBackend/OpenGL/ShaderVec.hpp @@ -6,8 +6,7 @@ namespace amalgine { - class VertexShader; - class PixelShader; + class Shader; class ShaderProgram; enum class AttributeType @@ -22,8 +21,7 @@ namespace amalgine class ShaderGlobalVec { - friend class VertexShader; - friend class PixelShader; + friend class Shader; friend class ShaderGlobalVec3; public: ShaderGlobalVec() : attributeType(AttributeType::NONE) {} @@ -38,8 +36,7 @@ namespace amalgine class ShaderGlobalVec3 { - friend class VertexShader; - friend class PixelShader; + friend class Shader; public: const std::string& getName() const { return globalVec.getName(); } AttributeType getAttributeType() const { return globalVec.getAttributeType(); } @@ -64,19 +61,19 @@ namespace amalgine class ShaderInputVec2 { - friend class VertexShader; + friend class Shader; public: const std::string& getName() const; void setData(const DeviceMemory &data); private: - ShaderInputVec2(VertexShader *_vertexShader, i32 _attributeIndex) : - vertexShader(_vertexShader), + ShaderInputVec2(Shader *_shader, i32 _attributeIndex) : + shader(_shader), attributeIndex(_attributeIndex) { } private: - VertexShader *vertexShader; + Shader *shader; i32 attributeIndex; }; @@ -126,20 +123,20 @@ namespace amalgine class ShaderOutputVec4 { - friend class PixelShader; + friend class Shader; public: const std::string& getName() const; void operator=(const ShaderVec4 &shaderVec4); private: - ShaderOutputVec4(PixelShader *_pixelShader, i32 _attributeIndex) : - pixelShader(_pixelShader), + ShaderOutputVec4(Shader *_shader, i32 _attributeIndex) : + shader(_shader), attributeIndex(_attributeIndex) { } private: - PixelShader *pixelShader; + Shader *shader; i32 attributeIndex; }; } diff --git a/include/RenderBackend/OpenGL/VertexShader.hpp b/include/RenderBackend/OpenGL/VertexShader.hpp index aaf8b24..6fdd6a4 100644 --- a/include/RenderBackend/OpenGL/VertexShader.hpp +++ b/include/RenderBackend/OpenGL/VertexShader.hpp @@ -1,79 +1,20 @@ #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 "Shader.hpp" -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. - */ +namespace amalgine { class CompiledVertexShader; + + using VertexShaderMainFunc = std::function<ShaderVec4()>; - class VertexShader + class VertexShader : public Shader { DISABLE_COPY(VertexShader) friend class ShaderProgram; public: VertexShader(); - - const std::string& getInputAttributeName(i32 attributeIndex) const; - AttributeType getInputAttributeType(i32 attributeIndex) const; - ShaderInputVec2 defineInputVec2(const std::string &name); + void defineMain(VertexShaderMainFunc mainFunc); Result<CompiledVertexShader*> compile(); - private: - void writeHeader(const std::string &code); - void writeBody(const std::string &code); - std::string build() const; - - /* - * 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<ShaderAttribute> vertexAttributeNames; - bool mainFuncDefined; }; } diff --git a/src/RenderBackend/OpenGL/DeviceFrame.cpp b/src/RenderBackend/OpenGL/DeviceFrame.cpp index 9d60597..e79dfa1 100644 --- a/src/RenderBackend/OpenGL/DeviceFrame.cpp +++ b/src/RenderBackend/OpenGL/DeviceFrame.cpp @@ -28,9 +28,11 @@ namespace amalgine void DeviceFrame::draw() { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); for(DeviceMemory *deviceMemory : buffers) { deviceMemory->draw(); } + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } } diff --git a/src/RenderBackend/OpenGL/PixelShader.cpp b/src/RenderBackend/OpenGL/PixelShader.cpp index f263513..e6006f2 100644 --- a/src/RenderBackend/OpenGL/PixelShader.cpp +++ b/src/RenderBackend/OpenGL/PixelShader.cpp @@ -1,103 +1,18 @@ #include "../../../include/RenderBackend/OpenGL/PixelShader.hpp" #include "../../../include/RenderBackend/OpenGL/opengl.hpp" #include "../../../include/RenderBackend/OpenGL/CompiledShader.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() { - - } - - 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].name; + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxAttribs); } - - ShaderOutputVec4 PixelShader::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 PixelShader::defineGlobalVec3(const std::string &name) - { - if(!isShaderVariableNameValid(name.c_str())) - throw PixelShaderInvalidAttributeName(name); - - if(globalAttributes.find(name) != globalAttributes.end()) - throw PixelShaderAttributeAlreadyDefined(name); - - writeHeader("uniform vec3 "); - writeHeader(name); - writeHeader(";\n"); - - ShaderGlobalVec3 globalVec(name); - globalAttributes[name] = globalVec.getVecObject(); - return ShaderGlobalVec3(globalVec); - } - - 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; - writeHeader("out "); - writeHeader(typeName); - writeHeader(" "); - writeHeader(variableName); - writeHeader(";\n"); - - ShaderAttribute shaderAttribute; - shaderAttribute.name = variableName; - shaderAttribute.typeName = typeName; - pixelAttributeNames.push_back(shaderAttribute); - ++locationCounter; - return attributeIndex; - } - + void PixelShader::defineMain(PixelShaderMainFunc mainFunc) { if(mainFuncDefined) - throw PixelShaderFunctionAlreadyDefined("main"); + throw ShaderFunctionAlreadyDefined("main"); writeBody("void main() {\n"); mainFunc(); @@ -105,38 +20,13 @@ namespace amalgine writeBody("}\n\n"); } - void PixelShader::assign(const ShaderOutputVec4 &lhsVariable, const ShaderVec4 &rhsVariable) - { - writeBody(lhsVariable.getName()); - writeBody(" = "); - writeBody(rhsVariable.getOutput()); - writeBody(";\n"); - } - - string PixelShader::build() const - { - 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; - } - Result<CompiledPixelShader*> PixelShader::compile() { + if(!mainFuncDefined) + return Result<CompiledPixelShader*>::Err("main function not defined (defineMain not called)"); + GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER); - string verterShaderSource = build(); + std::string verterShaderSource = build(); const char *verterShaderSourcePtr = verterShaderSource.c_str(); printf("Vertex shader:\n%s\n", verterShaderSourcePtr); glShaderSource(fragmentShaderId, 1, &verterShaderSourcePtr, NULL); @@ -144,12 +34,12 @@ namespace amalgine GLint status; glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &status); - string compileLog = getShaderCompileLog((u32)fragmentShaderId); + 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(pixelAttributes))); + 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 new file mode 100644 index 0000000..fad1702 --- /dev/null +++ b/src/RenderBackend/OpenGL/Shader.cpp @@ -0,0 +1,169 @@ +#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; + } + + 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 + { + std::string result; + result.reserve(header.size() + 2 + body.size()); + result += header; + result += "\n"; + result += body; + return result; + } + + void Shader::writeHeader(const string &code) + { + header += code; + } + + void Shader::writeBody(const string &code) + { + body += code; + } +} diff --git a/src/RenderBackend/OpenGL/ShaderVec.cpp b/src/RenderBackend/OpenGL/ShaderVec.cpp index dd3bbe5..8897b84 100644 --- a/src/RenderBackend/OpenGL/ShaderVec.cpp +++ b/src/RenderBackend/OpenGL/ShaderVec.cpp @@ -1,6 +1,5 @@ #include "../../../include/RenderBackend/OpenGL/ShaderVec.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/opengl.hpp" #include <cstring> @@ -16,7 +15,16 @@ namespace amalgine { 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; } @@ -28,13 +36,13 @@ namespace amalgine const string& ShaderInputVec2::getName() const { - return vertexShader->getInputAttributeName(attributeIndex); + return shader->getInputAttributeName(attributeIndex); } void ShaderInputVec2::setData(const DeviceMemory &data) { data.use(); - AttributeType attributeType = vertexShader->getInputAttributeType(attributeIndex); + AttributeType attributeType = shader->getInputAttributeType(attributeIndex); switch(attributeType) { case AttributeType::VEC2: @@ -51,11 +59,11 @@ namespace amalgine const string& ShaderOutputVec4::getName() const { - return pixelShader->getOutputAttributeName(attributeIndex); + return shader->getOutputAttributeName(attributeIndex); } void ShaderOutputVec4::operator=(const ShaderVec4 &shaderVec4) { - pixelShader->assign(*this, shaderVec4); + shader->assign(*this, shaderVec4); } } diff --git a/src/RenderBackend/OpenGL/VertexShader.cpp b/src/RenderBackend/OpenGL/VertexShader.cpp index ac9a159..19705b6 100644 --- a/src/RenderBackend/OpenGL/VertexShader.cpp +++ b/src/RenderBackend/OpenGL/VertexShader.cpp @@ -2,62 +2,16 @@ #include "../../../include/RenderBackend/OpenGL/opengl.hpp" #include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp" -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) const - { - assert(attributeIndex < vertexAttributeNames.size()); - return vertexAttributeNames[attributeIndex].name; - } - - AttributeType VertexShader::getInputAttributeType(i32 attributeIndex) const +namespace amalgine { + VertexShader::VertexShader() { - assert(attributeIndex < vertexAttributeNames.size()); - return getAttributeTypeByName(vertexAttributeNames[attributeIndex].typeName); + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs); } - - 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"); + throw ShaderFunctionAlreadyDefined("main"); writeBody("void main() {\n"); ShaderVec4 glPosition = mainFunc(); @@ -66,60 +20,11 @@ namespace amalgine 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; - ShaderAttribute shaderAttribute; - shaderAttribute.name = variableName; - shaderAttribute.typeName = typeName; - vertexAttributeNames.push_back(shaderAttribute); - - writeHeader("layout(location = "); - writeHeader(to_string(locationCounter)); - ++locationCounter; - writeHeader(") in "); - writeHeader(typeName); - writeHeader(" "); - writeHeader(variableName); - writeHeader(";\n"); - return attributeIndex; - } - - string VertexShader::build() const - { - 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; - } - + Result<CompiledVertexShader*> VertexShader::compile() { GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER); - string verterShaderSource = build(); + std::string verterShaderSource = build(); const char *verterShaderSourcePtr = verterShaderSource.c_str(); printf("Vertex shader:\n%s\n", verterShaderSourcePtr); glShaderSource(vertexShaderId, 1, &verterShaderSourcePtr, NULL); @@ -127,7 +32,7 @@ namespace amalgine GLint status; glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &status); - string compileLog = getShaderCompileLog((u32)vertexShaderId); + std::string compileLog = getShaderCompileLog((u32)vertexShaderId); if(status == GL_TRUE) { if(!compileLog.empty()) diff --git a/src/main.cpp b/src/main.cpp index ada75e2..24ef4f8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -133,7 +133,16 @@ 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); |