101 lines
2.9 KiB
C++
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);
|
|
} |