aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-11-04 00:50:45 +0100
committerdec05eba <dec05eba@protonmail.com>2021-11-18 15:21:48 +0100
commit23a37b2cdd8ffde8bb85a4159888bf3a7ec35966 (patch)
tree83db7b81936621b6a2435e9b5db0de18496cd12f /src
parentfbd2e5d9a802db4fb5e056705ec599ac423e09be (diff)
Use external shaders instead of generating shader code from c++ code...
Diffstat (limited to 'src')
-rw-r--r--src/RenderBackend/OpenGL/CommonShader.cpp20
-rw-r--r--src/RenderBackend/OpenGL/CompiledShader.cpp40
-rw-r--r--src/RenderBackend/OpenGL/DeviceFrame.cpp9
-rw-r--r--src/RenderBackend/OpenGL/DeviceMemory.cpp10
-rw-r--r--src/RenderBackend/OpenGL/PixelShader.cpp47
-rw-r--r--src/RenderBackend/OpenGL/Shader.cpp198
-rw-r--r--src/RenderBackend/OpenGL/ShaderProgram.cpp116
-rw-r--r--src/RenderBackend/OpenGL/ShaderVec.cpp69
-rw-r--r--src/RenderBackend/OpenGL/VertexShader.cpp45
-rw-r--r--src/main.cpp116
10 files changed, 145 insertions, 525 deletions
diff --git a/src/RenderBackend/OpenGL/CommonShader.cpp b/src/RenderBackend/OpenGL/CommonShader.cpp
deleted file mode 100644
index ea88f62..0000000
--- a/src/RenderBackend/OpenGL/CommonShader.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#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
deleted file mode 100644
index f4a1fec..0000000
--- a/src/RenderBackend/OpenGL/CompiledShader.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-
-using namespace std;
-
-namespace amalgine
-{
- CompiledVertexShader::CompiledVertexShader(u32 _shaderId) :
- shaderId(_shaderId)
- {
-
- }
-
- CompiledVertexShader::~CompiledVertexShader()
- {
- glDeleteShader(shaderId);
- }
-
- u32 CompiledVertexShader::getShaderId() const
- {
- return shaderId;
- }
-
- CompiledPixelShader::CompiledPixelShader(u32 _shaderId, unordered_map<string, i32> &&_pixelAttributes) :
- shaderId(_shaderId),
- pixelAttributes(_pixelAttributes)
- {
-
- }
-
- CompiledPixelShader::~CompiledPixelShader()
- {
- glDeleteShader(shaderId);
- }
-
- u32 CompiledPixelShader::getShaderId() const
- {
- return shaderId;
- }
-}
diff --git a/src/RenderBackend/OpenGL/DeviceFrame.cpp b/src/RenderBackend/OpenGL/DeviceFrame.cpp
index e79dfa1..2132f83 100644
--- a/src/RenderBackend/OpenGL/DeviceFrame.cpp
+++ b/src/RenderBackend/OpenGL/DeviceFrame.cpp
@@ -1,6 +1,7 @@
#include "../../../include/RenderBackend/OpenGL/DeviceFrame.hpp"
#include "../../../include/RenderBackend/OpenGL/DeviceMemory.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
namespace amalgine
{
@@ -26,13 +27,13 @@ namespace amalgine
return deviceMemory;
}
- void DeviceFrame::draw()
- {
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ void DeviceFrame::draw(ShaderProgram *shader) {
+ shader->use();
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
for(DeviceMemory *deviceMemory : buffers)
{
deviceMemory->draw();
}
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
}
diff --git a/src/RenderBackend/OpenGL/DeviceMemory.cpp b/src/RenderBackend/OpenGL/DeviceMemory.cpp
index 0dd3e89..2d40569 100644
--- a/src/RenderBackend/OpenGL/DeviceMemory.cpp
+++ b/src/RenderBackend/OpenGL/DeviceMemory.cpp
@@ -33,7 +33,7 @@ namespace amalgine
}
}
- DeviceMemory::DeviceMemory() : primitiveType(0), numVertices(0)
+ DeviceMemory::DeviceMemory() : primitiveType(0), numVertices(0), type(DeviceMemoryType::NONE)
{
glGenBuffers(1, &vertexBufferObjectId);
}
@@ -43,11 +43,6 @@ namespace amalgine
glDeleteBuffers(1, &vertexBufferObjectId);
}
- void DeviceMemory::operator delete(void *data)
- {
- free(data);
- }
-
void DeviceMemory::use() const
{
// TODO: Bind vao here?
@@ -68,12 +63,11 @@ namespace amalgine
glBufferData(GL_ARRAY_BUFFER, triangles.getByteSize(), triangles.data, getOpenglStorageType(storageType));
primitiveType = GL_TRIANGLES;
numVertices = triangles.size * 3;
+ type = DeviceMemoryType::VEC2;
}
void DeviceMemory::draw()
{
- if(primitiveType == 0)
- throw DeviceMemoryEmpty("Unable to draw buffer as no data has been copied to device memory");
glDrawArrays(primitiveType, 0, numVertices);
}
}
diff --git a/src/RenderBackend/OpenGL/PixelShader.cpp b/src/RenderBackend/OpenGL/PixelShader.cpp
deleted file mode 100644
index e6006f2..0000000
--- a/src/RenderBackend/OpenGL/PixelShader.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "../../../include/RenderBackend/OpenGL/PixelShader.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
-
-namespace amalgine
-{
- PixelShader::PixelShader()
- {
- glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxAttribs);
- }
-
- void PixelShader::defineMain(PixelShaderMainFunc mainFunc)
- {
- if(mainFuncDefined)
- throw ShaderFunctionAlreadyDefined("main");
-
- writeBody("void main() {\n");
- mainFunc();
- mainFuncDefined = true;
- writeBody("}\n\n");
- }
-
- Result<CompiledPixelShader*> PixelShader::compile()
- {
- if(!mainFuncDefined)
- return Result<CompiledPixelShader*>::Err("main function not defined (defineMain not called)");
-
- GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
- std::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);
- 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(inputAttributes)));
- }
- else
- return Result<CompiledPixelShader*>::Err(compileLog);
- }
-}
diff --git a/src/RenderBackend/OpenGL/Shader.cpp b/src/RenderBackend/OpenGL/Shader.cpp
index fad1702..3b6563f 100644
--- a/src/RenderBackend/OpenGL/Shader.cpp
+++ b/src/RenderBackend/OpenGL/Shader.cpp
@@ -1,169 +1,55 @@
#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;
+ static GLuint to_opengl_shader_type(Shader::Type type) {
+ switch(type) {
+ case Shader::Type::VERTEX:
+ return GL_VERTEX_SHADER;
+ case Shader::Type::PIXEL:
+ return GL_FRAGMENT_SHADER;
+ }
+ assert(false);
}
- 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
+ static std::string get_shader_compile_log(GLuint shaderId)
{
std::string result;
- result.reserve(header.size() + 2 + body.size());
- result += header;
- result += "\n";
- result += body;
+ GLint shaderLogLength;
+ glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &shaderLogLength);
+ if(shaderLogLength > 0) {
+ result.resize(shaderLogLength);
+ glGetShaderInfoLog(shaderId, shaderLogLength, NULL, &result[0]);
+ }
return result;
}
-
- void Shader::writeHeader(const string &code)
- {
- header += code;
+
+ Shader::Shader(u32 shader_id) : id(shader_id) {
+
}
-
- void Shader::writeBody(const string &code)
- {
- body += code;
+
+ Shader::~Shader() {
+ glDeleteShader(id);
+ }
+
+ // static
+ Result<std::unique_ptr<Shader>> Shader::compile(Type type, const char *str, int size) {
+ GLuint shader_id = glCreateShader(to_opengl_shader_type(type));
+ GLint shader_lengths[1] = { size };
+ glShaderSource(shader_id, 1, &str, shader_lengths);
+ glCompileShader(shader_id);
+
+ GLint status;
+ glGetShaderiv(shader_id, GL_COMPILE_STATUS, &status);
+ std::string compileLog = get_shader_compile_log(shader_id);
+ if(status == GL_TRUE) {
+ if(!compileLog.empty())
+ fprintf(stderr, "Shader compile log:\n%s", compileLog.c_str());
+ std::unique_ptr<Shader> shader;
+ shader.reset(new Shader(shader_id));
+ return Result<std::unique_ptr<Shader>>::Ok(std::move(shader));
+ }
+ else
+ return Result<std::unique_ptr<Shader>>::Err(compileLog);
}
}
diff --git a/src/RenderBackend/OpenGL/ShaderProgram.cpp b/src/RenderBackend/OpenGL/ShaderProgram.cpp
index aceda3b..e613668 100644
--- a/src/RenderBackend/OpenGL/ShaderProgram.cpp
+++ b/src/RenderBackend/OpenGL/ShaderProgram.cpp
@@ -1,56 +1,34 @@
#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
+
+#include "../../../include/RenderBackend/OpenGL/Shader.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
using namespace std;
-namespace amalgine
-{
- ShaderProgramUsedBeforeBuilt::ShaderProgramUsedBeforeBuilt() :
- runtime_error("Shader program was used before it was built")
- {
+namespace amalgine {
+ ShaderProgram::ShaderProgram(u32 shader_program_id) : program_id(shader_program_id) {
}
- ShaderProgramNonExistingGlobalVariable::ShaderProgramNonExistingGlobalVariable(const char *variableName) :
- runtime_error(string("There is no shader global variable with the name '") + variableName + "'")
- {
-
- }
-
- ShaderProgram::ShaderProgram() : built(false)
- {
- shaderProgramId = glCreateProgram();
- }
-
ShaderProgram::~ShaderProgram()
{
GLint numAttachedShaders;
- glGetProgramiv(shaderProgramId, GL_ATTACHED_SHADERS, &numAttachedShaders);
+ glGetProgramiv(program_id, GL_ATTACHED_SHADERS, &numAttachedShaders);
GLuint *attachedShaders = new GLuint[numAttachedShaders];
- glGetAttachedShaders(shaderProgramId, numAttachedShaders, nullptr, attachedShaders);
+ glGetAttachedShaders(program_id, numAttachedShaders, nullptr, attachedShaders);
for(int i = 0; i < numAttachedShaders; ++i)
{
GLuint attachedShaderId = attachedShaders[i];
- glDetachShader(shaderProgramId, attachedShaderId);
+ glDetachShader(program_id, attachedShaderId);
}
- glDeleteProgram(shaderProgramId);
- }
-
- // TODO: Before adding shader to program, check if it has already been added
-
- bool ShaderProgram::setVertexShader(CompiledVertexShader *vertexShader)
- {
- if(!vertexShader) return false;
-
- // TODO: Do not allow adding shader if the program has already been built
- glAttachShader(shaderProgramId, vertexShader->getShaderId());
- return true;
+ glDeleteProgram(program_id);
+ delete []attachedShaders;
}
+ #if 0
bool ShaderProgram::setPixelShader(CompiledPixelShader *pixelShader)
{
if(!pixelShader) return false;
@@ -68,41 +46,55 @@ namespace amalgine
return true;
}
+ #endif
- Result<bool> ShaderProgram::build()
- {
- if(built)
- return Result<bool>::Err("Shader program already built");
+ // static
+ Result<std::unique_ptr<ShaderProgram>> ShaderProgram::build(const std::vector<Shader*> &shaders) {
+ u32 shader_program_id = glCreateProgram();
+ if(shader_program_id == 0)
+ return Result<std::unique_ptr<ShaderProgram>>::Err("Failed to create shader program");
- glLinkProgram(shaderProgramId);
- built = true;
- return Result<bool>::Ok(true);
- }
-
- void ShaderProgram::use()
- {
- if(built)
- {
- glUseProgram(shaderProgramId);
- }
- else
- {
- throw ShaderProgramUsedBeforeBuilt();
+ for(Shader *shader : shaders) {
+ glAttachShader(shader_program_id, shader->id);
}
+
+ glLinkProgram(shader_program_id);
+ std::unique_ptr<ShaderProgram> shader_program;
+ shader_program.reset(new ShaderProgram(shader_program_id));
+ return Result<std::unique_ptr<ShaderProgram>>::Ok(std::move(shader_program));
}
-
- ShaderProgramGlobalVec3 ShaderProgram::getGlobalVec3(const char *name)
- {
- if(built)
- {
- GLint uniformId = glGetUniformLocation(shaderProgramId, name);
- if(uniformId == -1)
- throw ShaderProgramNonExistingGlobalVariable(name);
- return ShaderProgramGlobalVec3(this, uniformId);
+
+ int ShaderProgram::set_uniform(const char *name, const vec3f &value) {
+ GLint uniformId = glGetUniformLocation(program_id, name);
+ if(uniformId == -1)
+ return -1;
+ use();
+ glUniform3f(uniformId, value.x, value.y, value.z);
+ return 0;
+ }
+
+ int ShaderProgram::set_vertex_input(const char *name, const DeviceMemory &data) {
+ GLint attrib_location = glGetAttribLocation(program_id, name);
+ if(attrib_location == -1) {
+ fprintf(stderr, "No such attribute in shader: %s\n", name);
+ return -1;
}
- else
- {
- throw ShaderProgramUsedBeforeBuilt();
+
+ data.use();
+ switch(data.get_type()) {
+ case DeviceMemoryType::NONE:
+ return -1;
+ case DeviceMemoryType::VEC2: {
+ glVertexAttribPointer(attrib_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
+ break;
+ }
+ case DeviceMemoryType::VEC3: assert(false); return -1;
}
+ glEnableVertexAttribArray(attrib_location);
+ return 0;
+ }
+
+ void ShaderProgram::use() {
+ glUseProgram(program_id);
}
}
diff --git a/src/RenderBackend/OpenGL/ShaderVec.cpp b/src/RenderBackend/OpenGL/ShaderVec.cpp
deleted file mode 100644
index 8897b84..0000000
--- a/src/RenderBackend/OpenGL/ShaderVec.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include "../../../include/RenderBackend/OpenGL/ShaderVec.hpp"
-#include "../../../include/RenderBackend/OpenGL/Shader.hpp"
-#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include <cstring>
-#include <cassert>
-
-using namespace std;
-
-namespace amalgine
-{
- AttributeType getAttributeTypeByName(const char *attributeName)
- {
- if(strncmp(attributeName, "vec2", 4) == 0)
- {
- 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;
- }
-
- void ShaderProgramGlobalVec3::set(f32 x, f32 y, f32 z)
- {
- shaderProgram->use();
- glUniform3f(uniformId, x, y, z);
- }
-
- const string& ShaderInputVec2::getName() const
- {
- return shader->getInputAttributeName(attributeIndex);
- }
-
- void ShaderInputVec2::setData(const DeviceMemory &data)
- {
- data.use();
- AttributeType attributeType = shader->getInputAttributeType(attributeIndex);
- switch(attributeType)
- {
- case AttributeType::VEC2:
- {
- glVertexAttribPointer(attributeIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
- break;
- }
- default:
- assert(false);
- break;
- }
- glEnableVertexAttribArray(attributeIndex);
- }
-
- const string& ShaderOutputVec4::getName() const
- {
- return shader->getOutputAttributeName(attributeIndex);
- }
-
- void ShaderOutputVec4::operator=(const ShaderVec4 &shaderVec4)
- {
- shader->assign(*this, shaderVec4);
- }
-}
diff --git a/src/RenderBackend/OpenGL/VertexShader.cpp b/src/RenderBackend/OpenGL/VertexShader.cpp
deleted file mode 100644
index 19705b6..0000000
--- a/src/RenderBackend/OpenGL/VertexShader.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "../../../include/RenderBackend/OpenGL/VertexShader.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include "../../../include/RenderBackend/OpenGL/CompiledShader.hpp"
-
-namespace amalgine {
- VertexShader::VertexShader()
- {
- glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs);
- }
-
- void VertexShader::defineMain(VertexShaderMainFunc mainFunc)
- {
- if(mainFuncDefined)
- throw ShaderFunctionAlreadyDefined("main");
-
- writeBody("void main() {\n");
- ShaderVec4 glPosition = mainFunc();
- mainFuncDefined = true;
- writeBody("gl_Position = ");
- writeBody(glPosition.getOutput());
- writeBody(";\n}\n\n");
- }
-
- Result<CompiledVertexShader*> VertexShader::compile()
- {
- GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
- std::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);
- std::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);
- }
-}
diff --git a/src/main.cpp b/src/main.cpp
index 24ef4f8..f6f827f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,6 @@
#include <cstdio>
#include "../include/RenderBackend/OpenGL/opengl.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/DeviceMemory.hpp"
#include "../include/RenderBackend/OpenGL/DeviceFrame.hpp"
@@ -16,13 +15,11 @@
using namespace amalgine;
using namespace std;
-void glfwErrorHandler(int errorCode, const char *errorDescription);
-void initGlfw();
-void initGlew();
-GLFWwindow *createWindow();
-
-CompiledVertexShader* createVertexShader(const DeviceMemory &inputData);
-CompiledPixelShader* createPixelShader();
+static void glfwErrorHandler(int errorCode, const char *errorDescription);
+static void initGlfw();
+static void initGlew();
+static GLFWwindow *createWindow();
+static std::unique_ptr<Shader> load_shader_from_file(const char *filepath, Shader::Type shader_type);
int main()
{
@@ -40,25 +37,19 @@ int main()
DataView<Triangle2D> cpuTriangles(&cpuTriangle, 1);
DeviceMemory *gpuTriangle = frame.alloc();
gpuTriangle->copy(cpuTriangles, DeviceMemory::StorageType::STATIC);
+
+ std::unique_ptr<Shader> vertex_shader = load_shader_from_file("shaders/vertex.vert", Shader::Type::VERTEX);
+ std::unique_ptr<Shader> pixel_shader = load_shader_from_file("shaders/fragment.frag", Shader::Type::PIXEL);
- CompiledVertexShader *vertexShader = createVertexShader(*gpuTriangle);
- CompiledPixelShader *pixelShader = createPixelShader();
-
- ShaderProgram shaderProgram;
- shaderProgram.setVertexShader(vertexShader);
- shaderProgram.setPixelShader(pixelShader);
- // Make ShaderProgram.build return an object which we can do things on? since some operations
- // require the shader to be built to be used
- Result<bool> shaderBuildResult = shaderProgram.build();
-
- ShaderProgramGlobalVec3 triangleColor = shaderProgram.getGlobalVec3("triangleColor");
- triangleColor.set(1.0f, 0.0f, 0.0f);
-
- if(!shaderBuildResult)
- {
- fprintf(stderr, "Failed to build shader program: %s\n", shaderBuildResult.getErrorMsg().c_str());
- exit(20);
+ Result<std::unique_ptr<ShaderProgram>> shader_program_result = ShaderProgram::build({ vertex_shader.get(), pixel_shader.get() });
+ if(!shader_program_result) {
+ fprintf(stderr, "Failed to link shaders, error: %s\n", shader_program_result.getErrorMsg().c_str());
+ exit(13);
}
+ std::unique_ptr<ShaderProgram> shader_program = std::move(shader_program_result.unwrap());
+
+ shader_program->set_vertex_input("position", *gpuTriangle);
+ shader_program->set_uniform("triangle_color", vec3f{ 1.0f, 0.0f, 0.0f });
while(!glfwWindowShouldClose(window))
{
@@ -70,8 +61,7 @@ int main()
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Do the actual screen clearing, using the color set using glClearColor
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- shaderProgram.use();
- frame.draw();
+ frame.draw(shader_program.get());
glfwSwapBuffers(window);
}
@@ -128,53 +118,31 @@ GLFWwindow* createWindow()
return window;
}
-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);
- });
-
- Result<CompiledVertexShader*> compiledVertexShader = vertexShader.compile();
- if(!compiledVertexShader)
- {
- fprintf(stderr, "Failed to compile vertex shader:\n%s", compiledVertexShader.getErrorMsg().c_str());
- exit(2);
+static int file_read_all(const char *filepath, std::string &result) {
+ FILE *file = fopen(filepath, "rb");
+ if(!file) {
+ perror("file_read_all");
+ return errno;
}
-
- return compiledVertexShader.unwrap();
+
+ fseek(file, 0, SEEK_END);
+ size_t file_size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ result.resize(file_size);
+ fread(&result[0], 1, result.size(), file);
+ fclose(file);
+ return 0;
}
-CompiledPixelShader* createPixelShader()
-{
- PixelShader pixelShader;
- ShaderGlobalVec3 triangleColor = pixelShader.defineGlobalVec3("triangleColor");
- ShaderOutputVec4 outColor = pixelShader.defineOutputVec4("outColor");
-
- pixelShader.defineMain([&triangleColor, &outColor]()
- {
- outColor = ShaderVec4(triangleColor, 1.0f);
- });
-
- Result<CompiledPixelShader*> compiledPixelShader = pixelShader.compile();
- if(!compiledPixelShader)
- {
- fprintf(stderr, "Failed to compile pixel shader:\n%s", compiledPixelShader.getErrorMsg().c_str());
- exit(2);
+std::unique_ptr<Shader> load_shader_from_file(const char *filepath, Shader::Type shader_type) {
+ std::string file_content;
+ if(file_read_all(filepath, file_content) != 0)
+ exit(13);
+
+ Result<std::unique_ptr<Shader>> vertex_shader_result = Shader::compile(shader_type, file_content.data(), file_content.size());
+ if(!vertex_shader_result) {
+ fprintf(stderr, "Failed to compile shader, error: %s\n", vertex_shader_result.getErrorMsg().c_str());
+ exit(12);
}
-
- return compiledPixelShader.unwrap();
-}
+ return std::move(vertex_shader_result.unwrap());
+} \ No newline at end of file