From afc497002353c9069df30c2e6f0700515305e8a8 Mon Sep 17 00:00:00 2001 From: numzero Date: Sat, 27 Apr 2024 19:28:01 +0300 Subject: [PATCH] Extract rendering into a function --- src/main.rs | 55 ++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/main.rs b/src/main.rs index d745198..d267182 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ use std::io::Write; use rand::Rng; use glm::*; use show_image::{ImageInfo, ImageView, WindowOptions}; -use crate::mesh_loader::load_mesh; +use crate::mesh_loader::{Face, load_mesh}; const W: i32 = 320; const H: i32 = 240; @@ -57,41 +57,20 @@ fn ypr_to_mat(ypr: Vec3) -> Mat3 { m_roll * m_pitch * m_yaw } -#[show_image::main] -fn main() -> Result<(), Box> { - let args: Vec = env::args().collect(); - let mesh = { - let f = File::open(&args[1])?; - let mut f = BufReader::new(f); - load_mesh(&mut f)? - }; +fn render(mesh: &[Face], camera: impl Fn(Vec2) -> (Vec3, Vec3)) -> Image { let mut img = Image { w: W, h: H, data: vec![0; (3 * W * H) as usize], }; - let m_view = ypr_to_mat(vec3(135.0 * PI / 180.0, -30.0 * PI / 180.0, 0.0f32)); - let m_camera = transpose(&m_view); let img_size = vec2(W as f32, H as f32); for y in 0..H { for x in 0..W { - let img_coords: Vec2 = vec2(x as f32, y as f32); - - // perspective projection + let img_coords = vec2(x as f32, y as f32); let off = (img_coords - img_size * 0.5) / img_size.y; - let base = vec3(0.0, 0.0, -40.0); - let ray = vec3(off.x, off.y, 2.0); - - // orthographic projection - // let off = (img_coords - img_size * 0.5) / SCALE; - // let base = vec3(off.x, off.y, -10.0); - // let ray = vec3(0.0, 0.0, 1.0); - - let base = m_camera * base; - let ray = m_camera * normalize(ray); + let (base, ray) = camera(off); let mut dist = f32::INFINITY; - - for f in &mesh { + for f in mesh { let color = clamp(to_ivec3(f.normal * 120.0 + 128.0), ivec3(0, 0, 0), ivec3(255, 255, 255)); let fs = (0..3).map(|k| edge_dist(f.vertices[k], f.vertices[(k + 1) % 3], base, ray)); if fs.into_iter().all(|f| f >= 0.0) { @@ -110,6 +89,30 @@ fn main() -> Result<(), Box> { } } } + img +} + +#[show_image::main] +fn main() -> Result<(), Box> { + let args: Vec = env::args().collect(); + let mesh = { + let f = File::open(&args[1])?; + let mut f = BufReader::new(f); + load_mesh(&mut f)? + }; + let m_view = ypr_to_mat(vec3(135.0 * PI / 180.0, -30.0 * PI / 180.0, 0.0f32)); + let m_camera = transpose(&m_view); + let img = render(mesh.as_slice(), |off| { + // perspective projection + let base = vec3(0.0, 0.0, -40.0); + let ray = vec3(off.x, off.y, 2.0); + + // orthographic projection + // let base = vec3(off.x, off.y, -10.0); + // let ray = vec3(0.0, 0.0, 1.0); + + (m_camera * base, m_camera * ray) + }); let window = show_image::create_window("Raytracing", WindowOptions::default())?; let image = ImageView::new(ImageInfo::rgb8(W as u32, H as u32), img.data());