#include #include "rendering/Shader.h" #include "utils/Logger.h" #include "wrapper/GL.h" Shader::Shader() : shaders(0), program(0) { } Shader::~Shader() { for(GL::Shader shader : shaders) { GL::deleteShader(shader); } GL::deleteProgram(program); } static bool endsWith(const char* path, int length, const char* ending) { int endingLength = strlen(ending); if(length < endingLength) { return false; } return strcmp(path + (length - endingLength), ending) == 0; } GL::ShaderType Shader::getShaderType(const char* path) const { int length = strlen(path); if(endsWith(path, length, ".vs")) { return GL::VERTEX_SHADER; } else if(endsWith(path, length, ".fs")) { return GL::FRAGMENT_SHADER; } else if(endsWith(path, length, ".gs")) { return GL::GEOMETRY_SHADER; } else if(endsWith(path, length, ".tcs")) { return GL::TESSELATION_CONTROL_SHADER; } else if(endsWith(path, length, ".tes")) { return GL::TESSELATION_EVALUATION_SHADER; } return GL::NO_SHADER; } Error Shader::readAndCompile(const char* path, GL::Shader& s, GL::ShaderType st) { List code; Error error = readFile(code, path); if(error.has()) { return error; } return compileType(s, code, st); } Error Shader::readFile(List& code, const char* path) const { std::ifstream in; in.open(path); if(!in.good()) { return {"cannot read file"}; } while(true) { int c = in.get(); if(c == EOF) { break; } code.add(c); } code.add('\0'); return {}; } Error Shader::compileType(GL::Shader& s, const List& code, GL::ShaderType st) { s = GL::createShader(st); GL::compileShader(s, code.begin()); Error error = GL::getError("compile error"); if(error.has()) { return error; } return GL::getCompileError(s); } void Shader::use() const { GL::useProgram(program); } void Shader::setMatrix(const char* name, const float* data) { GL::setMatrix(program, name, data); } void Shader::setInt(const char* name, int data) { GL::setInt(program, name, data); } void Shader::setFloat(const char* name, float data) { GL::setFloat(program, name, data); } void Shader::setVector(const char* name, const Vector2& v) { GL::set2Float(program, name, &(v[0])); } void Shader::setVector(const char* name, const Vector3& v) { GL::set3Float(program, name, &(v[0])); } void Shader::setVector(const char* name, const Vector4& v) { GL::set4Float(program, name, &(v[0])); }