use image::{DynamicImage, ImageReader}; use crate::{ objects::{hit::Hit, materials::traits::Material}, ray::Ray, vec3::Vec3, }; #[derive(Debug)] pub struct Texture { source: DynamicImage, width: u32, height: u32, } impl Texture { pub fn new(texture: &str) -> Self { let img = ImageReader::open(texture).unwrap().decode().unwrap(); // FIXME: unwraps Self { width: img.width(), height: img.height(), source: img, } } fn _idx(&self, u: f32, v: f32) -> usize { let x: usize = (u * ((self.width - 1) as f32)) as usize; // TODO: check these calcs work let y: usize = (v * ((self.height - 1) as f32)) as usize; y * self.width as usize + x } fn _at(&self, u: f32, v: f32) -> Vec3 { let b = self.source.as_bytes(); // FIXME: i think im indexing colours incorrectly let idx = self._idx(u, v); Vec3::from_u8(b[3 * idx], b[3 * idx + 1], b[3 * idx + 2]) } } impl Material for Texture { fn scatter(&self, hit: &Hit, _ray: &Ray) -> Option<(Option, Vec3)> { let (u, v) = hit.uv(); let col = self._at(u, 1. - v); return Some((None, col)); } }