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

View File

@@ -1,86 +1,92 @@
#include "core/shader.hpp" #include "core/shader.hpp"
#include <iostream> #include "core/logger.hpp"
Shader::Shader() : shaderProgramID(0), vertexShaderID(0), fragmentShaderID(0) {} // Compile a shader from its ID and source code
static void add(GLuint shader, const char* src)
void Shader::compile(const char* vertexSource, const char* fragmentSource)
{ {
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); // Compile the shader on the GPU
this->fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); glCompileShader(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);
// Check if the compilation was successful
GLint success; GLint success;
glGetShaderiv(this->vertexShaderID, GL_COMPILE_STATUS, &success); glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) if (success) return; // Compilation succeeded, no error
{
// If compilation failed, retrieve the info log from OpenGL
GLchar infoLog[1024]; GLchar infoLog[1024];
glGetShaderInfoLog(this->vertexShaderID, 1024, nullptr, infoLog); glGetShaderInfoLog(shader, 1024, nullptr, infoLog);
std::cerr << "ERROR(SHADER): VERTEX COMPILATION FAILED (ID " // Log the compilation error with shader ID and info
<< this->vertexShaderID << ")\n" core::log::error(
<< infoLog << std::endl; 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); // Attach the vertex shader to the program
glCompileShader(this->fragmentShaderID); 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; GLint success;
glGetShaderiv(this->fragmentShaderID, GL_COMPILE_STATUS, &success); glGetProgramiv(id, GL_LINK_STATUS, &success);
if (!success) if (success) return; // Linking succeeded, no error
{
// If linking failed, retrieve the program info log
GLchar infoLog[1024]; GLchar infoLog[1024];
glGetShaderInfoLog(this->fragmentShaderID, 1024, nullptr, infoLog); glGetProgramInfoLog(id, 1024, nullptr, infoLog);
std::cerr << "ERROR(SHADER): FRAGMENT COMPILATION FAILED (ID " // Log the linking error with program ID and info
<< this->fragmentShaderID << ")\n" core::log::error(
<< infoLog << std::endl; 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); // Detach the vertex shader from the program
glAttachShader(this->shaderProgramID, this->fragmentShaderID); glDetachShader(id, vert);
glLinkProgram(this->shaderProgramID);
GLint success; // Detach the fragment shader from the program
glGetProgramiv(this->shaderProgramID, GL_LINK_STATUS, &success); glDetachShader(id, frag);
if (!success)
// 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]; // Create a vertex shader object on the GPU
glGetProgramInfoLog(this->shaderProgramID, 1024, nullptr, infoLog); GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
std::cerr << "ERROR(SHADER): LINKING FAILED (Program ID " // Create a fragment shader object on the GPU
<< this->shaderProgramID << ")\n" GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
<< infoLog << std::endl;
// 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); core::Shader::~Shader() { glDeleteProgram(id); }
glDetachShader(this->shaderProgramID, this->fragmentShaderID);
glDeleteShader(this->vertexShaderID); void core::Shader::use() const { glUseProgram(id); }
glDeleteShader(this->fragmentShaderID);
}
Shader::~Shader() { glDeleteProgram(this->shaderProgramID); }
void Shader::use() const { glUseProgram(this->shaderProgramID); }
GLuint Shader::getShaderProgramID() const { return this->shaderProgramID; }