diff --git a/includes/RT.hpp b/includes/RT.hpp index c4d695f..2ae3c2a 100644 --- a/includes/RT.hpp +++ b/includes/RT.hpp @@ -58,10 +58,12 @@ struct Vertex { # include "objects/Portal.hpp" # include "objects/Cylinder.hpp" +# include "Buffer.hpp" # include "Arguments.hpp" # include "Camera.hpp" # include "Renderer.hpp" # include "Window.hpp" +# include "ShaderProgram.hpp" # include "Shader.hpp" # include "Scene.hpp" # include "SceneParser.hpp" diff --git a/includes/RT/Buffer.hpp b/includes/RT/Buffer.hpp new file mode 100644 index 0000000..1cbcadc --- /dev/null +++ b/includes/RT/Buffer.hpp @@ -0,0 +1,54 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* Buffer.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: TheRed +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/12 23:45:57 by TheRed #+# #+# */ +/* Updated: 2025/02/12 23:45:57 by TheRed ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BUFFER_HPP +# define BUFFER_HPP + +# include "RT.hpp" + +class Buffer +{ + public: + enum Type + { + SSBO, + UBO + }; + + Buffer(Type type, GLuint binding_point, GLuint size, const void *data) + : _type(type), _binding_point(binding_point) + { + glGenBuffers(1, &_buffer_id); + glBindBuffer(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, _buffer_id); + glBufferData(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, size, data, GL_DYNAMIC_DRAW); + glBindBufferBase(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, _binding_point, _buffer_id); + glBindBuffer(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, 0); + } + + ~Buffer() { glDeleteBuffers(1, &_buffer_id); } + + void update(const void *data, GLuint size) + { + glBindBuffer(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, _buffer_id); + glBufferSubData(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, 0, size, data); + glBindBuffer(_type == SSBO ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER, 0); + } + + GLuint getID() const { return _buffer_id; } + + private: + Type _type; + GLuint _buffer_id; + GLuint _binding_point; +}; + +#endif \ No newline at end of file diff --git a/includes/RT/Shader.hpp b/includes/RT/Shader.hpp index a76edec..b19b360 100644 --- a/includes/RT/Shader.hpp +++ b/includes/RT/Shader.hpp @@ -18,9 +18,14 @@ class Shader { public: - Shader(std::string vertexPath, std::string fragmentPath, std::string computePath, std::string denoisingPath); + Shader(GLenum type, const std::string &file_path); ~Shader(void); + void compile(void); + void reload(); + + GLuint getShader(void) const; + void attach(void); void setupVertexBuffer(); void drawTriangles(); @@ -37,7 +42,6 @@ class Shader void set_textures(std::vector texture_ids, std::vector emissive_texture_ids); - GLuint getProgram(void) const; GLuint getProgramCompute(void) const; GLuint getProgramComputeDenoising(void) const; @@ -67,7 +71,12 @@ class Shader size_t _size; - void checkCompileErrors(unsigned int shader); + void checkCompileErrors(); + + // + GLenum _type; + GLuint _shader_id; + std::string _file_path; }; #endif diff --git a/includes/RT/ShaderProgram.hpp b/includes/RT/ShaderProgram.hpp new file mode 100644 index 0000000..23c6a34 --- /dev/null +++ b/includes/RT/ShaderProgram.hpp @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ShaderProgram.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: TheRed +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/12 22:22:17 by TheRed #+# #+# */ +/* Updated: 2025/02/12 22:22:17 by TheRed ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef SHADERPROGRAM_HPP +# define SHADERPROGRAM_HPP + +# include "RT.hpp" + +class ShaderProgram +{ + public: + ShaderProgram(); + ~ShaderProgram(void); + + void attachShader(Shader *shader); + void link(void); + + void use(void) const; + void dispathCompute(GLuint x, GLuint y, GLuint z) const; + + void bindImageTexture(GLuint texture_id, GLuint unit, GLenum access, GLenum format) const; + + void reloadShaders(void); + + void set_int(const std::string &name, int value) const; + void set_float(const std::string &name, float value) const; + void set_vec2(const std::string &name, const glm::vec2 &value) const; + + + GLuint getProgram(void) const; + + private: + std::vector _shaders; + GLuint _program; +}; + +#endif diff --git a/includes/RT/objects/Portal.hpp b/includes/RT/objects/Portal.hpp index 3d438cc..ebc6464 100644 --- a/includes/RT/objects/Portal.hpp +++ b/includes/RT/objects/Portal.hpp @@ -52,7 +52,6 @@ class Portal : public Object _rotation = glm::mat3(right, up, forward); _normal = forward * (_invert_normal ? -1.0f : 1.0f); - std::cout << glm::to_string(_normal) << std::endl; _linked_portal = -1; _mat_index = mat_index; diff --git a/shaders/frag.frag b/shaders/frag.frag index 017073a..b89b6c6 100644 --- a/shaders/frag.frag +++ b/shaders/frag.frag @@ -2,8 +2,9 @@ in vec2 TexCoords; out vec4 FragColor; -uniform sampler2D screenTexture; +layout (binding = 0, rgba32f) uniform image2D screenTexture; void main() { - FragColor = texture(screenTexture, TexCoords); + FragColor = imageLoad(screenTexture, ivec2(gl_FragCoord.xy)); + // FragColor = vec4(1.0, 0.0, 0.0, 1.0); } \ No newline at end of file diff --git a/shaders/light.glsl b/shaders/light.glsl index 6c0852b..4a3f1b8 100644 --- a/shaders/light.glsl +++ b/shaders/light.glsl @@ -2,7 +2,7 @@ hitInfo traceRay(inout Ray ray); vec3 GetEnvironmentLight(Ray ray) { - return vec3(0.); + // return vec3(0.); vec3 sun_pos = vec3(-0.5, 0.5, 0.5); float SunFocus = 1.5; float SunIntensity = 1.; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 2885aef..a1cec81 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -12,172 +12,77 @@ #include "RT.hpp" +void setupScreenTriangle(GLuint *VAO); +void drawScreenTriangle(GLuint VAO, GLuint output_texture, GLuint program); +std::vector generateTextures(unsigned int textures_count); +std::vector createDataOnGPU(Scene &scene); +void updateDataOnGPU(Scene &scene, std::vector buffers); + int main(int argc, char **argv) { Arguments args(argc, argv); if (args.error()) return (1); + Scene scene(args.getSceneName()); if (scene.fail()) return (1); + Window window(&scene, WIDTH, HEIGHT, "RT_GPU", 0, args); - Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/compute.glsl", "shaders/denoising.glsl"); - // Shader shader("shaders/vertex.vert", "shaders/frag.frag", "shaders/debug.glsl"); + + GLuint VAO; + setupScreenTriangle(&VAO); + + std::vector textures = generateTextures(2); + GLuint output_texture = textures[0]; + + ShaderProgram raytracing_program; + Shader compute = Shader(GL_COMPUTE_SHADER, "shaders/compute.glsl"); + + raytracing_program.attachShader(&compute); + raytracing_program.link(); + + raytracing_program.use(); + // raytracing_program.bindImageTexture(output_texture, 0, GL_READ_WRITE, GL_RGBA32F); + // raytracing_program.bindImageTexture(textures[1], 1, GL_READ_WRITE, GL_RGBA32F); - GLint max_gpu_size; - glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_gpu_size); + ShaderProgram render_program; + Shader vertex = Shader(GL_VERTEX_SHADER, "shaders/vertex.vert"); + Shader frag = Shader(GL_FRAGMENT_SHADER, "shaders/frag.frag"); - const std::vector &object_data = scene.getObjectData(); - const std::vector &triangle_data = scene.getTriangleData(); - const std::vector &bvh_nodes = scene.getBvh(); - const std::vector &bvh_data = scene.getBvhData(); - const std::vector &material_data = scene.getMaterialData(); + render_program.attachShader(&vertex); + render_program.attachShader(&frag); + render_program.link(); - std::cout << "Sending " << object_data.size() << " objects for " << \ - object_data.size() * sizeof(GPUObject) + \ - triangle_data.size() * sizeof(GPUTriangle) + \ - bvh_nodes.size() * sizeof(GPUBvh) + \ - material_data.size() * sizeof(GPUMaterial) \ - << " / " << max_gpu_size << " bytes" << std::endl; - - GLuint objectSSBO; - glGenBuffers(1, &objectSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, objectSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUObject) * object_data.size(), object_data.data(), GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, objectSSBO); - - GLuint trianglesSSBO; - glGenBuffers(1, &trianglesSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, trianglesSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUTriangle) * triangle_data.size(), triangle_data.data(), GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, trianglesSSBO); - - GLuint bvh_nodesSSBO; - glGenBuffers(1, &bvh_nodesSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, bvh_nodesSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUBvhData) * bvh_data.size(), bvh_data.data(), GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, bvh_nodesSSBO); - - GLuint bvhSSBO; - glGenBuffers(1, &bvhSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, bvhSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUBvh) * bvh_nodes.size(), bvh_nodes.data(), GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, bvhSSBO); - - GLuint materialSSBO; - glGenBuffers(1, &materialSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GPUMaterial) * material_data.size(), nullptr, GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, materialSSBO); - - GLuint lightSSBO; - glGenBuffers(1, &lightSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, scene.getGPULights().size() * sizeof(int), nullptr, GL_STATIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, lightSSBO); - - GLuint cameraUBO; - glGenBuffers(1, &cameraUBO); - glBindBuffer(GL_UNIFORM_BUFFER, cameraUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(GPUCamera), nullptr, GL_DYNAMIC_DRAW); - glBindBufferBase(GL_UNIFORM_BUFFER, 0, cameraUBO); - - GLuint volumeUBO; - glGenBuffers(1, &volumeUBO); - glBindBuffer(GL_UNIFORM_BUFFER, volumeUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(GPUVolume), nullptr, GL_STATIC_DRAW); - glBindBufferBase(GL_UNIFORM_BUFFER, 1, volumeUBO); - - GLuint debugUBO; - glGenBuffers(1, &debugUBO); - glBindBuffer(GL_UNIFORM_BUFFER, debugUBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(GPUDebug), nullptr, GL_STATIC_DRAW); - glBindBufferBase(GL_UNIFORM_BUFFER, 2, debugUBO); - - if (!scene.loadTextures()) - return (1); - - shader.attach(); - - shader.setupVertexBuffer(); + std::vector buffers = createDataOnGPU(scene); while (!window.shouldClose()) { window.updateDeltaTime(); - - glUseProgram(shader.getProgramCompute()); - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialSSBO); - glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, material_data.size() * sizeof(GPUMaterial), material_data.data()); - - std::set gpu_lights = scene.getGPULights(); - std::vector gpu_lights_array(gpu_lights.begin(), gpu_lights.end()); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightSSBO); - glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, gpu_lights_array.size() * sizeof(int), gpu_lights_array.data()); - window.rendererUpdate(shader); - - GPUCamera camera_data = scene.getCamera()->getGPUData(); - - glBindBuffer(GL_UNIFORM_BUFFER, cameraUBO); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GPUCamera), &camera_data); - - glBindBuffer(GL_UNIFORM_BUFFER, volumeUBO); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GPUVolume), &scene.getVolume()); - - glBindBuffer(GL_UNIFORM_BUFFER, debugUBO); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GPUDebug), &scene.getDebug()); - - shader.set_int("u_frameCount", window.getFrameCount()); - shader.set_int("u_objectsNum", object_data.size()); - shader.set_int("u_bvhNum", bvh_data.size()); - shader.set_int("u_lightsNum", gpu_lights.size()); - shader.set_int("u_pixelisation", window.getPixelisation()); - shader.set_float("u_time", (float)(glfwGetTime())); - shader.set_vec2("u_resolution", glm::vec2(WIDTH, HEIGHT)); - - shader.set_textures(scene.getTextureIDs(), scene.getEmissionTextureIDs()); - - glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - - GPUDenoise denoise = scene.getDenoise(); - if (denoise.enabled) - { - glUseProgram(shader.getProgramComputeDenoising()); - - glUniform2fv(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_resolution"), 1, glm::value_ptr(glm::vec2(WIDTH, HEIGHT))); - glUniform1f(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_c_phi"), denoise.c_phi); - glUniform1f(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_p_phi"), denoise.p_phi); - glUniform1f(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_n_phi"), denoise.n_phi); - - for (int pass = 0; pass < denoise.pass ; ++pass) - { - shader.flipOutputDenoising(pass % 2 == 0); - - glUniform1i(glGetUniformLocation(shader.getProgramComputeDenoising(), "u_pass"), pass); - - glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - } - shader.flipOutputDenoising(true); - } - - glClear(GL_COLOR_BUFFER_BIT); - + + updateDataOnGPU(scene, buffers); + + raytracing_program.use(); + raytracing_program.set_int("u_frameCount", window.getFrameCount()); + raytracing_program.set_int("u_objectsNum", scene.getObjectData().size()); + raytracing_program.set_int("u_bvhNum", scene.getBvhData().size()); + raytracing_program.set_int("u_lightsNum", scene.getGPULights().size()); + raytracing_program.set_int("u_pixelisation", window.getPixelisation()); + raytracing_program.set_float("u_time", (float)(glfwGetTime())); + raytracing_program.set_vec2("u_resolution", glm::vec2(WIDTH, HEIGHT)); + raytracing_program.dispathCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); + window.imGuiNewFrame(); - glUseProgram(shader.getProgram()); - shader.drawTriangles(); + render_program.use(); + drawScreenTriangle(VAO, output_texture, render_program.getProgram()); window.imGuiRender(); window.display(); window.pollEvents(); - - glClearTexImage(shader.getNormalTexture(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glClearTexImage(shader.getPositionTexture(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } ImGui_ImplOpenGL3_Shutdown(); diff --git a/srcs/RT_utils.cpp b/srcs/RT_utils.cpp new file mode 100644 index 0000000..06c585a --- /dev/null +++ b/srcs/RT_utils.cpp @@ -0,0 +1,117 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* RT_utils.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: TheRed +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/12 23:21:09 by TheRed #+# #+# */ +/* Updated: 2025/02/12 23:21:09 by TheRed ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "RT.hpp" + +void setupScreenTriangle(GLuint *VAO) +{ + GLuint VBO; + + Vertex vertices[3] = {{{-1.0f, -1.0f}, {0.0f, 0.0f}},{{3.0f, -1.0f}, {2.0f, 0.0f}},{{-1.0f, 3.0f}, {0.0f, 2.0f}}}; + size_t size = sizeof(vertices) / sizeof(Vertex) / 3; // size 1 + + glGenVertexArrays(1, VAO); + glBindVertexArray(*VAO); + + glGenBuffers(1, &VBO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, size * 3 * sizeof(Vertex), vertices, GL_STATIC_DRAW); + + // Position attribute + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); + glEnableVertexAttribArray(0); + + // Texture coordinate attribute + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texCoord)); + glEnableVertexAttribArray(1); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +void drawScreenTriangle(GLuint VAO, GLuint output_texture, GLuint program) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, output_texture); + glUniform1i(glGetUniformLocation(program, "screenTexture"), 0); + + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 1 * 3); // size 1 +} + +std::vector generateTextures(unsigned int textures_count) +{ + std::vector textures(textures_count); + + glGenTextures(textures_count, textures.data()); + for (unsigned int i = 0; i < textures_count; ++i) + { + glBindTexture(GL_TEXTURE_2D, textures[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); + glBindImageTexture(i, textures[i], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + } + return (textures); +} + +std::vector createDataOnGPU(Scene &scene) +{ + GLint max_gpu_size; + glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_gpu_size); + + const std::vector &object_data = scene.getObjectData(); + const std::vector &triangle_data = scene.getTriangleData(); + const std::vector &bvh_nodes = scene.getBvh(); + const std::vector &bvh_data = scene.getBvhData(); + const std::vector &material_data = scene.getMaterialData(); + + std::cout << "Sending " << object_data.size() << " objects for " << \ + object_data.size() * sizeof(GPUObject) + \ + triangle_data.size() * sizeof(GPUTriangle) + \ + bvh_nodes.size() * sizeof(GPUBvh) + \ + material_data.size() * sizeof(GPUMaterial) \ + << " / " << max_gpu_size << " bytes" << std::endl; + + std::vector buffers; + + buffers.push_back(new Buffer(Buffer::Type::SSBO, 1, sizeof(GPUObject) * object_data.size(), object_data.data())); + buffers.push_back(new Buffer(Buffer::Type::SSBO, 2, sizeof(GPUTriangle) * triangle_data.size(), triangle_data.data())); + buffers.push_back(new Buffer(Buffer::Type::SSBO, 3, sizeof(GPUBvhData) * bvh_data.size(), bvh_data.data())); + buffers.push_back(new Buffer(Buffer::Type::SSBO, 4, sizeof(GPUBvh) * bvh_nodes.size(), bvh_nodes.data())); + buffers.push_back(new Buffer(Buffer::Type::SSBO, 5, sizeof(GPUMaterial) * material_data.size(), nullptr)); + buffers.push_back(new Buffer(Buffer::Type::SSBO, 6, scene.getGPULights().size() * sizeof(int), nullptr)); + + buffers.push_back(new Buffer(Buffer::Type::UBO, 0, sizeof(GPUCamera), nullptr)); + buffers.push_back(new Buffer(Buffer::Type::UBO, 1, sizeof(GPUVolume), nullptr)); + buffers.push_back(new Buffer(Buffer::Type::UBO, 2, sizeof(GPUDebug), nullptr)); + + return (buffers); +} + +void updateDataOnGPU(Scene &scene, std::vector buffers) +{ + const std::vector &material_data = scene.getMaterialData(); + const std::set &gpu_lights = scene.getGPULights(); + std::vector gpu_lights_array(gpu_lights.begin(), gpu_lights.end()); + + buffers[4]->update(material_data.data(), sizeof(GPUMaterial) * material_data.size()); + buffers[5]->update(gpu_lights_array.data(), gpu_lights.size() * sizeof(int)); + + GPUCamera camera_data = scene.getCamera()->getGPUData(); + buffers[6]->update(&camera_data, sizeof(GPUCamera)); + + buffers[7]->update(&scene.getVolume(), sizeof(GPUVolume)); + buffers[8]->update(&scene.getDebug(), sizeof(GPUDebug)); +} diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index c8ceb8a..9b29006 100644 --- a/srcs/class/Shader.cpp +++ b/srcs/class/Shader.cpp @@ -61,52 +61,36 @@ void printWithLineNumbers(const char *str) std::cout << lineNumber++ << ": " << line << std::endl; } -Shader::Shader(std::string vertexPath, std::string fragmentPath, std::string computePath, std::string denoisingPath) +Shader::Shader(GLenum type, const std::string &file_path) { - const char *vertexCode = loadFileWithIncludes(vertexPath); - const char *fragmentCode = loadFileWithIncludes(fragmentPath); - const char *computeCode = loadFileWithIncludes(computePath); - const char *denoisingCode = loadFileWithIncludes(denoisingPath); + _type = type; + _file_path = file_path; + _shader_id = 0; - // printWithLineNumbers(computeCode); - - _vertex = glCreateShader(GL_VERTEX_SHADER); - - glShaderSource(_vertex, 1, &vertexCode, NULL); - glCompileShader(_vertex); - - checkCompileErrors(_vertex); - - _fragment = glCreateShader(GL_FRAGMENT_SHADER); - - glShaderSource(_fragment, 1, &fragmentCode, NULL); - glCompileShader(_fragment); - - checkCompileErrors(_fragment); - - _compute = glCreateShader(GL_COMPUTE_SHADER); - - glShaderSource(_compute, 1, &computeCode, NULL); - glCompileShader(_compute); - - checkCompileErrors(_compute); - - _denoising = glCreateShader(GL_COMPUTE_SHADER); - - glShaderSource(_denoising, 1, &denoisingCode, NULL); - glCompileShader(_denoising); - - checkCompileErrors(_denoising); + this->compile(); } Shader::~Shader(void) { - glDeleteShader(_vertex); - glDeleteShader(_fragment); - glDeleteShader(_compute); - glDeleteProgram(_program); - glDeleteProgram(_program_compute); - glDeleteProgram(_denoising); +} + +void Shader::compile() +{ + _shader_id = glCreateShader(_type); + + const char *shader_code = loadFileWithIncludes(_file_path); + // printWithLineNumbers(shader_code); + + glShaderSource(_shader_id, 1, &shader_code, NULL); + glCompileShader(_shader_id); + + this->checkCompileErrors(); +} + +void Shader::reload() +{ + glDeleteShader(_shader_id); + this->compile(); } void Shader::attach(void) @@ -176,15 +160,15 @@ void Shader::attach(void) glBindImageTexture(4, _position_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); } -void Shader::checkCompileErrors(GLuint shader) +void Shader::checkCompileErrors() { GLint success; GLchar infoLog[512]; - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + glGetShaderiv(_shader_id, GL_COMPILE_STATUS, &success); if (!success) { - glGetShaderInfoLog(shader, 512, NULL, infoLog); + glGetShaderInfoLog(_shader_id, 512, NULL, infoLog); std::cout << "ERROR::SHADER::COMPILATION_FAILED\n" << infoLog << std::endl; } } @@ -287,29 +271,9 @@ void Shader::set_textures(std::vector texture_ids, std::vector e } -GLuint Shader::getProgram(void) const +GLuint Shader::getShader(void) const { - return (_program); -} - -GLuint Shader::getProgramCompute(void) const -{ - return (_program_compute); -} - -GLuint Shader::getProgramComputeDenoising(void) const -{ - return (_program_denoising); -} - -GLuint Shader::getNormalTexture(void) const -{ - return (_normal_texture); -} - -GLuint Shader::getPositionTexture(void) const -{ - return (_position_texture); + return (_shader_id); } std::vector Shader::getOutputImage(void) diff --git a/srcs/class/ShaderProgram.cpp b/srcs/class/ShaderProgram.cpp new file mode 100644 index 0000000..2d8df5c --- /dev/null +++ b/srcs/class/ShaderProgram.cpp @@ -0,0 +1,92 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ShaderProgram.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: TheRed +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/12 22:21:46 by TheRed #+# #+# */ +/* Updated: 2025/02/12 22:21:46 by TheRed ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ShaderProgram.hpp" + +ShaderProgram::ShaderProgram() +{ + _program = glCreateProgram(); +} + +ShaderProgram::~ShaderProgram(void) +{ + glDeleteProgram(_program); +} + +void ShaderProgram::attachShader(Shader *shader) +{ + _shaders.push_back(shader); + glAttachShader(_program, shader->getShader()); +} + +void ShaderProgram::link() +{ + glLinkProgram(_program); + + GLint success; + glGetProgramiv(_program, GL_LINK_STATUS, &success); + if (!success) + { + GLchar infoLog[512]; + glGetProgramInfoLog(_program, 512, NULL, infoLog); + std::cerr << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; + } +} + +void ShaderProgram::use() const +{ + glUseProgram(_program); +} + +void ShaderProgram::dispathCompute(GLuint x, GLuint y, GLuint z) const +{ + this->use(); + glDispatchCompute(x, y, z); + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); +} + +void ShaderProgram::bindImageTexture(GLuint texture_id, GLuint unit, GLenum access, GLenum format) const +{ + glBindImageTexture(unit, texture_id, 0, GL_FALSE, 0, access, format); +} + +void ShaderProgram::reloadShaders(void) +{ + std::cout << "Reloading shaders" << std::endl; + + for (Shader *shader : _shaders) + { + glDetachShader(_program, shader->getShader()); + shader->reload(); + glAttachShader(_program, shader->getShader()); + } + + this->link(); +} + +void ShaderProgram::set_int(const std::string &name, int value) const +{ + glUniform1i(glGetUniformLocation(_program, name.c_str()), value); +} +void ShaderProgram::set_float(const std::string &name, float value) const +{ + glUniform1f(glGetUniformLocation(_program, name.c_str()), value); +} +void ShaderProgram::set_vec2(const std::string &name, const glm::vec2 &value) const +{ + glUniform2fv(glGetUniformLocation(_program, name.c_str()), 1, glm::value_ptr(value)); +} + +GLuint ShaderProgram::getProgram(void) const +{ + return (_program); +} \ No newline at end of file