yupplemayham/YuppleMayham/src/graphics/shader.cpp

123 lines
3.2 KiB
C++

#include "graphics/shader.h"
#include "utility/logger.h"
#include <cassert>
Shader::Shader(const char* vertexPath, const char* fragmentPath)
{
std::string vertexSource;
std::string fragmentSource;
std::ifstream vertexStream;
std::ifstream fragmentStream;
vertexStream.exceptions(std::ifstream::badbit | std::ifstream::failbit);
fragmentStream.exceptions(std::ifstream::badbit | std::ifstream::failbit);
try
{
vertexStream.open(vertexPath);
fragmentStream.open(fragmentPath);
std::stringstream vStringStream, fStringStream;
vStringStream << vertexStream.rdbuf();
fStringStream << fragmentStream.rdbuf();
vertexSource = vStringStream.str();
fragmentSource = fStringStream.str();
vertexStream.close();
fragmentStream.close();
}
catch(std::exception e)
{
LOG(ERROR, "failed to open shader files '{}', '{}' error: {}", vertexPath, fragmentPath, e.what());
assert(1 == 0); // force crash
}
const char* vSource = vertexSource.c_str();
const char* fSource = fragmentSource.c_str();
unsigned int vertexid, fragmentid;
char infoLog[512];
int success;
//compile vertex shader
vertexid = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexid, 1, &vSource, NULL);
glCompileShader(vertexid);
glGetShaderiv(vertexid, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexid, 512, NULL, infoLog);
LOG(ERROR, "VERTEX SHADER '{}' COMPILE ERROR\n{}", vertexPath, infoLog);
}
//compile fragment shader
fragmentid = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentid, 1, &fSource, NULL);
glCompileShader(fragmentid);
glGetShaderiv(fragmentid, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentid, 512, NULL, infoLog);
LOG(ERROR, "FRAGMENT SHADER '{}' COMPILE ERROR\n{}", fragmentPath, infoLog);
}
//create and link program with compiled shaders
ID = glCreateProgram();
glAttachShader(ID, vertexid);
glAttachShader(ID, fragmentid);
glLinkProgram(ID);
glGetProgramiv(ID, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(ID, 512, NULL, infoLog);
LOG(ERROR, "PROGRAM LINKER ERROR\n{}", infoLog);
}
glDeleteShader(vertexid);
glDeleteShader(fragmentid);
}
void Shader::setFloat(const std::string& name, float value)
{
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setFloatArray(const std::string& name, size_t count, const float* value)
{
glUniform1fv(glGetUniformLocation(ID, name.c_str()), count, value);
}
void Shader::setIntArray(const std::string& name, size_t count, const int* value)
{
glUniform1iv(glGetUniformLocation(ID, name.c_str()), count, value);
}
void Shader::setInt(const std::string& name, int value)
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setBool(const std::string& name, bool value)
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setVec2(const std::string& name, const float* value)
{
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, value);
}
void Shader::setMatrix4f(const std::string& name, const float* value)
{
GLuint loc = glGetUniformLocation(ID, name.c_str());
glUniformMatrix4fv(loc, 1, GL_FALSE, value);
}
Shader::~Shader()
{
glDeleteProgram(ID);
}