#include #include #include #include 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& file) { std::string src; std::ifstream strm; // If this shader does not have a name, pick the filename. if (m_name.length() < 1) { m_name = File::getBasename(file); } // Load file into memory. strm.open(file.c_str(), std::fstream::in); if (!strm.is_open()) { m_error = "Can't open file: " + file; return false; } src.assign(std::istreambuf_iterator(strm), std::istreambuf_iterator()); strm.close(); 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); }