Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Adding a Progress Indicator

Before we continue, let's add a progress indicator to our output. This is a handy way to track the progress of a long render, and also to possibly identify a run that's stalled out due to an infinite loop or other problem.

Our program outputs the image to the standard output stream (std::cout), so leave that alone and instead write to the logging output stream (std::clog):1

diff --git a/src/main.rs b/src/main.rs
index af636bc..00cad27 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,26 +1,29 @@
 fn main() {
     // Image
 
     const IMAGE_WIDTH: u32 = 256;
     const IMAGE_HEIGHT: u32 = 256;
 
     // Render
 
+    env_logger::init();
     println!("P3");
     println!("{IMAGE_WIDTH} {IMAGE_HEIGHT}");
     println!("255");
 
     for j in 0..IMAGE_HEIGHT {
+        log::info!("Scanlines remaining: {}", IMAGE_HEIGHT - j);
         for i in 0..IMAGE_WIDTH {
             let r = i as f64 / (IMAGE_WIDTH - 1) as f64;
             let g = j as f64 / (IMAGE_HEIGHT - 1) as f64;
             let b = 0.0;
 
             let ir = (255.999 * r) as i32;
             let ig = (255.999 * g) as i32;
             let ib = (255.999 * b) as i32;
 
             println!("{ir} {ig} {ib}");
         }
     }
+    log::info!("Done.");
 }

Listing 3: [main.rs] Main render loop with progress reporting


Now when running, you'll see a running count of the number of scanlines remaining. Hopefully this runs so fast that you don't even see it! Don't worry — you'll have lots of time in the future to watch a slowly updating progress line as we expand our ray tracer.


  1. The log crate with the env_logger implementation is a good alternative to std::clog. Run RUST_LOG=info cargo r > image.ppm for the log output.