From 85fd31025287301b984168f648cac00f40c0f7d1 Mon Sep 17 00:00:00 2001 From: "Duong (Zach) Nguyen" Date: Sun, 15 Jan 2023 18:00:44 -0500 Subject: [PATCH] Delete submodule output/: use a frame buffer --- CMakeLists.txt | 1 - include/3d/Renderer.hpp | 15 +++++++++---- include/output/ImageOutput.hpp | 11 ---------- include/output/PPMOutput.hpp | 37 ------------------------------- src/3d/Renderer.cpp | 40 +++++++++++++++++++++++----------- src/main.cpp | 36 ++++++++++++++++++++---------- 6 files changed, 63 insertions(+), 77 deletions(-) delete mode 100644 include/output/ImageOutput.hpp delete mode 100644 include/output/PPMOutput.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d138a9..15feea6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,6 @@ target_include_directories( ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include/math ${CMAKE_SOURCE_DIR}/include/3d - ${CMAKE_SOURCE_DIR}/include/output ) install( diff --git a/include/3d/Renderer.hpp b/include/3d/Renderer.hpp index aec834d..1d753c0 100644 --- a/include/3d/Renderer.hpp +++ b/include/3d/Renderer.hpp @@ -2,19 +2,26 @@ #define RENDERER_H #include "Camera.hpp" -#include "ImageOutput.hpp" #include "Ray.hpp" #include "Scene.hpp" #include "Vec3.hpp" class Renderer { private: - ImageOutput &output; + int output_width; + int output_height; + int num_pixels; + size_t frame_buffer_size; + float *frame_buffer; public: - Renderer(ImageOutput &output); + Renderer(int output_width, int output_height); - ImageOutput &getOutput() const; + int getOutputWidth(); + int getOutputHeight(); + float *getFrameBuffer(); + + void setOutputSize(int output_width, int output_height); void render(const Scene &scene, const Camera &camera); diff --git a/include/output/ImageOutput.hpp b/include/output/ImageOutput.hpp deleted file mode 100644 index 561a711..0000000 --- a/include/output/ImageOutput.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef IMAGE_OUTPUT_H -#define IMAGE_OUTPUT_H - -class ImageOutput { -public: - virtual int getWidth() const = 0; - virtual int getHeight() const = 0; - virtual void writeColor(int r, int g, int b) const = 0; -}; - -#endif // IMAGE_OUTPUT_H \ No newline at end of file diff --git a/include/output/PPMOutput.hpp b/include/output/PPMOutput.hpp deleted file mode 100644 index 4dee8ea..0000000 --- a/include/output/PPMOutput.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef PPM_OUTPUT_H -#define PPM_OUTPUT_H - -#include - -#include "ImageOutput.hpp" - -class PPMOutput : public ImageOutput { -private: - int width; - int height; - int max_color; - std::ostream &output_stream; - -public: - PPMOutput(int width, int height, int max_color = 255, - std::ostream &output_stream = std::cout) - : width(width), height(height), max_color(max_color), - output_stream(output_stream) {} - - int getWidth() const override { return this->width; } - int getHeight() const override { return this->height; } - int getMaxColor() const { return this->max_color; } - std::ostream &getOutputStream() const { return this->output_stream; } - - void writeHeader() { - this->output_stream << "P3\n" - << this->width << ' ' << this->height << '\n' - << max_color << '\n'; - } - - inline void writeColor(int r, int g, int b) const override { - this->output_stream << r << ' ' << g << ' ' << b << '\n'; - } -}; - -#endif // PPM_OUTPUT_H \ No newline at end of file diff --git a/src/3d/Renderer.cpp b/src/3d/Renderer.cpp index 5d53d18..03e26c9 100644 --- a/src/3d/Renderer.cpp +++ b/src/3d/Renderer.cpp @@ -2,27 +2,41 @@ #include "MathUtils.hpp" -Renderer::Renderer(ImageOutput &output) : output(output) {} +Renderer::Renderer(int output_width, int output_height) { + this->setOutputSize(output_width, output_height); +} -ImageOutput &Renderer::getOutput() const { return this->output; } +int Renderer::getOutputWidth() { return this->output_width; } +int Renderer::getOutputHeight() { return this->output_height; } +float *Renderer::getFrameBuffer() { return this->frame_buffer; } -void Renderer::render(const Scene &scene, const Camera &camera) { - const int WIDTH = this->output.getWidth(); - const int HEIGHT = this->output.getHeight(); +void Renderer::setOutputSize(int output_width, int output_height) { + this->output_width = output_width; + this->output_height = output_height; + + this->num_pixels = output_width * output_height; + this->frame_buffer_size = 3 * num_pixels * sizeof(float); + this->frame_buffer = (float *)malloc(frame_buffer_size); +} - for (int i = 0; i < WIDTH; i++) { - for (int j = 0; j < HEIGHT; j++) { - auto u = static_cast(i) / (WIDTH - 1); - auto v = static_cast(j) / (HEIGHT - 1); +void Renderer::render(const Scene &scene, const Camera &camera) { + for (int i = 0; i < this->output_width; i++) { + for (int j = 0; j < this->output_height; j++) { + auto u = static_cast(i) / (this->output_width - 1); + auto v = static_cast(j) / (this->output_height - 1); Ray ray = camera.getRay(u, v); Color ray_color = this->getRayColor(ray, scene); - int r = static_cast(256 * clamp(ray_color.getX(), 0, 0.999)); - int g = static_cast(256 * clamp(ray_color.getY(), 0, 0.999)); - int b = static_cast(256 * clamp(ray_color.getZ(), 0, 0.999)); + // int r = static_cast(256 * clamp(ray_color.getX(), 0, 0.999)); + // int g = static_cast(256 * clamp(ray_color.getY(), 0, 0.999)); + // int b = static_cast(256 * clamp(ray_color.getZ(), 0, 0.999)); + + int pixel_index = 3 * (i + j * this->output_width); - this->output.writeColor(r, g, b); + this->frame_buffer[pixel_index] = clamp(ray_color.getX(), 0, 0.999); + this->frame_buffer[pixel_index + 1] = clamp(ray_color.getY(), 0, 0.999); + this->frame_buffer[pixel_index + 2] = clamp(ray_color.getZ(), 0, 0.999); } } } diff --git a/src/main.cpp b/src/main.cpp index c4d5e66..7bd17a8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,6 @@ #include #include -#include -#include "PPMOutput.hpp" #include "Renderer.hpp" #include "Scene.hpp" #include "Sphere.hpp" @@ -15,16 +13,8 @@ int main() { const int IMAGE_WIDTH = 256; const int IMAGE_HEIGHT = 256; - const int MAX_COLOR = 255; std::ofstream f_out("image.ppm"); - std::ostream &f_ostream(f_out); - - f_ostream.rdbuf(f_out.rdbuf()); - - auto output = PPMOutput(IMAGE_WIDTH, IMAGE_HEIGHT, MAX_COLOR, f_ostream); - - output.writeHeader(); // Camera @@ -38,7 +28,31 @@ int main() { scene.add(test_sphere); - Renderer renderer(output); + // Render + + Renderer renderer(IMAGE_WIDTH, IMAGE_HEIGHT); + + float *frame_buffer = renderer.getFrameBuffer(); renderer.render(scene, camera); + + // Write to PPM + + f_out << "P3\n" << IMAGE_WIDTH << ' ' << IMAGE_HEIGHT << '\n' << 255 << '\n'; + + for (int i = 0; i < IMAGE_WIDTH; i++) { + for (int j = 0; j < IMAGE_HEIGHT; j++) { + int pixel_index = 3 * (i + j * IMAGE_WIDTH); + + float r = frame_buffer[pixel_index + 0]; + float g = frame_buffer[pixel_index + 1]; + float b = frame_buffer[pixel_index + 2]; + + int ir = int(255.99 * r); + int ig = int(255.99 * g); + int ib = int(255.99 * b); + + f_out << ir << ' ' << ig << ' ' << ib << '\n'; + } + } } \ No newline at end of file