engineer-thesis-WUT/Engine/engine/shader.cpp

111 lines
3.6 KiB
C++

#ifndef SHADER_CPP
#define SHADER_CPP
#include <glad/glad.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include "shader.hpp"
const std::string Shader::fileToShader(const std::string shaderPath)
{
// 1. retrieve the vertex/fragment source code from filePath
std::string shaderCode;
std::ifstream shaderFile;
// ensure ifstream objects can throw exceptions:
shaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
try
{
// open files
shaderFile.open(shaderPath);
std::stringstream shaderStream;
// read file's buffer contents into streams
shaderStream << shaderFile.rdbuf();
// close file handlers
shaderFile.close();
// convert stream into string
shaderCode = shaderStream.str();
}
catch (std::ifstream::failure& e)
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ: " << e.what() << std::endl;
}
return shaderCode;
}
Shader::Shader(const std::string vertexPath, const std::string fragmentPath)
{
const std::string vshaderCodeString = this -> fileToShader(vertexPath);
const std::string fShaderCodeString = this -> fileToShader(fragmentPath);
const char* vShaderCode = vshaderCodeString.c_str();
const char * fShaderCode = fShaderCodeString.c_str();
// 2. compile shaders
unsigned int vertex, fragment;
// vertex shader
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
checkCompileErrors(vertex, "VERTEX");
// fragment Shader
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
checkCompileErrors(fragment, "FRAGMENT");
// shader Program
ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
glLinkProgram(ID);
checkCompileErrors(ID, "PROGRAM");
// delete the shaders as they're linked into our program now and no longer necessary
glDeleteShader(vertex);
glDeleteShader(fragment);
}
void Shader::use()
{
glUseProgram(ID);
}
void Shader::setBool(const std::string &name, bool value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
}
void Shader::setInt(const std::string &name, int value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::setFloat(const std::string &name, float value) const
{
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}
void Shader::checkCompileErrors(unsigned int shader, std::string type)
{
int success;
char infoLog[1024];
if (type != "PROGRAM")
{
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
}
else
{
glGetProgramiv(shader, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
}
}
#endif // SHADER_CPP