#include #include #include #include namespace sp { Shader::Shader(Type type, const std::string& name) : m_name (name) { GLenum internal_type = type == Vertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER; m_handle = glCreateShader(internal_type); } Shader::~Shader() { if (m_handle) { glDeleteShader(m_handle); } } unsigned int Shader::getHandle() const { return m_handle; } const std::string& Shader::getName() const { return m_name; } bool Shader::loadFromFile(const std::string& filename) { std::string src; File file; // If this shader does not have a name, pick the filename. if (m_name.length() < 1) { m_name = Path::getBasename(filename); } if (!file.open(filename)) { m_error = "Can't open file: " + filename; return false; } // Load file into memory. if (!file.read(src)) { m_error = "Could not read file: " + filename; return false; } return loadFromMemory(src); } bool Shader::loadFromMemory(const std::string& source) { const char *s = source.c_str(); glShaderSource(m_handle, 1, &s, NULL); return compile(); } const std::string& Shader::getError() const { return m_error; } bool Shader::isCompiled() const { // A shader without handle is not compiled. if (m_handle) { // Query OpenGL for status. GLint status; glGetShaderiv(m_handle, GL_COMPILE_STATUS, &status); return status == GL_TRUE; } return false; } bool Shader::compile() { glCompileShader(m_handle); if (!isCompiled()) { m_error = fetchErrorLog(); return false; } return true; } std::string Shader::fetchErrorLog() { GLchar buf[4096] = { '\0' }; glGetShaderInfoLog(m_handle, sizeof(buf), NULL, buf); return std::string(buf); } } // namespace sp