mirror of
https://github.com/guezoloic/LearnOpenGL.git
synced 2026-01-25 09:34:16 +00:00
feat(shader): rework files and add comments
This commit is contained in:
@@ -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
|
||||||
@@ -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
|
||||||
{
|
|
||||||
GLchar infoLog[1024];
|
|
||||||
glGetShaderInfoLog(this->vertexShaderID, 1024, nullptr, infoLog);
|
|
||||||
|
|
||||||
std::cerr << "ERROR(SHADER): VERTEX COMPILATION FAILED (ID "
|
// If compilation failed, retrieve the info log from OpenGL
|
||||||
<< this->vertexShaderID << ")\n"
|
GLchar infoLog[1024];
|
||||||
<< infoLog << std::endl;
|
glGetShaderInfoLog(shader, 1024, nullptr, infoLog);
|
||||||
}
|
|
||||||
|
// 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);
|
// 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
|
||||||
{
|
|
||||||
GLchar infoLog[1024];
|
|
||||||
glGetShaderInfoLog(this->fragmentShaderID, 1024, nullptr, infoLog);
|
|
||||||
|
|
||||||
std::cerr << "ERROR(SHADER): FRAGMENT COMPILATION FAILED (ID "
|
// If linking failed, retrieve the program info log
|
||||||
<< this->fragmentShaderID << ")\n"
|
GLchar infoLog[1024];
|
||||||
<< infoLog << std::endl;
|
glGetProgramInfoLog(id, 1024, nullptr, infoLog);
|
||||||
}
|
|
||||||
|
// 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);
|
// 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)
|
|
||||||
{
|
|
||||||
GLchar infoLog[1024];
|
|
||||||
glGetProgramInfoLog(this->shaderProgramID, 1024, nullptr, infoLog);
|
|
||||||
|
|
||||||
std::cerr << "ERROR(SHADER): LINKING FAILED (Program ID "
|
// Delete the shader objects from GPU memory
|
||||||
<< this->shaderProgramID << ")\n"
|
// After linking, shaders are no longer needed
|
||||||
<< infoLog << std::endl;
|
glDeleteShader(vert);
|
||||||
}
|
glDeleteShader(frag);
|
||||||
|
|
||||||
glDetachShader(this->shaderProgramID, this->vertexShaderID);
|
|
||||||
glDetachShader(this->shaderProgramID, this->fragmentShaderID);
|
|
||||||
|
|
||||||
glDeleteShader(this->vertexShaderID);
|
|
||||||
glDeleteShader(this->fragmentShaderID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader::~Shader() { glDeleteProgram(this->shaderProgramID); }
|
core::Shader::Shader(const char* vert, const char* frag)
|
||||||
|
{
|
||||||
|
// Create a vertex shader object on the GPU
|
||||||
|
GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
|
||||||
void Shader::use() const { glUseProgram(this->shaderProgramID); }
|
// Create a fragment shader object on the GPU
|
||||||
|
GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
GLuint Shader::getShaderProgramID() const { return this->shaderProgramID; }
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
core::Shader::~Shader() { glDeleteProgram(id); }
|
||||||
|
|
||||||
|
void core::Shader::use() const { glUseProgram(id); }
|
||||||
Reference in New Issue
Block a user