Files
raytracing/src/objects/materials/texture.rs
2026-09-13 15:18:05 +02:00

69 lines
1.9 KiB
Rust

use image::{DynamicImage, ImageReader};
use log::trace;
use crate::{objects::hit::Hit, vec3::Vec3};
#[derive(Debug)]
pub struct Texture {
source: DynamicImage,
width: u32,
height: u32,
stride: usize,
}
impl Texture {
pub fn new(texture: &str) -> Self {
let img = ImageReader::open(texture).unwrap().decode().unwrap(); // FIXME: unwraps
trace!(
"texture '{}' is {} by {} pixels, with {} bytes total",
texture,
img.width(),
img.height(),
img.as_bytes().len()
);
let stride = match img.color() {
// TODO: support other types of image
image::ColorType::L8 => todo!(),
image::ColorType::La8 => todo!(),
image::ColorType::Rgb8 => 3,
image::ColorType::Rgba8 => 4,
image::ColorType::L16 => todo!(),
image::ColorType::La16 => todo!(),
image::ColorType::Rgb16 => todo!(),
image::ColorType::Rgba16 => todo!(),
image::ColorType::Rgb32F => todo!(),
image::ColorType::Rgba32F => todo!(),
_ => 3,
};
Self {
width: img.width(),
height: img.height(),
source: img,
stride,
}
}
fn _idx(&self, u: f32, v: f32) -> usize {
let x: usize = (u * ((self.width - 1) as f32)) as usize;
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();
let idx = self._idx(u, v);
Vec3::from_u8(
b[self.stride * idx],
b[self.stride * idx + 2],
b[self.stride * idx + 1],
)
}
pub fn colour_at(&self, hit: &Hit) -> Vec3 {
let (u, v) = hit.uv();
self._at(u, 1. - v)
}
}