aboutsummaryrefslogtreecommitdiff
path: root/src/texture/image_texture.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/texture/image_texture.rs')
-rw-r--r--src/texture/image_texture.rs63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/texture/image_texture.rs b/src/texture/image_texture.rs
new file mode 100644
index 0000000..763c3f0
--- /dev/null
+++ b/src/texture/image_texture.rs
@@ -0,0 +1,63 @@
+use super::Texture;
+use crate::{vec3::Color, vec3::Point3};
+
+// assume 24 bit depth
+const BYTES_PER_PIXEL: usize = 3;
+pub struct ImageTexture {
+ data: Vec<u8>,
+ width: usize,
+ height: usize,
+ bytes_per_scanline: usize,
+}
+
+impl ImageTexture {
+ pub fn from_bmp_data(bmp_data: &Vec<u8>) -> Self {
+ let data_position = u32::from_le_bytes([
+ bmp_data[0x0A],
+ bmp_data[0x0B],
+ bmp_data[0x0C],
+ bmp_data[0x0D],
+ ]);
+ // assuming windows BITMAPINFOHEADER, these are i32
+ let width = i32::from_le_bytes([
+ bmp_data[0x12],
+ bmp_data[0x13],
+ bmp_data[0x14],
+ bmp_data[0x15],
+ ]) as usize;
+ let height = i32::from_le_bytes([
+ bmp_data[0x16],
+ bmp_data[0x17],
+ bmp_data[0x18],
+ bmp_data[0x19],
+ ]) as usize;
+ Self {
+ data: bmp_data[(data_position as usize)..bmp_data.len()].to_vec(),
+ height,
+ width,
+ bytes_per_scanline: BYTES_PER_PIXEL * width,
+ }
+ }
+}
+
+impl Texture for ImageTexture {
+ fn value(&self, u: f64, v: f64, _: &Point3) -> Color {
+ let u = u.clamp(0.0, 1.0);
+ // This is a deviation from the book, where v gets flipped.
+ // This is probably because the BMP loader loads in stuff upside down.
+ //let v = 1.0 - v.clamp(0.0, 1.0);
+ let v = v.clamp(0.0, 1.0);
+ let mut i = (u * self.width as f64) as usize;
+ let mut j = (v * self.height as f64) as usize;
+
+ if i >= self.width { i = self.width - 1 };
+ if j >= self.height { j = self.height - 1 };
+ let color_scale = 1.0 / 255.0;
+ let pixel = j * self.bytes_per_scanline + i * BYTES_PER_PIXEL;
+ Color {
+ x: color_scale * *self.data.get(pixel + 2).unwrap() as f64,
+ y: color_scale * *self.data.get(pixel + 1).unwrap() as f64,
+ z: color_scale * *self.data.get(pixel).unwrap() as f64,
+ }
+ }
+}