80 lines
2.2 KiB
C++
80 lines
2.2 KiB
C++
#include "shader_utils.hpp"
|
|
#include <spdlog/spdlog.h>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
|
|
namespace shader {
|
|
|
|
std::string loadFile(const char* path) {
|
|
std::ifstream file(path);
|
|
if (!file.is_open()) {
|
|
spdlog::error("Failed to open shader file: {}", path);
|
|
throw std::runtime_error(std::string("Cannot open shader: ") + path);
|
|
}
|
|
|
|
std::stringstream buffer;
|
|
buffer << file.rdbuf();
|
|
return buffer.str();
|
|
}
|
|
|
|
GLuint compileShader(GLenum type, const char* source) {
|
|
GLuint shader = glCreateShader(type);
|
|
glShaderSource(shader, 1, &source, nullptr);
|
|
glCompileShader(shader);
|
|
|
|
GLint success = 0;
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
|
if (!success) {
|
|
char log[512];
|
|
glGetShaderInfoLog(shader, 512, nullptr, log);
|
|
spdlog::error("Shader compilation failed:\n{}", log);
|
|
glDeleteShader(shader);
|
|
throw std::runtime_error("Shader compilation failed");
|
|
}
|
|
|
|
return shader;
|
|
}
|
|
|
|
GLuint linkProgram(GLuint vertShader, GLuint fragShader) {
|
|
GLuint program = glCreateProgram();
|
|
glAttachShader(program, vertShader);
|
|
glAttachShader(program, fragShader);
|
|
glLinkProgram(program);
|
|
|
|
GLint success = 0;
|
|
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
|
if (!success) {
|
|
char log[512];
|
|
glGetProgramInfoLog(program, 512, nullptr, log);
|
|
spdlog::error("Program linking failed:\n{}", log);
|
|
glDeleteProgram(program);
|
|
throw std::runtime_error("Program linking failed");
|
|
}
|
|
|
|
return program;
|
|
}
|
|
|
|
GLuint createProgram(const char* vertPath, const char* fragPath) {
|
|
std::string vertSource = loadFile(vertPath);
|
|
std::string fragSource = loadFile(fragPath);
|
|
|
|
GLuint vertShader = compileShader(GL_VERTEX_SHADER, vertSource.c_str());
|
|
GLuint fragShader = compileShader(GL_FRAGMENT_SHADER, fragSource.c_str());
|
|
|
|
GLuint program = linkProgram(vertShader, fragShader);
|
|
|
|
glDeleteShader(vertShader);
|
|
glDeleteShader(fragShader);
|
|
|
|
return program;
|
|
}
|
|
|
|
void checkGLError(const char* op) {
|
|
GLenum err;
|
|
while ((err = glGetError()) != GL_NO_ERROR) {
|
|
spdlog::error("GL error after {}: 0x{:x}", op, err);
|
|
}
|
|
}
|
|
|
|
} // namespace shader
|