100 lines
1.8 KiB
C++
100 lines
1.8 KiB
C++
|
|
#include <fstream>
|
|
#include <Spectre/System/File.h>
|
|
#include <Spectre/Graphics/OpenGL.h>
|
|
#include <Spectre/Graphics/Shader.h>
|
|
|
|
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<char>(strm), std::istreambuf_iterator<char>());
|
|
|
|
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);
|
|
}
|