diff --git a/src/main.rs b/src/main.rs index 47cc2aa..9da117c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,17 @@ extern crate sdl2; +mod object; +mod ray; +mod render; +mod sphere; + +use render::render; use sdl2::event::Event; use sdl2::keyboard::Keycode; -use sdl2::pixels::Color; use sdl2::pixels::PixelFormatEnum; use sdl2::surface::Surface; use std::time::Duration; -fn put_pixel(data: &mut [u8], x: usize, y: usize, color: Color) { - data[y * 3 * 800 + x * 3] = color.r; - data[y * 3 * 800 + x * 3 + 1] = color.g; - data[y * 3 * 800 + x * 3 + 2] = color.b; -} - fn main() { let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); @@ -34,20 +33,21 @@ fn main() { let mut event_pump = sdl_context.event_pump().unwrap(); let mut i = 0; 'running: loop { - put_pixel( - &mut *data, - i, - i, - Color { - r: 0, - g: 0, - b: 0, - a: 0, - }, - ); - if i < 599 { - i += 1; - } + render(&mut *data); + // put_pixel( + // &mut *data, + // i, + // i, + // Color { + // r: 0, + // g: 0, + // b: 0, + // a: 0, + // }, + // ); + // if i < 599 { + // i += 1; + // } // canvas.set_draw_color(Color::RGB(i, 64, 255 - i)); let surface = Surface::from_data(&mut *data, 800, 600, 2400, PixelFormatEnum::RGB24).unwrap(); diff --git a/src/object.rs b/src/object.rs index 08b1491..c9b41e6 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,4 +1,4 @@ -use super::Ray; +use super::ray::Ray; pub trait Object { fn get_intersection(&self, ray: Ray) -> Option; diff --git a/src/ray.rs b/src/ray.rs index 94a8304..7432011 100644 --- a/src/ray.rs +++ b/src/ray.rs @@ -1,3 +1,4 @@ +#[derive(Clone, Copy)] pub struct Ray { pub origin: [f64; 3], pub direction: [f64; 3], diff --git a/src/render.rs b/src/render.rs new file mode 100644 index 0000000..278bc45 --- /dev/null +++ b/src/render.rs @@ -0,0 +1,92 @@ +extern crate mat4; +extern crate vec3; + +use crate::object::Object; +use crate::ray::Ray; +use crate::sphere::Sphere; +use sdl2::pixels::Color; + +struct Camera { + rv: [f64; 3], + uv: [f64; 3], +} + +fn put_pixel(data: &mut [u8], x: usize, y: usize, color: Color) { + data[y * 3 * 800 + x * 3] = color.r; + data[y * 3 * 800 + x * 3 + 1] = color.g; + data[y * 3 * 800 + x * 3 + 2] = color.b; +} + +pub fn render(data: &mut [u8]) { + let sphere = Sphere {}; + let projection_matrix: [f64; 16] = *mat4::perspective( + &mut mat4::new_zero(), + &(45. * 3.141592 / 180.), + &(800. / 600.), + &(0.1), + &(1000.), + ); + let view_matrix: [f64; 16] = *mat4::translate( + &mut mat4::new_identity(), + &mat4::new_identity(), + &vec3::new(0., 0., -10.), + ); + let model_matrix: [f64; 16] = *mat4::translate( + &mut mat4::new_identity(), + &mat4::new_identity(), + &vec3::new(1., 1., 0.), + ); + let camera = Camera { + rv: [1., 0., 0.], + uv: [0., 1., 0.], + }; + for x in 0..800 { + for y in 0..600 { + let mut ray = Ray { + origin: [0., 0., 0.], + direction: [0., 0., 1.], + }; + ray.direction[0] += (x as f64 - 400.) / 800.; + ray.direction[1] += (y as f64 - 300.) / 800.; + let mut n = + ray.direction[0].powi(2) + ray.direction[1].powi(2) + ray.direction[2].powi(2); + n = n.sqrt(); + ray.direction[0] /= n; + ray.direction[1] /= n; + ray.direction[2] /= n; + let ray2 = Box::clone(&Box::new(ray)); + // vec3::transform_mat4(&mut ray.direction, &ray2.direction, &projection_matrix); + vec3::transform_mat4(&mut ray.origin, &ray2.origin, &view_matrix); + let ray2 = Box::clone(&Box::new(ray)); + vec3::transform_mat4(&mut ray.origin, &ray2.origin, &model_matrix); + match sphere.get_intersection(ray) { + Some(v) => { + put_pixel( + &mut *data, + x, + y, + Color { + r: 255, + g: 0, + b: 0, + a: 0, + }, + ); + } + None => { + put_pixel( + &mut *data, + x, + y, + Color { + r: 0, + g: 0, + b: 0, + a: 0, + }, + ); + } + } + } + } +} diff --git a/src/sphere.rs b/src/sphere.rs index 581a299..11a560f 100644 --- a/src/sphere.rs +++ b/src/sphere.rs @@ -1,8 +1,8 @@ extern crate vec3; -use super::Object; -use super::Ray; +use super::object::Object; +use super::ray::Ray; -struct Sphere {} +pub struct Sphere {} fn return_min(root1: f64, root2: f64) -> Option { if root1 < root2 && root1 > 0. {