aboutsummaryrefslogtreecommitdiff
path: root/src/camera/film.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/camera/film.rs')
-rw-r--r--src/camera/film.rs92
1 files changed, 63 insertions, 29 deletions
diff --git a/src/camera/film.rs b/src/camera/film.rs
index 6661529..1d87399 100644
--- a/src/camera/film.rs
+++ b/src/camera/film.rs
@@ -1,67 +1,101 @@
-use crate::vector::*;
+use crate::core::*;
use crate::Float;
-use crate::bound;
-use crate::spectrum::Spectrum;
-
-use bound::{Bound2i, Bound2f};
-use super::filter::Filter;
-use std::rc::Rc;
#[derive(Clone)]
pub struct Pixel {
- pub rgb: [Float; 3],
+ rgb: Spectrum,
+ samples: u32,
}
pub struct Film {
- pub resolution: Vector2i,
+ size: Vector2i,
drawingBound: Bound2i,
pixels: Vec<Pixel>,
- filter: Rc<Filter>,
}
pub struct FilmTile {
- pub bounds: Bound2i,
- filter: Rc<Filter>,
+ bounds: Bound2i,
+ size: Vector2i,
+
+ pixels: Vec<Pixel>,
}
+//const HalfPixel = Vector2f::new(0.5);
+
impl Pixel {
fn new() -> Pixel {
- Pixel { rgb: [0.0, 0.0, 0.0] }
+ Pixel {
+ rgb: Default::default(),
+ samples: 0,
+ }
+ }
+
+ fn add(&mut self, c: &Spectrum, weight: Float) {
+ self.rgb += &(c * weight);
+ self.samples += 1;
+ }
+}
+
+impl std::ops::AddAssign<&Self> for Pixel {
+ fn add_assign(&mut self, op: &Self) {
+ self.rgb += &op.rgb;
+ self.samples += op.samples;
}
}
impl Film {
- pub fn new(resolution: Vector2i, filter: Rc<Filter>) -> Film {
- let area = resolution.x * resolution.y;
+ pub fn new(size: Vector2i) -> Film {
+ let area = size.x * size.y;
Film {
- resolution,
- drawingBound: Bound2i::new(&Vector2::new(0), &resolution),
+ size,
+ drawingBound: Bound2i::new(&Vector2i::new(0), &size),
pixels: vec![Pixel::new(); area as usize],
- filter,
}
}
pub fn get_tile(&self, bound: &Bound2i) -> FilmTile {
- // Used to calculate descrete coordinates into continues
- let halfpixel = Vector2f::new_xy(0.5, 0.5);
- let fbound = Bound2f::from(bound);
+ FilmTile::new(
+ bound,
+ )
+
+ }
- let p0 = Vector2i::from((fbound.min - halfpixel - self.filter.radius).ceil());
- let p1 = Vector2i::from((fbound.min - halfpixel + self.filter.radius).floor());
+ pub fn commit_tile(&mut self, tile: &FilmTile) {
+ let offset = tile.bounds.min;
- let tilebound = bound::intersect(&Bound2i::new(&p0, &p1), &self.drawingBound);
+ for y in 0 ..= tile.size.y {
+ let rowindex = (offset.y + y) * self.size.x;
+ let prowindex = y * tile.size.x;
- FilmTile {
- bounds: tilebound,
- filter: self.filter.clone(),
+ for x in 0 ..= tile.size.x {
+ let index = offset.x + x + rowindex;
+ let pindex: i32 = x + prowindex;
+
+ self.pixels[index as usize] += &tile.pixels[pindex as usize];
+ }
}
}
}
impl FilmTile {
- fn add_sample(point: &Vector2f, c: Spectrum) {
-
+ fn new(bounds: &Bound2i) -> FilmTile {
+ FilmTile {
+ bounds: bounds.clone(),
+ pixels: vec![Pixel::new(); bounds.area() as usize],
+ size: bounds.diagonal(),
+ }
+ }
+
+ pub fn add_sample(&mut self, point: &Vector2f, c: Spectrum) {
+ let point = Vector2i::from(point.floor());
+ // Subtract the offset
+ let point = point - self.bounds.min;
+
+ let index = point.x + point.y * self.size.x;
+
+ let pixel = self.pixels.get_mut(index as usize).unwrap();
+ pixel.add(&c, 1.0);
}
}