#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp" #include "../../../include/RenderBackend/OpenGL/CommonShader.hpp" #include "../../../include/RenderBackend/OpenGL/opengl.hpp" using namespace std; namespace amalgine { string getShaderCompileLog(GLuint 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; } ShaderProgram::ShaderProgram() : locationCounter(0) { glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxPixelAttribs); } const string& ShaderProgram::getOutputAttributeName(i32 attributeIndex) { assert(attributeIndex < pixelAttributeNames.size()); return pixelAttributeNames[attributeIndex]; } ShaderOutputVec4 ShaderProgram::defineOutputVec4(const std::string &name) { i32 attributeIndex = defineOutputVariable(name, "vec4"); return ShaderOutputVec4(this, attributeIndex); } i32 ShaderProgram::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; pixelAttributeNames.push_back(variableName); ++locationCounter; return attributeIndex; } /* Result ShaderProgram::addVertexShader(const VertexShader &vertexShader) { 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::Ok(compileLog); else return Result::Err(compileLog); } Result ShaderProgram::addPixelShader(const PixelShader &pixelShader) { 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); GLint status; glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &status); string compileLog = getShaderCompileLog(fragmentShaderId); if(status == GL_TRUE) return Result::Ok(compileLog); else return Result::Err(compileLog); } void ShaderProgram::build() { GLuint shaderProgramId = glCreateProgram(); for(u32 shaderId : shaderIds) { glAttachShader(shaderProgramId, shaderId); } } */ }