diff --git a/src/material/mod.rs b/src/material/mod.rs index 523367b..bbc8094 100644 --- a/src/material/mod.rs +++ b/src/material/mod.rs @@ -1,56 +1,13 @@ use super::core::color::LinearColor; +use super::Point2D; -/// Represent the physical light properties of an object in the scene. -#[derive(Debug, PartialEq)] -pub struct Material { - /// The diffuse component. - diffuse: LinearColor, - /// The specular component. - specular: LinearColor, +/// Represent the physical light properties of an object in the scene; +pub trait Material: std::fmt::Debug { + /// The diffuse component on a texel point. + fn diffuse(&self, point: Point2D) -> LinearColor; + /// The specular component on a texel point. + fn specular(&self, point: Point2D) -> LinearColor; } -impl Material { - pub fn new(diffuse: LinearColor, specular: LinearColor) -> Self { - Material { diffuse, specular } - } - - pub fn diffuse(&self) -> &LinearColor { - &self.diffuse - } - - pub fn specular(&self) -> &LinearColor { - &self.specular - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn new_works() { - let diffuse = LinearColor::new(0., 0.5, 0.); - let specular = LinearColor::new(1., 1., 1.); - let mat = Material::new(diffuse.clone(), specular.clone()); - assert_eq!(mat, Material { diffuse, specular }) - } - - fn simple_material() -> Material { - Material::new( - LinearColor::new(0.5, 0.5, 0.5), - LinearColor::new(1., 1., 1.), - ) - } - - #[test] - fn diffuse_works() { - let mat = simple_material(); - assert_eq!(mat.diffuse(), &LinearColor::new(0.5, 0.5, 0.5)) - } - - #[test] - fn specular_works() { - let mat = simple_material(); - assert_eq!(mat.specular(), &LinearColor::new(1., 1., 1.)) - } -} +pub mod uniform; +pub use uniform::*; diff --git a/src/material/uniform.rs b/src/material/uniform.rs new file mode 100644 index 0000000..b86b43b --- /dev/null +++ b/src/material/uniform.rs @@ -0,0 +1,64 @@ +use super::super::core::color::LinearColor; +use super::super::Point2D; +use super::Material; + +/// A material with the same characteristics on all points. +#[derive(Debug, PartialEq)] +pub struct UniformMaterial { + diffuse: LinearColor, + specular: LinearColor, +} + +impl UniformMaterial { + pub fn new(diffuse: LinearColor, specular: LinearColor) -> Self { + UniformMaterial { diffuse, specular } + } +} + +impl Material for UniformMaterial { + fn diffuse(&self, _: Point2D) -> LinearColor { + self.diffuse.clone() + } + + fn specular(&self, _: Point2D) -> LinearColor { + self.specular.clone() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn new_works() { + let diffuse = LinearColor::new(0., 0.5, 0.); + let specular = LinearColor::new(1., 1., 1.); + let mat = UniformMaterial::new(diffuse.clone(), specular.clone()); + assert_eq!(mat, UniformMaterial { diffuse, specular }) + } + + fn simple_material() -> impl Material { + UniformMaterial::new( + LinearColor::new(0.5, 0.5, 0.5), + LinearColor::new(1., 1., 1.), + ) + } + + #[test] + fn diffuse_works() { + let mat = simple_material(); + assert_eq!( + mat.diffuse(Point2D::origin()), + LinearColor::new(0.5, 0.5, 0.5) + ) + } + + #[test] + fn specular_works() { + let mat = simple_material(); + assert_eq!( + mat.specular(Point2D::origin()), + LinearColor::new(1., 1., 1.) + ) + } +}