Skip to content

Commit

Permalink
Clean up ImageBuffer API
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Oom committed Mar 26, 2024
1 parent 3a6d294 commit fffa680
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 32 deletions.
2 changes: 1 addition & 1 deletion pathtracer-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ fn main() {
.into_par_iter()
.map(|i| worker_thread(i, &work, iterations_per_thread, &tx));
let printer = std::thread::spawn(move || printer_thread(args.threads, args.iterations, rx));
let buffer = buffers.reduce_with(|a, b| a + b).unwrap();
let buffer = buffers.reduce_with(|a, b| a.add(b)).unwrap();
tx.send(time::Duration::ZERO).unwrap();
printer.join().unwrap();

Expand Down
50 changes: 27 additions & 23 deletions src/image_buffer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{ops::Add, path::Path};
use std::path::Path;

pub struct ImageBuffer(image::ImageBuffer<image::Rgb<f32>, Vec<f32>>);

Expand All @@ -9,13 +9,17 @@ fn gamma_correct(x: &f32) -> f32 {

impl ImageBuffer {
pub fn new(width: u32, height: u32) -> Self {
ImageBuffer(image::ImageBuffer::new(height, width))
ImageBuffer(image::ImageBuffer::new(width, height))
}

pub fn ncols(&self) -> u32 {
pub fn size(&self) -> [u32; 2] {
[self.0.width(), self.0.height()]
}

pub fn width(&self) -> u32 {
self.0.width()
}
pub fn nrows(&self) -> u32 {
pub fn height(&self) -> u32 {
self.0.height()
}

Expand All @@ -30,45 +34,45 @@ impl ImageBuffer {
)
}

pub fn gamma_correct(&self) -> Self {
pub fn add(&self, rhs: Self) -> Self {
ImageBuffer(
image::ImageBuffer::from_vec(
self.0.width(),
self.0.height(),
self.0.iter().map(gamma_correct).collect(),
self.0
.iter()
.zip(rhs.0.iter())
.map(|(a, b)| a + b)
.collect(),
)
.unwrap(),
)
}

pub fn save_png(self, path: &Path) -> Result<(), image::ImageError> {
image::DynamicImage::ImageRgb32F(self.0)
.into_rgb8()
.save_with_format(path, image::ImageFormat::Png)
}

pub fn add_mut(&mut self, x: u32, y: u32, value: [f32; 3]) {
pub fn add_pixel_mut(&mut self, x: u32, y: u32, value: [f32; 3]) {
self.0[(x, y)][0] += value[0];
self.0[(x, y)][1] += value[1];
self.0[(x, y)][2] += value[2];
}
}

impl Add for ImageBuffer {
type Output = ImageBuffer;

fn add(self, rhs: Self) -> Self::Output {
pub fn gamma_correct(&self) -> Self {
ImageBuffer(
image::ImageBuffer::from_vec(
self.0.width(),
self.0.height(),
self.0
.iter()
.zip(rhs.0.iter())
.map(|(a, b)| a + b)
.collect(),
self.0.iter().map(gamma_correct).collect(),
)
.unwrap(),
)
}

pub fn to_rgba8(self) -> Vec<u8> {
image::DynamicImage::ImageRgb32F(self.0).to_rgba8().to_vec()
}

pub fn save_png(self, path: &Path) -> Result<(), image::ImageError> {
image::DynamicImage::ImageRgb32F(self.0)
.into_rgb8()
.save_with_format(path, image::ImageFormat::Png)
}
}
8 changes: 4 additions & 4 deletions src/pathtracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ pub fn render(
buffer: &mut ImageBuffer,
rng: &mut SmallRng,
) {
let buffer_size = Vector2::new(buffer.ncols() as f32, buffer.nrows() as f32);
for y in 0..buffer.nrows() {
for x in 0..buffer.ncols() {
let buffer_size = Vector2::new(buffer.width() as f32, buffer.height() as f32);
for y in 0..buffer.height() {
for x in 0..buffer.width() {
let pixel_center = Vector2::new(x as f32, y as f32) + uniform_sample_unit_square(rng);
let scene_direction = pixel_center.component_div(&buffer_size);
let ray = camera.ray(scene_direction.x, scene_direction.y);
Expand All @@ -127,7 +127,7 @@ pub fn render(
0,
rng,
);
buffer.add_mut(x, y, value.into());
buffer.add_pixel_mut(x, y, value.into());
}
}
}
8 changes: 4 additions & 4 deletions src/raytracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ fn trace_ray(scene: &Scene, ray: &Ray) -> Vector3<f32> {
}

pub fn render(scene: &Scene, camera: &Pinhole, buffer: &mut ImageBuffer) {
let buffer_size = Vector2::new(buffer.ncols() as f32, buffer.nrows() as f32);
for y in 0..buffer.nrows() {
for x in 0..buffer.ncols() {
let buffer_size = Vector2::new(buffer.width() as f32, buffer.height() as f32);
for y in 0..buffer.height() {
for x in 0..buffer.width() {
let pixel_center = Vector2::new(x as f32, y as f32) + Vector2::new(0.5, 0.5);
let scene_direction = pixel_center.component_div(&buffer_size);
let ray = camera.ray(scene_direction.x, scene_direction.y);
let value = trace_ray(scene, &ray);
buffer.add_mut(x, y, value.into());
buffer.add_pixel_mut(x, y, value.into());
}
}
}

0 comments on commit fffa680

Please sign in to comment.