tedit/shaderutils.h
2025-04-07 20:08:16 -04:00

101 lines
2.9 KiB
C++

// shader_utils.h
#ifndef SHADER_UTILS_H
#define SHADER_UTILS_H
#include <string>
#if defined(IMGUI_IMPL_OPENGL_ES2)
#include <SDL_opengles2.h>
#else
#include <GL/glew.h>
#include <SDL_opengl.h>
#endif
GLuint LoadShaderProgram(const std::string& vsSource, const std::string& fsSource);
GLuint LoadShaderProgramFromFiles(const std::string& vsPath, const std::string& fsPath);
#endif // SHADER_UTILS_H
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
// Function to compile a shader
GLuint CompileShader(GLenum type, const std::string& source) {
GLuint shader = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(shader, 1, &src, nullptr);
glCompileShader(shader);
GLint success;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
GLint logLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
std::vector<char> log(logLength);
glGetShaderInfoLog(shader, logLength, nullptr, log.data());
std::cerr << "ERROR::SHADER::COMPILATION_FAILED\n" << (type == GL_VERTEX_SHADER ? "Vertex" : "Fragment") << "\n" << log.data() << std::endl;
glDeleteShader(shader);
return 0;
}
return shader;
}
// Function to link shaders into a program
GLuint LinkProgram(GLuint vertexShader, GLuint fragmentShader) {
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
GLint success;
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success) {
GLint logLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
std::vector<char> log(logLength);
glGetProgramInfoLog(program, logLength, nullptr, log.data());
std::cerr << "ERROR::PROGRAM::LINKING_FAILED\n" << log.data() << std::endl;
glDeleteProgram(program);
return 0;
}
return program;
}
GLuint LoadShaderProgram(const std::string& vsSource, const std::string& fsSource) {
GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
if (!vs) return 0;
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
if (!fs) { glDeleteShader(vs); return 0; }
GLuint program = LinkProgram(vs, fs);
// Shaders can be deleted after linking
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
std::string ReadFile(const std::string& path) {
std::ifstream file(path);
if (!file) {
std::cerr << "Error opening file: " << path << std::endl;
return "";
}
std::stringstream buffer;
buffer << file.rdbuf();
return buffer.str();
}
GLuint LoadShaderProgramFromFiles(const std::string& vsPath, const std::string& fsPath) {
std::string vsSource = ReadFile(vsPath);
std::string fsSource = ReadFile(fsPath);
if (vsSource.empty() || fsSource.empty()) {
return 0;
}
return LoadShaderProgram(vsSource, fsSource);
}