From 94f1898b5183ab7f35ff1662bea9635e8212c25f Mon Sep 17 00:00:00 2001 From: vonhyou Date: Tue, 27 Feb 2024 20:35:41 -0500 Subject: [PATCH] rewrite output --- src/Output.cc | 22 ++++++++++++++++++++++ src/Output.h | 37 +++++++++++++++++++++++++++++++++++++ src/RayTracer.cc | 32 +++++++++++--------------------- src/RayTracer.h | 8 +++----- 4 files changed, 73 insertions(+), 26 deletions(-) create mode 100644 src/Output.cc create mode 100644 src/Output.h diff --git a/src/Output.cc b/src/Output.cc new file mode 100644 index 0000000..81da024 --- /dev/null +++ b/src/Output.cc @@ -0,0 +1,22 @@ +#include "Output.h" + +#include + +void Output::write() { + std::ofstream fout(path, std::ios_base::out | std::ios_base::binary); + fout << "P6\n" << width << ' ' << height << '\n' << "255" << std::endl; + + for (unsigned int y = 0; y < height; ++y) + for (unsigned int x = 0; x < width; ++x) + fout << (char)(255.0f * red[y * width + x]) + << (char)(255.0f * green[y * width + x]) + << (char)(255.0f * blue[y * width + x]); + fout.close(); +} + +float Output::r(int index) { return red.at(index); } +float Output::g(int index) { return green.at(index); } +float Output::b(int index) { return blue.at(index); } +void Output::r(int index, float value) { red.at(index) = value; } +void Output::g(int index, float value) { green.at(index) = value; } +void Output::b(int index, float value) { blue.at(index) = value; } diff --git a/src/Output.h b/src/Output.h new file mode 100644 index 0000000..d7b9af9 --- /dev/null +++ b/src/Output.h @@ -0,0 +1,37 @@ +#ifndef OUTPUT_H_ +#define OUTPUT_H_ + +#include +#include +#include + +using Eigen::Vector3f; +using std::string; +using std::vector; + +class Output { +public: + Output(const Vector3f &bgc, string path, int w, int h) + : red(vector(w * h, bgc.x())), + green(vector(w * h, bgc.y())), + blue(vector(w * h, bgc.z())), path(path), width(w), height(h) {} + + void write(); + +private: + int width, height; + string path; + vector red; + vector green; + vector blue; + +public: + void r(int, float); + float r(int); + void g(int, float); + float g(int); + void b(int, float); + float b(int); +}; + +#endif // !OUTPUT_H_ diff --git a/src/RayTracer.cc b/src/RayTracer.cc index 7994cf6..e4a393b 100644 --- a/src/RayTracer.cc +++ b/src/RayTracer.cc @@ -1,5 +1,6 @@ #include "RayTracer.h" #include "../external/simpleppm.h" +#include "Output.h" #include "Parser.h" #include "Ray.h" @@ -39,13 +40,8 @@ void RayTracer::render(Scene *scene) { Vector3f vpUpperLeft = cameraPos + lookAt - vpU / 2.0 - vpV / 2.0; Vector3f pxUpperLeft = vpUpperLeft + (du + dv) / 2.0; - Buffer buffer(width * height * 3); - Vector3f bgc = scene->getBackgroundColor(); - for (int i = 0; i < width * height; ++i) { - buffer[i * 3] = bgc.x(); - buffer[i * 3 + 1] = bgc.y(); - buffer[i * 3 + 2] = bgc.z(); - } + Output *buffer = + new Output(scene->getBackgroundColor(), scene->getName(), width, height); for (int y = 0; y < height; ++y) for (int x = 0; x < width; ++x) { @@ -53,23 +49,18 @@ void RayTracer::render(Scene *scene) { for (auto geometry : geometries) if (geometry->intersect(ray)) { - buffer[3 * y * width + 3 * x + 0] = 1; - buffer[3 * y * width + 3 * x + 1] = 1; - buffer[3 * y * width + 3 * x + 2] = 1; + buffer->r(y * width + x, 1); + buffer->g(y * width + x, 1); + buffer->b(y * width + x, 1); break; } } - - Task *task = new Task(scene, buffer); - tasks.push_back(task); + outputs.push_back(buffer); } -void RayTracer::output(Task *task) { - string path = task->first->getName(); - int width = task->first->getWidth(); - int height = task->first->getHeight(); - - save_ppm(path, task->second, width, height); +void RayTracer::output() { + for (auto output : outputs) + output->write(); } void RayTracer::run() { @@ -78,6 +69,5 @@ void RayTracer::run() { for (auto scene : scenes) render(scene); - for (auto task : tasks) - output(task); + output(); } diff --git a/src/RayTracer.h b/src/RayTracer.h index 95c917c..807b370 100644 --- a/src/RayTracer.h +++ b/src/RayTracer.h @@ -4,14 +4,12 @@ #include "../external/json.hpp" #include "Geometry.h" #include "Light.h" +#include "Output.h" #include "Scene.h" #include #include -using Buffer = std::vector; -using Task = std::pair; - class RayTracer { public: RayTracer(const nlohmann::json &j) : json(j) {} @@ -23,11 +21,11 @@ private: std::vector lights; std::vector geometries; - std::vector tasks; + std::vector outputs; void parse(); void render(Scene *); - void output(Task *); + void output(); }; #endif // !RAY_TRACER_H_