diff options
Diffstat (limited to 'src/camera')
-rw-r--r-- | src/camera/camera.rs | 9 | ||||
-rw-r--r-- | src/camera/film.rs | 40 | ||||
-rw-r--r-- | src/camera/mod.rs | 1 |
3 files changed, 38 insertions, 12 deletions
diff --git a/src/camera/camera.rs b/src/camera/camera.rs index 69fd4e0..7822e92 100644 --- a/src/camera/camera.rs +++ b/src/camera/camera.rs @@ -7,13 +7,13 @@ //! //! ``` //! use pathtrace::camera::Camera; -//! use pathtrace::core::{Vector3f, Vector2f}; +//! use pathtrace::core::{Vector3f, Vector2f, Vector2i}; //! //! let cam = Camera::new( //! Vector3f::new(10.0), //! Vector3f::new(0.0), //! Vector3f::new_xyz(0.0, 1.0, 0.0), -//! 90.0, Vector2f::new(10.0), +//! 90.0, Vector2i::new(10.0), //! ); //! //! let (r, _) = cam.generate_ray(&Vector2f::new(5.0)); @@ -27,7 +27,7 @@ //! //! ``` use crate::Float; -use crate::core::{Vector3f, Vector2f, Ray}; +use crate::core::{Vector3f, Vector2f, Vector2i, Ray}; /// A simple perspective camera pub struct Camera { @@ -45,7 +45,8 @@ impl Camera { /// /// The field of view specifies how wide the image should be. /// Currently must be between [0; 180[. - pub fn new(origin: Vector3f, target: Vector3f, up: Vector3f, fov: Float, screensize: Vector2f) -> Camera { + pub fn new(origin: Vector3f, target: Vector3f, up: Vector3f, fov: Float, screensize: Vector2i) -> Camera { + let screensize = Vector2f::from(screensize); // Calculate translation vectors let forward = (target - origin).norm(); let right = up.cross(&origin).norm(); diff --git a/src/camera/film.rs b/src/camera/film.rs index 30fd2fe..3586374 100644 --- a/src/camera/film.rs +++ b/src/camera/film.rs @@ -1,5 +1,6 @@ use crate::core::*; use crate::Float; +use image::{RgbImage, Rgb}; /// Contains the necesary values when doing calculations /// @@ -14,7 +15,7 @@ pub struct Pixel { pub struct Film { size: Vector2i, - drawing_bound: Bound2i, + pub frame: Bound2i, pixels: Vec<Pixel>, } @@ -24,14 +25,12 @@ pub struct Film { /// This means that multiple threads can work on the same area and commit their changed when they /// are done. pub struct FilmTile { - bounds: Bound2i, - size: Vector2i, + pub bounds: Bound2i, + pub size: Vector2i, pixels: Vec<Pixel>, } -//const HalfPixel = Vector2f::new(0.5); - impl Pixel { fn new() -> Pixel { Pixel { @@ -44,6 +43,15 @@ impl Pixel { self.rgb += &(c * weight); self.samples += 1; } + + fn finalize_rgb(&self) -> [u8; 3] { + let (r, g, b) = self.rgb.to_rgb(255.0); + [ + r as u8, + g as u8, + b as u8, + ] + } } impl std::ops::AddAssign<&Self> for Pixel { @@ -58,7 +66,7 @@ impl Film { let area = size.x * size.y; Film { size, - drawing_bound: Bound2i::new(&Vector2i::new(0), &size), + frame: Bound2i::new(&Vector2i::new(0), &size), pixels: vec![Pixel::new(); area as usize], } } @@ -79,18 +87,34 @@ impl Film { pub fn commit_tile(&mut self, tile: &FilmTile) { let offset = tile.bounds.min; - for y in 0 ..= tile.size.y { + for y in 0 .. tile.size.y { let rowindex = (offset.y + y) * self.size.x; let prowindex = y * tile.size.x; - for x in 0 ..= tile.size.x { + 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]; } } + } + + pub fn finalize_image(&self) -> RgbImage { + let mut img = RgbImage::new(self.size.x as u32, self.size.y as u32); + + for y in 0..self.size.y { + let index = y * self.size.x; + for x in 0..self.size.x { + img.put_pixel( + x as u32, + y as u32, + Rgb(self.pixels[(index + x) as usize].finalize_rgb()), + ); + } + } + img } } diff --git a/src/camera/mod.rs b/src/camera/mod.rs index b7c982b..1391cea 100644 --- a/src/camera/mod.rs +++ b/src/camera/mod.rs @@ -10,3 +10,4 @@ pub mod film; pub mod camera; pub use camera::Camera; +pub use film::Film; |