aboutsummaryrefslogtreecommitdiff
path: root/src/RenderBackend/OpenGL
diff options
context:
space:
mode:
Diffstat (limited to 'src/RenderBackend/OpenGL')
-rw-r--r--src/RenderBackend/OpenGL/CommonShader.cpp20
-rw-r--r--src/RenderBackend/OpenGL/CompiledShader.cpp37
-rw-r--r--src/RenderBackend/OpenGL/DeviceMemory.cpp11
-rw-r--r--src/RenderBackend/OpenGL/PixelShader.cpp67
-rw-r--r--src/RenderBackend/OpenGL/ShaderProgram.cpp113
-rw-r--r--src/RenderBackend/OpenGL/ShaderVec.cpp3
-rw-r--r--src/RenderBackend/OpenGL/VertexShader.cpp23
7 files changed, 198 insertions, 76 deletions
diff --git a/src/RenderBackend/OpenGL/CommonShader.cpp b/src/RenderBackend/OpenGL/CommonShader.cpp
new file mode 100644
index 0000000..ea88f62
--- /dev/null
+++ b/src/RenderBackend/OpenGL/CommonShader.cpp
@@ -0,0 +1,20 @@
+#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp"
+#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+
+using namespace std;
+
+namespace amalgine
+{
+ string getShaderCompileLog(u32 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;
+ }
+}
diff --git a/src/RenderBackend/OpenGL/CompiledShader.cpp b/src/RenderBackend/OpenGL/CompiledShader.cpp
new file mode 100644
index 0000000..6707b7a
--- /dev/null
+++ b/src/RenderBackend/OpenGL/CompiledShader.cpp
@@ -0,0 +1,37 @@
+#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
+#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+
+namespace amalgine
+{
+ CompiledVertexShader::CompiledVertexShader(u32 _shaderId) :
+ shaderId(_shaderId)
+ {
+
+ }
+
+ CompiledVertexShader::~CompiledVertexShader()
+ {
+ glDeleteShader(shaderId);
+ }
+
+ u32 CompiledVertexShader::getShaderId() const
+ {
+ return shaderId;
+ }
+
+ CompiledPixelShader::CompiledPixelShader(u32 _shaderId) :
+ shaderId(_shaderId)
+ {
+
+ }
+
+ CompiledPixelShader::~CompiledPixelShader()
+ {
+ glDeleteShader(shaderId);
+ }
+
+ u32 CompiledPixelShader::getShaderId() const
+ {
+ return shaderId;
+ }
+}
diff --git a/src/RenderBackend/OpenGL/DeviceMemory.cpp b/src/RenderBackend/OpenGL/DeviceMemory.cpp
index f166666..9e33ac9 100644
--- a/src/RenderBackend/OpenGL/DeviceMemory.cpp
+++ b/src/RenderBackend/OpenGL/DeviceMemory.cpp
@@ -8,17 +8,22 @@ namespace amalgine
glGenBuffers(1, &vertexBufferObjectId);
}
- void DeviceMemory::copyStatic(const DataView<f32> &data)
+ DeviceMemory::~DeviceMemory()
+ {
+ glDeleteBuffers(1, &vertexBufferObjectId);
+ }
+
+ void DeviceMemory::copyAsStatic(const DataView<f32> &data)
{
copy(data, GL_STATIC_DRAW);
}
- void DeviceMemory::copyDynamic(const DataView<f32> &data)
+ void DeviceMemory::copyAsDynamic(const DataView<f32> &data)
{
copy(data, GL_DYNAMIC_DRAW);
}
- void DeviceMemory::copyStream(const DataView<f32> &data)
+ void DeviceMemory::copyAsStream(const DataView<f32> &data)
{
copy(data, GL_STREAM_DRAW);
}
diff --git a/src/RenderBackend/OpenGL/PixelShader.cpp b/src/RenderBackend/OpenGL/PixelShader.cpp
index 2a7c913..2af68e5 100644
--- a/src/RenderBackend/OpenGL/PixelShader.cpp
+++ b/src/RenderBackend/OpenGL/PixelShader.cpp
@@ -1,4 +1,7 @@
#include "../../../include/RenderBackend/OpenGL/PixelShader.hpp"
+#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
+#include <cassert>
using namespace std;
@@ -28,11 +31,51 @@ namespace amalgine
}
- PixelShader::PixelShader() : mainFuncDefined(false)
+ 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;
+ }
+
+ ShaderOutputVec4 PixelShader::defineOutputVec4(const std::string &name)
+ {
+ i32 attributeIndex = defineOutputVariable(name, "vec4");
+ return ShaderOutputVec4(this, attributeIndex);
+ }
+
+ 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)
@@ -71,4 +114,26 @@ namespace amalgine
{
body += code;
}
+
+ Result<CompiledPixelShader*> PixelShader::compile()
+ {
+ GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
+ string verterShaderSource = build();
+ const char *verterShaderSourcePtr = verterShaderSource.c_str();
+ printf("Vertex shader:\n%s\n", verterShaderSourcePtr);
+ glShaderSource(fragmentShaderId, 1, &verterShaderSourcePtr, NULL);
+ glCompileShader(fragmentShaderId);
+
+ GLint status;
+ glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &status);
+ 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));
+ }
+ else
+ return Result<CompiledPixelShader*>::Err(compileLog);
+ }
}
diff --git a/src/RenderBackend/OpenGL/ShaderProgram.cpp b/src/RenderBackend/OpenGL/ShaderProgram.cpp
index 892f45e..f76903e 100644
--- a/src/RenderBackend/OpenGL/ShaderProgram.cpp
+++ b/src/RenderBackend/OpenGL/ShaderProgram.cpp
@@ -1,103 +1,74 @@
#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
-#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
using namespace std;
namespace amalgine
{
- string getShaderCompileLog(GLuint shaderId)
+ ShaderProgramUsedBeforeBuilt::ShaderProgramUsedBeforeBuilt() :
+ runtime_error("Shader program was used before it was built")
{
- 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)
+ ShaderProgram::ShaderProgram() : built(false)
{
- glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxPixelAttribs);
+ shaderProgramId = glCreateProgram();
}
- const string& ShaderProgram::getOutputAttributeName(i32 attributeIndex)
+ ShaderProgram::~ShaderProgram()
{
- assert(attributeIndex < pixelAttributeNames.size());
- return pixelAttributeNames[attributeIndex];
+ GLint numAttachedShaders;
+ glGetProgramiv(shaderProgramId, GL_ATTACHED_SHADERS, &numAttachedShaders);
+
+ GLuint *attachedShaders = new GLuint[numAttachedShaders];
+ glGetAttachedShaders(shaderProgramId, numAttachedShaders, nullptr, attachedShaders);
+
+ for(int i = 0; i < numAttachedShaders; ++i)
+ {
+ GLuint attachedShaderId = attachedShaders[i];
+ glDetachShader(shaderProgramId, attachedShaderId);
+ }
+
+ glDeleteProgram(shaderProgramId);
}
- ShaderOutputVec4 ShaderProgram::defineOutputVec4(const std::string &name)
- {
- i32 attributeIndex = defineOutputVariable(name, "vec4");
- return ShaderOutputVec4(this, attributeIndex);
- }
+ // TODO: Before adding shader to program, check if it has already been added
- i32 ShaderProgram::defineOutputVariable(const string &variableName, const char *typeName)
+ bool ShaderProgram::addVertexShader(CompiledVertexShader *vertexShader)
{
- 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;
+ // TODO: Do not allow adding shader if the program has already been built
+ glAttachShader(shaderProgramId, vertexShader->getShaderId());
+ return true;
}
- /*
- Result<string> ShaderProgram::addVertexShader(const VertexShader &vertexShader)
+ bool ShaderProgram::addPixelShader(CompiledPixelShader *pixelShader)
{
- 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);
+ // TODO: Do not allow adding shader if the program has already been built
+ glAttachShader(shaderProgramId, pixelShader->getShaderId());
+ return true;
}
- Result<string> ShaderProgram::addPixelShader(const PixelShader &pixelShader)
+ Result<bool> ShaderProgram::build()
{
- 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);
+ if(built)
+ return Result<bool>::Err("Shader program already built");
- 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);
+ glLinkProgram(shaderProgramId);
+ built = true;
+ return Result<bool>::Ok(true);
}
- void ShaderProgram::build()
+ void ShaderProgram::use()
{
- GLuint shaderProgramId = glCreateProgram();
- for(u32 shaderId : shaderIds)
+ if(built)
+ {
+ glUseProgram(shaderProgramId);
+ }
+ else
{
- glAttachShader(shaderProgramId, shaderId);
+ throw ShaderProgramUsedBeforeBuilt();
}
}
- */
}
diff --git a/src/RenderBackend/OpenGL/ShaderVec.cpp b/src/RenderBackend/OpenGL/ShaderVec.cpp
index 0dfb4c6..6411650 100644
--- a/src/RenderBackend/OpenGL/ShaderVec.cpp
+++ b/src/RenderBackend/OpenGL/ShaderVec.cpp
@@ -1,11 +1,12 @@
#include "../../../include/RenderBackend/OpenGL/ShaderVec.hpp"
#include "../../../include/RenderBackend/OpenGL/VertexShader.hpp"
#include "../../../include/RenderBackend/OpenGL/PixelShader.hpp"
+#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
using namespace std;
namespace amalgine
-{
+{
const string& ShaderInputVec2::getName() const
{
return vertexShader->getInputAttributeName(attributeIndex);
diff --git a/src/RenderBackend/OpenGL/VertexShader.cpp b/src/RenderBackend/OpenGL/VertexShader.cpp
index 04bf863..1505ff4 100644
--- a/src/RenderBackend/OpenGL/VertexShader.cpp
+++ b/src/RenderBackend/OpenGL/VertexShader.cpp
@@ -1,6 +1,7 @@
#include "../../../include/RenderBackend/OpenGL/VertexShader.hpp"
#include "../../../include/RenderBackend/OpenGL/CommonShader.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
using namespace std;
@@ -106,4 +107,26 @@ namespace amalgine
{
body += code;
}
+
+ Result<CompiledVertexShader*> VertexShader::compile()
+ {
+ GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
+ string verterShaderSource = build();
+ const char *verterShaderSourcePtr = verterShaderSource.c_str();
+ printf("Vertex shader:\n%s\n", verterShaderSourcePtr);
+ glShaderSource(vertexShaderId, 1, &verterShaderSourcePtr, NULL);
+ glCompileShader(vertexShaderId);
+
+ GLint status;
+ glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &status);
+ string compileLog = getShaderCompileLog((u32)vertexShaderId);
+ if(status == GL_TRUE)
+ {
+ if(!compileLog.empty())
+ printf("Vertex shader compile log:\n%s", compileLog.c_str());
+ return Result<CompiledVertexShader*>::Ok(new CompiledVertexShader(vertexShaderId));
+ }
+ else
+ return Result<CompiledVertexShader*>::Err(compileLog);
+ }
}