3#include "common/maths/Vec.h" 
   12    Shader::Shader(
const String& filepathVertexShader, 
const String& filepathPixelShader)
 
   13        : m_FilePathVS(filepathVertexShader)
 
   14        , m_FilePathPS(filepathPixelShader)
 
   17        ShaderProgramSource source = parseShader(filepathVertexShader, filepathPixelShader);
 
   19        m_RendererID = createShader(source.VertexSource, source.PixelSource);
 
   21        GLCall(glUseProgram(m_RendererID));
 
   23        if (m_RendererID == -1)
 
   25            ERROR(
"Shader creation failed");
 
   31        GLCall(glDeleteProgram(m_RendererID));
 
   34    void Shader::Bind()
 const 
   36        GLCall(glUseProgram(m_RendererID));
 
   39    void Shader::Unbind()
 const 
   41        GLCall(glUseProgram(0));
 
   44    int Shader::getUniformLocation(
const std::string& name)
 
   46        if (m_UniformLocationCache.find(name) != m_UniformLocationCache.end())
 
   47            return m_UniformLocationCache[name];
 
   49        GLCall(
int location = glGetUniformLocation(m_RendererID, name.c_str()));
 
   51            std::cout << 
"No active uniform variable with name " << name << 
" found" << std::endl;
 
   53        m_UniformLocationCache[name] = location;
 
   58    void Shader::SetUniform1i(
const std::string& name, 
int value)
 
   60        GLCall(glUniform1i(getUniformLocation(name), value));
 
   63    void Shader::SetUniform1f(
const std::string& name, 
float value)
 
   65        GLCall(glUniform1f(getUniformLocation(name), value));
 
   68    void Shader::SetUniform3f(
const std::string& name, Maths::Vec3& value)
 
   70        GLCall(glUniform3f(getUniformLocation(name), (GLfloat)value.x, (GLfloat)value.y, (GLfloat)value.z));
 
   73    void Shader::SetUniform4f(
const std::string& name, 
float f0, 
float f1, 
float f2, 
float f3)
 
   75        GLCall(glUniform4f(getUniformLocation(name), f0, f1, f2, f3));
 
   78    void Shader::SetUniform4f(
const std::string& name, 
const glm::vec4& matrix)
 
   80        GLCall(glUniform4f(getUniformLocation(name), matrix.x, matrix.y, matrix.z, matrix.w));
 
   83    void Shader::SetUniformMat4f(
const std::string& name, 
const glm::mat4& matrix)
 
   85        GLCall(glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &matrix[0][0]));
 
   95    struct ShaderProgramSource
 
   96    Shader::parseShader(const std::string& filepathVertexShader, const std::string& filepathPixelShader)
 
   98        std::ifstream streamVS(filepathVertexShader);
 
   99        std::ifstream streamPS(filepathPixelShader);
 
  101        std::stringstream ss[2];
 
  102        ShaderType type = NONE;
 
  104        while (getline(streamVS, line))
 
  106            ss[VERTEX] << line << 
'\n';
 
  108        while (getline(streamPS, line))
 
  110            ss[PIXEL] << line << 
'\n';
 
  113        return { ss[0].str(), ss[1].str() };
 
  116    unsigned int Shader::compileShader(
unsigned int type, 
const std::string& source)
 
  118        GLCall(
unsigned int id = glCreateShader(type));
 
  119        const char* src = source.c_str();
 
  120        GLCall(glShaderSource(
id, 1, &src, 
nullptr));
 
  121        GLCall(glCompileShader(
id));
 
  125        GLCall(glGetShaderiv(
id, GL_COMPILE_STATUS, &result));
 
  126        std::cout << (type == GL_VERTEX_SHADER ? 
"vertex" : 
"pixel") << 
" shader compile status: " << result
 
  128        if (result == GL_FALSE)
 
  131            GLCall(glGetShaderiv(
id, GL_INFO_LOG_LENGTH, &length));
 
  132            char* message = (
char*)alloca(length * 
sizeof(
char));
 
  133            GLCall(glGetShaderInfoLog(
id, length, &length, message));
 
  135                << 
"Failed to compile " 
  136                << (type == GL_VERTEX_SHADER ? 
"vertex" : 
"pixel")
 
  139            std::cout << message << std::endl;
 
  140            GLCall(glDeleteShader(
id));
 
  147    unsigned int Shader::createShader(
const std::string& vertexShader, 
const std::string& pixelShader)
 
  149        unsigned int program = glCreateProgram();
 
  150        unsigned int vs = compileShader(GL_VERTEX_SHADER, vertexShader);
 
  151        unsigned int ps = compileShader(GL_FRAGMENT_SHADER, pixelShader);
 
  153        if (vs == 0 || ps == 0)
 
  158        GLCall(glAttachShader(program, vs));
 
  159        GLCall(glAttachShader(program, ps));
 
  161        GLCall(glLinkProgram(program));
 
  163        GLint program_linked;
 
  165        GLCall(glGetProgramiv(program, GL_LINK_STATUS, &program_linked));
 
  166        std::cout << 
"Program link status: " << program_linked << std::endl;
 
  167        if (program_linked != GL_TRUE)
 
  169            GLsizei log_length = 0;
 
  170            GLchar message[1024];
 
  171            GLCall(glGetProgramInfoLog(program, 1024, &log_length, message));
 
  172            std::cout << 
"Failed to link program" << std::endl;
 
  173            std::cout << message << std::endl;
 
  177        GLCall(glValidateProgram(program));
 
  179        GLCall(glDeleteShader(vs));
 
  180        GLCall(glDeleteShader(ps));
 
  185    Ref<Shader> Shader::Create(
const std::string& filepathVertexShader, 
const std::string& filepathPixelShader)
 
  187        return MakeRef<Shader>(filepathVertexShader, filepathPixelShader);