diff --git a/src/fart/Engine.cpp b/src/fart/Engine.cpp index 5ab7477..96d65f0 100644 --- a/src/fart/Engine.cpp +++ b/src/fart/Engine.cpp @@ -1,8 +1,81 @@ #include #include +#include #include #include #include +#include + +namespace +{ + +/** + * Reports render progress to stdout when stdout is a TTY. + * + * An update is written only when progress has increased by at least 1%, + * or when progress has increased at all and at least 1 second has elapsed + * since the last update. + */ +class ProgressReporter +{ +public: + using clock = std::chrono::steady_clock; + + explicit ProgressReporter(size_t total) + : total(total) + , enabled(total > 0u && isatty(STDOUT_FILENO)) + { + if (enabled) + { + last_time = clock::now(); + print(0u); + } + } + + void update(size_t done) + { + if (!enabled || done <= last_done) + { + return; + } + /* (done - last_done) / total >= 1 / 100 */ + bool percent_step = (done - last_done) * 100u >= total; + clock::time_point now = clock::now(); + if (percent_step || (now - last_time) >= std::chrono::seconds(1)) + { + last_time = now; + print(done); + } + } + + void finish() + { + if (enabled) + { + if (last_done < total) + { + print(total); + } + fputc('\n', stdout); + fflush(stdout); + } + } + +protected: + size_t total; + bool enabled; + size_t last_done = 0u; + clock::time_point last_time; + + void print(size_t done) + { + last_done = done; + printf("\rRendering: %6.2f%%", (double)done * 100.0 / (double)total); + fflush(stdout); + } +}; + +} Engine::Engine(const Options & options) : options(options) @@ -67,13 +140,18 @@ int Engine::run(string_view input_file, opt output_file) options.apply_defaults(); Image image(*options.width, *options.height); + ProgressReporter progress(*options.width * *options.height); + size_t pixels_done = 0u; for (size_t y = 0u; y < *options.height; y++) { for (size_t x = 0u; x < *options.width; x++) { - image[x, y] = *options.background; + image[x, y] = render_pixel(x, y); + pixels_done++; + progress.update(pixels_done); } } + progress.finish(); if (!image_writer->write(image)) { @@ -82,3 +160,8 @@ int Engine::run(string_view input_file, opt output_file) return 0; } + +Color Engine::render_pixel(size_t x, size_t y) +{ + return *this->options.background; +} diff --git a/src/fart/Engine.h b/src/fart/Engine.h index 7845529..d32246c 100644 --- a/src/fart/Engine.h +++ b/src/fart/Engine.h @@ -16,4 +16,6 @@ protected: Options options; std::unique_ptr image_writer; Scene * scene = nullptr; + + Color render_pixel(size_t x, size_t y); };