extern crate mat4; extern crate vec3; use crate::object::Object; use crate::ray::Ray; use crate::sphere::Sphere; use sdl2::pixels::Color; 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.), ); 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); let ray2 = Box::clone(&Box::new(ray)); 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(dist) => { let n = [ ray.origin[0] + ray.direction[0] * dist, ray.origin[1] + ray.direction[1] * dist, ray.origin[2] + ray.direction[2] * dist, ]; let normal = sphere.get_normal(n); let light = [n[0] - 10., n[1] - 10., n[2] - 10.]; let scalar = (light[0].powi(2) + light[1].powi(2) + light[2].powi(2)).sqrt(); let light_d = [light[0] / scalar, light[1] / scalar, light[2] / scalar]; let mut diffuse = normal[0] * light_d[0] + normal[1] * light_d[1] + normal[2] * light_d[2]; if diffuse < 0. { diffuse = 0.; } put_pixel( &mut *data, x, y, Color { r: (diffuse * 255.) as u8, g: (diffuse * 255.) as u8, b: (diffuse * 255.) as u8, a: 0, }, ); } None => { put_pixel( &mut *data, x, y, Color { r: 0, g: 0, b: 0, a: 0, }, ); } } } } }