From 23a37b2cdd8ffde8bb85a4159888bf3a7ec35966 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 4 Nov 2019 00:50:45 +0100 Subject: Use external shaders instead of generating shader code from c++ code... --- src/RenderBackend/OpenGL/ShaderProgram.cpp | 116 ++++++++++++++--------------- 1 file changed, 54 insertions(+), 62 deletions(-) (limited to 'src/RenderBackend/OpenGL/ShaderProgram.cpp') 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 ShaderProgram::build() - { - if(built) - return Result::Err("Shader program already built"); + // static + Result> ShaderProgram::build(const std::vector &shaders) { + u32 shader_program_id = glCreateProgram(); + if(shader_program_id == 0) + return Result>::Err("Failed to create shader program"); - glLinkProgram(shaderProgramId); - built = true; - return Result::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 shader_program; + shader_program.reset(new ShaderProgram(shader_program_id)); + return Result>::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); } } -- cgit v1.2.3