use image::RgbImage; use texture::Texture; use vec3::Vec3; pub struct ImageTexture { img: RgbImage, width: f32, height: f32, } impl ImageTexture { pub fn new(img: RgbImage) -> ImageTexture { let (w, h) = img.dimensions(); ImageTexture { img, width: f32::from(w.min(64000) as u16), height: f32::from(h.min(64000) as u16), } } } impl Texture for ImageTexture { fn value(&self, u: f32, v: f32, _p: Vec3) -> Vec3 { // Wrap texcoords by default. let x = (u % 1. * (self.width - 1.)) as u32; let y = ((1. - v % 1.) * (self.height - 1.)) as u32; if x >= self.width as u32 { panic!(format!( "u {} v {} x {} y {} w {} h {}", u, v, x, y, self.width, self.height )); } if y >= self.height as u32 { panic!(format!( "u {} v {} x {} y {} w {} h {}", u, v, x, y, self.width, self.height )); } let pixel = self.img.get_pixel(x, y); Vec3::new( f32::from(pixel[0]) / 255., f32::from(pixel[1]) / 255., f32::from(pixel[2]) / 255., ) } }