extern crate mat4; extern crate vec3; extern crate vec4; 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. / 800.), &(0.1), &(1000.), ); // let view_matrix: [f64; 16] = *mat4::translate( // &mut mat4::new_identity(), // &mat4::new_identity(), // &vec3::new(0., 0., -10.), // ); let mut view_matrix = mat4::new_zero(); // view_matrix[0] = 1.; // view_matrix[4] = 0.; // view_matrix[8] = 0.; // view_matrix[12] = 0.; // view_matrix[1] = 0.; // view_matrix[5] = 1.; // view_matrix[9] = 0.; // view_matrix[13] = 0.; // view_matrix[2] = 0.; // view_matrix[6] = 0.; // view_matrix[10] = 1.; // view_matrix[14] = 0.; // view_matrix[3] = 0.; // view_matrix[7] = 0.; // view_matrix[11] = -10.; // view_matrix[15] = 1.; view_matrix[0] = 1.; view_matrix[1] = 0.; view_matrix[2] = 0.; view_matrix[3] = 0.; view_matrix[4] = 0.; view_matrix[5] = 1.; view_matrix[6] = 0.; view_matrix[7] = 0.; view_matrix[8] = 0.; view_matrix[9] = 0.; view_matrix[10] = 1.; view_matrix[11] = 0.; view_matrix[12] = 0.; view_matrix[13] = 0.; view_matrix[14] = 10.; view_matrix[15] = 1.; let _model_matrix: [f64; 16] = *mat4::rotate_y( &mut mat4::new_identity(), mat4::translate( &mut mat4::new_identity(), &mat4::new_identity(), &vec3::new(0.5, 0.5, 0.), ), &(3.141592 / 4.), ); let _model_matrix: [f64; 16] = *mat4::translate( &mut mat4::new_identity(), mat4::rotate_y( &mut mat4::new_identity(), &mat4::new_identity(), &(3.141592 / 4.), ), &vec3::new(0.5, 0.5, 0.), ); let _model_matrix: [f64; 16] = *mat4::translate( &mut mat4::new_identity(), &mat4::new_identity(), &vec3::new(0.5, 0.5, 0.), ); let _model_matrix: [f64; 16] = *mat4::rotate_y( &mut mat4::new_identity(), &mat4::new_identity(), &(3.141592 / 40.), ); let _model_matrix: [f64; 16] = *mat4::rotate_y(&mut mat4::new_identity(), &mat4::new_identity(), &0.03); let model_matrix: [f64; 16] = *mat4::scale( &mut mat4::new_zero(), mat4::rotate_y( &mut mat4::new_zero(), mat4::translate( &mut mat4::new_zero(), &mat4::new_identity(), &vec3::new(0., 0., 0.), ), &(3.141592 / 4.), ), &vec3::new(1., 1., 1.), ); // let model_matrix: [f64; 16] = *mat4::scale( // &mut mat4::new_zero(), // mat4::translate( // &mut mat4::new_zero(), // &mat4::new_identity(), // &vec3::new(0.5, 0.5, 0.), // ), // &vec3::new(1., 2., 1.), // ); // let model_matrix = mat4::new_identity(); for x in 0..800 { for y in 0..800 { let mut view_projection_matrix = mat4::new_zero(); mat4::mul(&mut view_projection_matrix, &model_matrix, &view_matrix); let mut model_view_projection_matrix = mat4::new_zero(); mat4::mul( &mut model_view_projection_matrix, &view_projection_matrix, &projection_matrix, ); let mut inverse_view_projection_matrix = mat4::new_zero(); mat4::inv( &mut inverse_view_projection_matrix, &model_view_projection_matrix, ); let far = vec4::new((x as f64 - 400.) / 400., (y as f64 - 400.) / 400., 1., 0.); let near = vec4::new((x as f64 - 400.) / 400., (y as f64 - 400.) / 400., 0., 0.); let mut new_far = vec4::new_zero(); let mut new_near = vec4::new_zero(); vec4::transform_mat4(&mut new_far, &far, &inverse_view_projection_matrix); vec4::transform_mat4(&mut new_near, &near, &inverse_view_projection_matrix); new_far[0] /= new_far[3]; new_far[1] /= new_far[3]; new_far[2] /= new_far[3]; new_far[3] /= new_far[3]; new_near[0] /= new_near[3]; new_near[1] /= new_near[3]; new_near[2] /= new_near[3]; new_near[3] /= new_near[3]; // let mut ray = Ray { // origin: [view_matrix[3], view_matrix[7], view_matrix[11]], // direction: [ // new_far[0] - new_near[0], // new_far[1] - new_near[1], // new_far[2] - new_near[2], // ], // }; let mut ray = Ray { origin: [view_matrix[12], view_matrix[13], view_matrix[14]], direction: [ new_far[0] - new_near[0], new_far[1] - new_near[1], new_far[2] - new_near[2], ], }; let scalar = (ray.direction[0].powi(2) + ray.direction[1].powi(2) + ray.direction[2].powi(2)) .sqrt(); ray.direction = [ ray.direction[0] / scalar, ray.direction[1] / scalar, ray.direction[2] / scalar, ]; if x == 0 && y == 0 { println!("{:?}", ray); } // 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. * 0.9 + 0.1 * 255.) as u8, g: (diffuse * 255. * 0.9 + 0.1 * 255.) as u8, b: (diffuse * 255. * 0.9 + 0.1 * 255.) as u8, a: 0, }, ); } None => { put_pixel( &mut *data, x, y, Color { r: 0, g: 0, b: 0, a: 0, }, ); } } } } }