Skip to content

Commit

Permalink
Partially working progress reporter class.
Browse files Browse the repository at this point in the history
  • Loading branch information
wermos committed Jul 30, 2024
1 parent 60130e7 commit 1d9c9f4
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 11 deletions.
4 changes: 3 additions & 1 deletion Celerity/include/renderer/renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// Image writer includes
#include "imageWriters/imageWriter.hpp"

#include "progressReporter.hpp"
namespace Renderer {
void singleCoreRender(const int imageWidth, const int imageHeight,
const HittableList& world, const int maxRayDepth,
Expand All @@ -20,5 +21,6 @@ void singleCoreRender(const int imageWidth, const int imageHeight,
void multiCoreRender(std::atomic<int>& scanLinesLeft, const int imageWidth,
const int imageHeight, const HittableList& world,
const int maxRayDepth, const Camera& camera,
const int samplesPerPixel, ImageWriter& iw);
const int samplesPerPixel, ImageWriter& iw,
ProgressReporter& progressReporter);
} // namespace Renderer
9 changes: 8 additions & 1 deletion Celerity/src/main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
// spdlog include
#include "spdlog/spdlog.h"

#include "progressReporter.hpp"

int main() {
// Image
constexpr float aspectRatio = 16.0 / 9.0;
Expand Down Expand Up @@ -58,12 +60,17 @@ int main() {

spdlog::info("Commencing ray tracing...");

// Create a single ProgressReporter instance
ProgressReporter progressReporter(imageHeight);
progressReporter.start();

// Kick off each thread with the Renderer::multiCoreRender() task
for (std::size_t i = 0; i < numThreads; ++i) {
threadPool[i] =
std::jthread(Renderer::multiCoreRender, std::ref(scanLinesLeft),
imageWidth, imageHeight, std::cref(world), maxRayDepth,
std::cref(camera), samplesPerPixel, std::ref(iw));
std::cref(camera), samplesPerPixel, std::ref(iw),
std::ref(progressReporter));
}

delete[] threadPool;
Expand Down
11 changes: 6 additions & 5 deletions Celerity/src/renderer/renderer.cxx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "renderer/renderer.hpp"
#include "progressReporter.hpp"

#include <iostream>
#include <syncstream>
Expand Down Expand Up @@ -66,16 +67,13 @@ void singleCoreRender(const int imageWidth, const int imageHeight,
void multiCoreRender(std::atomic<int>& scanLinesLeft, const int imageWidth,
const int imageHeight, const HittableList& world,
const int maxRayDepth, const Camera& camera,
const int samplesPerPixel, ImageWriter& iw) {
const int samplesPerPixel, ImageWriter& iw,
ProgressReporter& progressReporter) {
while (scanLinesLeft >= 0) {
int currentImageRow = scanLinesLeft;
scanLinesLeft--;
int bufferRow = imageHeight - currentImageRow - 1;

std::osyncstream syncedLog(std::clog); // TODO: Make this optional.
syncedLog << "\rScanlines remaining: " << currentImageRow << " "
<< std::flush;

for (int i = 0; i < imageWidth; ++i) {
color pixelColor;
for (int s = 0; s < samplesPerPixel; ++s) {
Expand All @@ -91,6 +89,9 @@ void multiCoreRender(std::atomic<int>& scanLinesLeft, const int imageWidth,

iw.addPixel(3 * (bufferRow * imageWidth + i), pixelColor);
}

progressReporter.scanlineProcessed();
progressReporter.update();
}
}
} // namespace Renderer
75 changes: 71 additions & 4 deletions utilities/include/progressReporter.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,75 @@
#pragma once

#include <atomic>
#include <chrono>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <iostream>
#include <iomanip>
#include <thread>
#include <mutex>
#include <sstream>

class ProgressReporter {
public:
public:
ProgressReporter(int totalScanLines, int updateInterval = 1)
: totalScanLines(totalScanLines), scanLinesLeft(totalScanLines),
updateInterval(updateInterval), startTime(std::chrono::steady_clock::now()), lastUpdate(startTime) {
auto logger = spdlog::stdout_color_mt("progress_logger");
logger->set_pattern("%v"); // Set pattern to only show the message
spdlog::set_default_logger(logger);

spdlog::info("Starting render with {} total scanlines", totalScanLines);
}

void start() {
startTime = std::chrono::steady_clock::now();
scanLinesLeft = totalScanLines;
}

void update() {
using namespace std::chrono;
auto now = steady_clock::now();
if (duration_cast<seconds>(now - lastUpdate).count() >= updateInterval) {
lastUpdate = now;
displayProgressBar();
}
}

void scanlineProcessed() {
--scanLinesLeft;
}

private:
int totalScanLines;
std::atomic<int> scanLinesLeft;
std::chrono::steady_clock::time_point startTime;
std::chrono::steady_clock::time_point lastUpdate;
int updateInterval;
std::mutex mtx;

void displayProgressBar() {
std::lock_guard<std::mutex> lock(mtx);
int remaining = scanLinesLeft.load();
int processed = totalScanLines - remaining;
float progress = static_cast<float>(processed) / totalScanLines;

int barWidth = 50;
std::ostringstream bar;
bar << "\r[";
int pos = barWidth * progress;
for (int i = 0; i < barWidth; ++i) {
if (i < pos) bar << "=";
else if (i == pos) bar << ">";
else bar << " ";
}
bar << "] " << int(progress * 100.0) << "%";

auto now = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - startTime).count();
auto eta = progress > 0 ? static_cast<int>((elapsed / progress) * (1.0 - progress)) : 0;
bar << " ETA: " << eta << "s ";

private:

};
spdlog::default_logger_raw()->log(spdlog::level::info, bar.str());
}
};

0 comments on commit 1d9c9f4

Please sign in to comment.