aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/RenderBackend/OpenGL/PixelShader.hpp74
-rw-r--r--include/RenderBackend/OpenGL/Shader.hpp79
-rw-r--r--include/RenderBackend/OpenGL/ShaderVec.hpp25
-rw-r--r--include/RenderBackend/OpenGL/VertexShader.hpp71
-rw-r--r--src/RenderBackend/OpenGL/DeviceFrame.cpp2
-rw-r--r--src/RenderBackend/OpenGL/PixelShader.cpp130
-rw-r--r--src/RenderBackend/OpenGL/Shader.cpp169
-rw-r--r--src/RenderBackend/OpenGL/ShaderVec.cpp20
-rw-r--r--src/RenderBackend/OpenGL/VertexShader.cpp111
-rw-r--r--src/main.cpp9
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);