128 lines
3.1 KiB
C++
128 lines
3.1 KiB
C++
|
|
//
|
||
|
|
// Created by lbmas on 4/29/2026.
|
||
|
|
//
|
||
|
|
|
||
|
|
#include "ShaderProgram.h"
|
||
|
|
|
||
|
|
#include <fstream>
|
||
|
|
#include <string>
|
||
|
|
#include <sstream>
|
||
|
|
|
||
|
|
#include "glad/gl.h"
|
||
|
|
#include "spdlog/spdlog.h"
|
||
|
|
|
||
|
|
void log_shader_compile_errors(GLuint shader, std::string_view shaderType);
|
||
|
|
void log_program_compile_errors(GLuint program);
|
||
|
|
|
||
|
|
std::shared_ptr<ShaderProgram> ShaderProgram::load(std::string_view vertexPath, std::string_view fragmentPath)
|
||
|
|
{
|
||
|
|
std::string vertexSource;
|
||
|
|
std::string fragmentSource;
|
||
|
|
|
||
|
|
std::ifstream vertexFile {};
|
||
|
|
std::ifstream fragmentFile {};
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
std::stringstream ss;
|
||
|
|
vertexFile.open(vertexPath.data());
|
||
|
|
fragmentFile.open(fragmentPath.data());
|
||
|
|
|
||
|
|
ss << vertexFile.rdbuf();
|
||
|
|
vertexSource = ss.str();
|
||
|
|
ss.clear();
|
||
|
|
ss << fragmentFile.rdbuf();
|
||
|
|
fragmentSource = ss.str();
|
||
|
|
|
||
|
|
vertexFile.close();
|
||
|
|
fragmentFile.close();
|
||
|
|
} catch (std::ifstream::failure& e) {
|
||
|
|
spdlog::error("Failed to load shader program {}, {}: {}", vertexPath, fragmentPath, std::string(e.what()).c_str());
|
||
|
|
return nullptr;
|
||
|
|
}
|
||
|
|
|
||
|
|
unsigned int vertex;
|
||
|
|
unsigned int fragment;
|
||
|
|
|
||
|
|
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||
|
|
glShaderSource(vertex, 1, reinterpret_cast<const GLchar* const*>(vertexSource.data()), NULL);
|
||
|
|
glCompileShader(vertex);
|
||
|
|
log_shader_compile_errors(vertex, "vertex");
|
||
|
|
|
||
|
|
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||
|
|
glShaderSource(fragment, 1, reinterpret_cast<const GLchar* const*>(fragmentSource.data()), NULL);
|
||
|
|
glCompileShader(fragment);
|
||
|
|
log_shader_compile_errors(fragment, "fragment");
|
||
|
|
|
||
|
|
ShaderProgram program;
|
||
|
|
program.id = glCreateProgram();
|
||
|
|
|
||
|
|
glAttachShader(program.id, vertex);
|
||
|
|
glAttachShader(program.id, fragment);
|
||
|
|
glLinkProgram(program.id);
|
||
|
|
log_program_compile_errors(program.id);
|
||
|
|
|
||
|
|
glDeleteShader(vertex);
|
||
|
|
glDeleteShader(fragment);
|
||
|
|
|
||
|
|
return std::make_shared<ShaderProgram>(program);
|
||
|
|
}
|
||
|
|
|
||
|
|
void ShaderProgram::bind()
|
||
|
|
{
|
||
|
|
glUseProgram(id);
|
||
|
|
}
|
||
|
|
|
||
|
|
void ShaderProgram::unbind()
|
||
|
|
{
|
||
|
|
glUseProgram(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
void ShaderProgram::setFloat(std::string_view name, float value) const
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void ShaderProgram::setVec2(std::string_view name, const glm::vec2& value) const
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void ShaderProgram::setVec3(std::string_view name, const glm::vec3& value) const
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void ShaderProgram::setVec4(std::string_view name, const glm::vec4& value) const
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void ShaderProgram::setMat4(std::string_view name, const glm::mat4& value) const
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void log_shader_compile_errors(GLuint shader, std::string_view shaderType)
|
||
|
|
{
|
||
|
|
GLint success;
|
||
|
|
GLchar infoLog[1024];
|
||
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||
|
|
if (!success)
|
||
|
|
{
|
||
|
|
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
||
|
|
spdlog::error("Failed to compile {} shader: {}", shaderType, infoLog);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void log_program_compile_errors(GLuint program)
|
||
|
|
{
|
||
|
|
GLint success;
|
||
|
|
GLchar infoLog[1024];
|
||
|
|
glGetProgramiv(program, GL_COMPILE_STATUS, &success);
|
||
|
|
if (!success)
|
||
|
|
{
|
||
|
|
glGetShaderInfoLog(program, 1024, NULL, infoLog);
|
||
|
|
spdlog::error("Failed to compile program: {}", infoLog);
|
||
|
|
}
|
||
|
|
}
|