diff options
Diffstat (limited to 'src/RenderBackend/OpenGL/ShaderProgram.cpp')
-rw-r--r-- | src/RenderBackend/OpenGL/ShaderProgram.cpp | 113 |
1 files changed, 42 insertions, 71 deletions
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(); } } - */ } |