diff --git a/src/main.rs b/src/main.rs index 1141c87..f1f9c1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,9 +30,24 @@ fn main() { // let surface = Surface::from_data(&mut data, 800, 600, 3, PixelFormatEnum::RGB24).unwrap(); let texture_creator = canvas.texture_creator(); let mut event_pump = sdl_context.event_pump().unwrap(); - // let mut i = 0; + let mut i = -15; 'running: loop { - render(&mut *data); + for event in event_pump.poll_iter() { + match event { + Event::Quit { .. } + | Event::KeyDown { + keycode: Some(Keycode::Escape), + .. + } => break 'running, + _ => {} + } + } + + render(&mut *data, i); + i += 1; + if i > 15 { + i = -15 + } // put_pixel( // &mut *data, // i, @@ -56,15 +71,5 @@ fn main() { canvas.copy(&texture, None, None).unwrap(); canvas.present(); - for event in event_pump.poll_iter() { - match event { - Event::Quit { .. } - | Event::KeyDown { - keycode: Some(Keycode::Escape), - .. - } => break 'running, - _ => {} - } - } } } diff --git a/src/render.rs b/src/render.rs index 7827ec8..7d0f8ea 100644 --- a/src/render.rs +++ b/src/render.rs @@ -13,151 +13,67 @@ fn put_pixel(data: &mut [u8], x: usize, y: usize, color: Color) { data[y * 3 * 800 + x * 3 + 2] = color.b; } -pub fn render(data: &mut [u8]) { +pub fn render(data: &mut [u8], i: i32) { let sphere = Sphere {}; - let projection_matrix: [f64; 16] = *mat4::perspective( + let view_matrix = *mat4::inv( &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( + mat4::look_at( &mut mat4::new_zero(), - mat4::translate( - &mut mat4::new_zero(), - &mat4::new_identity(), - &vec3::new(0., 0., 0.), - ), + &[0., 0., 20.], + &[0., 0., 19.], + &[0., 1., 0.], + ), + ); + // let view_matrix = *mat4::look_at( + // &mut mat4::new_zero(), + // &[0., 0., 10.], + // &[0., 0., 9.], + // &[0., 1., 0.], + // ); + let scale = *mat4::scale( + &mut mat4::new_zero(), + &mat4::new_identity(), + &vec3::new(1. / 1., 1. / 3., 1. / 1.), + ); + let translate = *mat4::translate( + &mut mat4::new_zero(), + &mat4::new_identity(), + &vec3::new(-i as f64, -i as f64, 0.), + ); + let rotate = *mat4::transpose( + &mut mat4::new_zero(), + mat4::rotate( + &mut mat4::new_zero(), + &mat4::new_identity(), + &(3.141592 / 4.), + &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(); + let model_matrix_tmp = *mat4::mul(&mut mat4::new_zero(), &scale, &rotate); + let model_matrix1 = *mat4::mul(&mut mat4::new_zero(), &model_matrix_tmp, &translate); 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 pi_4: f64 = 3.141592 / 3.; + let dirx = (2. * ((x as f64 + 0.5) / 800.) - 1.) * pi_4.tan(); + let diry = (1. - 2. * ((y as f64 + 0.5) / 800.)) * pi_4.tan(); + + let scalar = (dirx.powi(2) + diry.powi(2) + 1.).sqrt(); 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], - ], + origin: [0., 0., 0.], + direction: [dirx / scalar, diry / scalar, -1. / scalar], }; + let test = ray.direction; + vec3::transform_mat4(&mut ray.direction, &test, &view_matrix); + let test = ray.direction; + vec3::transform_mat4(&mut ray.direction, &test, &model_matrix1); + let test = ray.origin; + vec3::transform_mat4(&mut ray.origin, &test, &view_matrix); + let test = ray.origin; + vec3::transform_mat4(&mut ray.origin, &test, &model_matrix1); + ray.direction[0] = ray.direction[0] - ray.origin[0]; + ray.direction[1] = ray.direction[1] - ray.origin[1]; + ray.direction[2] = ray.direction[2] - ray.origin[2]; let scalar = (ray.direction[0].powi(2) + ray.direction[1].powi(2) + ray.direction[2].powi(2)) .sqrt(); @@ -166,17 +82,17 @@ pub fn render(data: &mut [u8]) { 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 ray2 = ray; + let mut distances = Vec::new(); + distances.push(sphere.get_intersection(ray)); + distances.push(None); + let a = (distances[0], distances[1]); + match a { + (Some(dist), None) => { let n = [ ray.origin[0] + ray.direction[0] * dist, ray.origin[1] + ray.direction[1] * dist, @@ -196,14 +112,78 @@ pub fn render(data: &mut [u8]) { x, y, Color { - r: (diffuse * 255. * 0.9 + 0.1 * 255.) as u8, + r: (diffuse * 128. * 0.9 + 0.1 * 255.) as u8, + g: 0, + b: (diffuse * 255. * 0.9 + 0.1 * 255.) as u8, + a: 0, + }, + ); + } + + (None, Some(dist)) => { + let n = [ + ray2.origin[0] + ray2.direction[0] * dist, + ray2.origin[1] + ray2.direction[1] * dist, + ray2.origin[2] + ray2.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: 0, g: (diffuse * 255. * 0.9 + 0.1 * 255.) as u8, b: (diffuse * 255. * 0.9 + 0.1 * 255.) as u8, a: 0, }, ); } - None => { + (Some(dist1), Some(dist2)) => { + let n; + if dist1 < dist2 { + n = [ + ray.origin[0] + ray.direction[0] * dist1, + ray.origin[1] + ray.direction[1] * dist1, + ray.origin[2] + ray.direction[2] * dist1, + ]; + } else { + n = [ + ray2.origin[0] + ray2.direction[0] * dist2, + ray2.origin[1] + ray2.direction[1] * dist2, + ray2.origin[2] + ray2.direction[2] * dist2, + ]; + } + 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: 0, + g: (diffuse * 255. * 0.9 + 0.1 * 255.) as u8, + b: (diffuse * 255. * 0.9 + 0.1 * 255.) as u8, + a: 0, + }, + ); + } + (None, None) => { put_pixel( &mut *data, x,