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

107 lines
3.4 KiB
C++
Raw Normal View History

2022-09-18 18:10:03 +02:00
#ifndef SHADER_CPP
#define SHADER_CPP
#include <glad/glad.h>
#include <fstream>
#include "shader.hpp"
#include "misc.hpp"
unsigned int Shader::linkShaderObjectsShaderProgram(const unsigned int vertexShaders, const unsigned int fragmentShader) const
{
// link shader objects into shader program
// will store shader program id
// creates program
const unsigned int shaderProgram = glCreateProgram();
// attachShaders
glAttachShader(shaderProgram, vertexShaders);
glAttachShader(shaderProgram, fragmentShader);
// link shaders
glLinkProgram(shaderProgram);
if (!shaderSuccessful(shaderProgram, false))
return 0;
// delete shaders (they are linked into shaderProgram and we do not need them anymore)
glDeleteShader(vertexShaders);
glDeleteShader(fragmentShader);
if (shaderProgram == 0)
print("Shader Program Linking Failed");
return shaderProgram;
}
unsigned int Shader::compileShader(const GLenum shaderType, const char *shaderSource) const
{
// we create vertex shader and assign its id to shader variable
const unsigned int shaderID = glCreateShader(shaderType);
// attach shader source code to shader object
// from left: shader object to compile, how many strings as source code, actual source code (we leave the 4th as NULL)
glShaderSource(shaderID, 1, &shaderSource, NULL);
// compile shader
glCompileShader(shaderID);
if (!shaderSuccessful(shaderID, true))
return 0;
return shaderID;
}
const char* Shader::getSourceCode(const std::string_view sourcePath) const
{
// 1. retrieve the vertex/fragment source code from filePath
std::string sourceCode;
std::ifstream sourceFile;
// ensure ifstream objects can throw exceptions:
sourceFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
try
{
sourceCode = fileBufferToString(sourcePath, sourceFile);
}
// https://stackoverflow.com/a/62030396
catch(std::ifstream::failure const& e)
{
std::cerr << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ for sourcePath: " << sourcePath << std::endl;
}
const char* cSourceCode = sourceCode.c_str();
return cSourceCode;
}
void Shader::use()
{
glUseProgram(ID);
}
void Shader::setBool(const std::string_view &name, const bool value) const
{
const int vertexColorLocation = glGetUniformLocation(ID, name.c_str());
if(vertexColorLocation != -1) {
glUniform1i(vertexColorLocation, (int)value);
}
}
void Shader::setInt(const std::string_view &name, const int value) const
{
const int vertexColorLocation = glGetUniformLocation(ID, name.c_str());
if(vertexColorLocation != -1) {
glUniform1i(vertexColorLocation, value);
}
}
void Shader::setFloat(const std::string_view &name, const float value) const
{
const int vertexColorLocation = glGetUniformLocation(ID, name.c_str());
if(vertexColorLocation != -1) {
glUniform1f(vertexColorLocation, value);
}
}
Shader::Shader(const std::string_view vertexPath, const std::string_view fragmentPath)
{
const char* vShaderCode = getSourceCode(vertexPath);
const char* fShaderCode = getSourceCode(fragmentPath);
const int vectorShaderID = compileShader(GL_VERTEX_SHADER, vShaderCode);
const int fragmentShaderID = compileShader(GL_FRAGMENT_SHADER, fShaderCode);
ID = linkShaderObjectsShaderProgram(vectorShaderID, fragmentShaderID);
}
#endif // SHADER_CPP