aboutsummaryrefslogtreecommitdiff
path: root/src/camera
diff options
context:
space:
mode:
Diffstat (limited to 'src/camera')
-rw-r--r--src/camera/camera.rs9
-rw-r--r--src/camera/film.rs40
-rw-r--r--src/camera/mod.rs1
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;