Files
exalock/src/shader_utils.cpp

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