#include "shader_utils.hpp" #include #include #include 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