aboutsummaryrefslogtreecommitdiff
path: root/src/RenderBackend/OpenGL/ShaderProgram.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/RenderBackend/OpenGL/ShaderProgram.cpp')
-rw-r--r--src/RenderBackend/OpenGL/ShaderProgram.cpp116
1 files changed, 54 insertions, 62 deletions
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);
}
}