feat(shader): rework files and add comments

This commit is contained in:
2026-01-07 19:13:32 +01:00
parent b5c1d8ecb1
commit ed73fc5483
2 changed files with 86 additions and 80 deletions

View File

@@ -3,33 +3,33 @@
#include "glad/glad.h"
namespace core
{
class Shader
{
private:
GLuint vertexShaderID; // vertex shader id
GLuint fragmentShaderID; // fragment shader id
GLuint id; // Shader program ID
// final compiled shader program id used by the gpu
GLuint shaderProgramID;
// Attach compiled shaders (vertex & fragment) to the program and link it
// Combines the shaders into an executable GPU program
void attach(GLuint vert, GLuint frag);
// compile vertex shader source code
void addVertShader(const char* vertexSource);
// compile fragment shader source code
void addFragShader(const char* fragmentSource);
// link both compile vertex and fragment shader
void compileInProgram();
// Detach and delete compiled shaders from the program
// After linking, shaders are no longer needed on the GPU
void detach(GLuint vert, GLuint frag);
public:
// Does nothing apart initializing all IDs to 0
Shader();
// compile and link vertex and fragment into the shader struct
void compile(const char* vertexSource, const char* fragmentSource);
// free shader program
// Constructor: takes vertex & fragment shader source code
// Compiles shaders, links them into a program, and stores the program ID
Shader(const char *vert, const char *frag);
// Destructor: deletes the program from GPU memory
~Shader();
GLuint getShaderProgramID() const;
// activate shader program into gpu pipeline
// Activates the shader program for rendering
// All subsequent draw calls will use this program
void use() const;
};
} // namespace core
#endif

View File

@@ -1,86 +1,92 @@
#include "core/shader.hpp"
#include <iostream>
#include "core/logger.hpp"
Shader::Shader() : shaderProgramID(0), vertexShaderID(0), fragmentShaderID(0) {}
void Shader::compile(const char* vertexSource, const char* fragmentSource)
// Compile a shader from its ID and source code
static void add(GLuint shader, const char* src)
{
if (this->shaderProgramID != 0) glDeleteProgram(this->shaderProgramID);
// Attach the source code to the shader object
glShaderSource(shader, 1, &src, nullptr);
this->vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
this->fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
this->shaderProgramID = glCreateProgram();
this->addVertShader(vertexSource);
this->addFragShader(fragmentSource);
this->compileInProgram();
}
void Shader::addVertShader(const char* vertexSource)
{
glShaderSource(this->vertexShaderID, 1, &vertexSource, nullptr);
glCompileShader(this->vertexShaderID);
// Compile the shader on the GPU
glCompileShader(shader);
// Check if the compilation was successful
GLint success;
glGetShaderiv(this->vertexShaderID, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (success) return; // Compilation succeeded, no error
// If compilation failed, retrieve the info log from OpenGL
GLchar infoLog[1024];
glGetShaderInfoLog(this->vertexShaderID, 1024, nullptr, infoLog);
glGetShaderInfoLog(shader, 1024, nullptr, infoLog);
std::cerr << "ERROR(SHADER): VERTEX COMPILATION FAILED (ID "
<< this->vertexShaderID << ")\n"
<< infoLog << std::endl;
}
// Log the compilation error with shader ID and info
core::log::error(
std::format("SHADER (ID: {}) compilation failed: {}", shader, infoLog)
.c_str());
}
void Shader::addFragShader(const char* fragmentSource)
void core::Shader::attach(GLuint vert, GLuint frag)
{
glShaderSource(this->fragmentShaderID, 1, &fragmentSource, nullptr);
glCompileShader(this->fragmentShaderID);
// Attach the vertex shader to the program
glAttachShader(id, vert);
// Attach the fragment shader to the program
glAttachShader(id, frag);
// Link the program (combine shaders into an executable GPU program)
glLinkProgram(id);
// Check if the linking was successful
GLint success;
glGetShaderiv(this->fragmentShaderID, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetProgramiv(id, GL_LINK_STATUS, &success);
if (success) return; // Linking succeeded, no error
// If linking failed, retrieve the program info log
GLchar infoLog[1024];
glGetShaderInfoLog(this->fragmentShaderID, 1024, nullptr, infoLog);
glGetProgramInfoLog(id, 1024, nullptr, infoLog);
std::cerr << "ERROR(SHADER): FRAGMENT COMPILATION FAILED (ID "
<< this->fragmentShaderID << ")\n"
<< infoLog << std::endl;
}
// Log the linking error with program ID and info
core::log::error(
std::format("SHADER (ID: {}) linking failed: {}", id, infoLog).c_str());
}
void Shader::compileInProgram()
void core::Shader::detach(GLuint vert, GLuint frag)
{
glAttachShader(this->shaderProgramID, this->vertexShaderID);
glAttachShader(this->shaderProgramID, this->fragmentShaderID);
glLinkProgram(this->shaderProgramID);
// Detach the vertex shader from the program
glDetachShader(id, vert);
GLint success;
glGetProgramiv(this->shaderProgramID, GL_LINK_STATUS, &success);
if (!success)
// Detach the fragment shader from the program
glDetachShader(id, frag);
// Delete the shader objects from GPU memory
// After linking, shaders are no longer needed
glDeleteShader(vert);
glDeleteShader(frag);
}
core::Shader::Shader(const char* vert, const char* frag)
{
GLchar infoLog[1024];
glGetProgramInfoLog(this->shaderProgramID, 1024, nullptr, infoLog);
// Create a vertex shader object on the GPU
GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
std::cerr << "ERROR(SHADER): LINKING FAILED (Program ID "
<< this->shaderProgramID << ")\n"
<< infoLog << std::endl;
// Create a fragment shader object on the GPU
GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
// Create a program object to combine shaders
id = glCreateProgram();
// Compile each shader from source
add(vertex, vert);
add(fragment, frag);
// Attach compiled shaders and link the program
attach(vertex, fragment);
// Detach and delete shaders after linking (they are no longer needed)
detach(vertex, fragment);
}
glDetachShader(this->shaderProgramID, this->vertexShaderID);
glDetachShader(this->shaderProgramID, this->fragmentShaderID);
core::Shader::~Shader() { glDeleteProgram(id); }
glDeleteShader(this->vertexShaderID);
glDeleteShader(this->fragmentShaderID);
}
Shader::~Shader() { glDeleteProgram(this->shaderProgramID); }
void Shader::use() const { glUseProgram(this->shaderProgramID); }
GLuint Shader::getShaderProgramID() const { return this->shaderProgramID; }
void core::Shader::use() const { glUseProgram(id); }