diff --git a/ria-weekend/Cargo.lock b/ria-weekend/Cargo.lock index 54777c4..175f897 100644 --- a/ria-weekend/Cargo.lock +++ b/ria-weekend/Cargo.lock @@ -1,4 +1,249 @@ +[[package]] +name = "autocfg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.50" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-iter" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_jitter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ria-weekend" version = "0.1.0" +dependencies = [ + "sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)", +] +[[package]] +name = "sdl2" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sdl2-sys" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" +"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" +"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" +"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" +"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" +"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" +"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebf85f207d42e4da59fa31fff977be5ff0b224873506c4bd70cc1c94b331593" +"checksum sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e82803e85c2e6178d28886cef25b2c53afc2eecaeff739f2247f23ed3352e6c1" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/ria-weekend/Cargo.toml b/ria-weekend/Cargo.toml index 8505789..91ec00e 100644 --- a/ria-weekend/Cargo.toml +++ b/ria-weekend/Cargo.toml @@ -5,3 +5,4 @@ authors = ["ishanjain28 "] edition = "2018" [dependencies] +sdl2 = "*" diff --git a/ria-weekend/examples/ray_demo.rs b/ria-weekend/examples/ray_demo.rs index 3dd3a78..b0b7ba9 100644 --- a/ria-weekend/examples/ray_demo.rs +++ b/ria-weekend/examples/ray_demo.rs @@ -1,12 +1,15 @@ extern crate ria_weekend; +extern crate sdl2; use ria_weekend::{demo::Demo, ray, ray::Ray, vec3::Vec3}; +use sdl2::{pixels, rect::Rect}; fn main() { - let demo = Demo::new("ray_demo"); - let dimensions = demo.dimensions(); + let (width, height): (usize, usize) = (500, 500); + let mut demo = Demo::new("ray_demo", width, height).expect("error occurred"); + + let texture_creator = demo.canvas.texture_creator(); - let mut buf = String::new(); // linear interpolation based on y coordinate // top to down let linear_interpolate_y = |ray: Ray| -> Vec3 { @@ -15,8 +18,21 @@ fn main() { // (1.0 - t) * start blend_color + t * end color Vec3::new(1.0, 1.0, 1.0) * (1.0 - t) + Vec3::new(0.0, 0.0, 0.0) * t }; + let mut texture = texture_creator + .create_texture_streaming(pixels::PixelFormatEnum::RGB888, width as u32, height as u32) + .map_err(|e| e.to_string()) + .expect("error in creating texture"); + let mut buf = Vec::new(); + ray::create_ray_demo( + &mut buf, + (width as u32, height as u32), + linear_interpolate_y, + ); - ray::create_ray_demo(&mut buf, dimensions, linear_interpolate_y); + texture.update(Rect::new(0, 0, width as u32, height as u32), &buf, 20); - demo.save_as_ppm(buf); + demo.canvas.copy(&texture, None, None).unwrap(); + demo.canvas.present(); + demo.save_as_ppm(&buf); + demo.start().unwrap(); } diff --git a/ria-weekend/examples/sphere.rs b/ria-weekend/examples/sphere.rs deleted file mode 100644 index bd734d0..0000000 --- a/ria-weekend/examples/sphere.rs +++ /dev/null @@ -1,46 +0,0 @@ -extern crate ria_weekend; - -use ria_weekend::{demo::Demo, ray, ray::Ray, vec3::Vec3}; - -fn main() { - let demo = Demo::new("single_sphere_demo"); - let dimensions = demo.dimensions(); - - let mut buf = String::new(); - // linear interpolation based on y coordinate - // top to down - let color = |ray: Ray| -> Vec3 { - // center at z=-1. xy axis cuts sphere in half - if ray_hit_sphere(Vec3::new(0.0, 0.0, -1.0), 0.5, &ray) { - // For all rays that hit sphere, return red color - // This will result in a sphere that is red in color - return Vec3::new(1.0, 0.0, 0.0); - } - let unit_direction = ray.direction().unit_vector(); - // For rays that don't hit sphere, It'll paint the gradient as the background - // Linear gradient depends on y - let t = 0.5 * (unit_direction.y() + 1.0); - - // start color + end color - Vec3::new(1.0, 1.0, 1.0) * (1.0 - t) + Vec3::new(0.0, 0.0, 0.0) * t - }; - - ray::create_ray_demo(&mut buf, dimensions, color); - - demo.save_as_ppm(buf); -} - -fn ray_hit_sphere(center: Vec3, radius: f32, ray: &Ray) -> bool { - // dot(A + t*B - C, A + t*B - C) = R*R - // when expanded we get - // t * t * dot(B, B) + 2 * t * dot(B, A-C) + dot(A-C, A-C) - R*R = 0 - - // A-C - let ac = ray.origin() - center; - let a = ray.direction().dot(&ray.direction()); - let b = 2.0 * ac.dot(&ray.direction()); - let c = ac.dot(&ac) - radius * radius; - let discriminant = b * b - 4.0 * a * c; - - discriminant > 0.0 -} diff --git a/ria-weekend/src/demo.rs b/ria-weekend/src/demo.rs index 798819e..0832ccb 100644 --- a/ria-weekend/src/demo.rs +++ b/ria-weekend/src/demo.rs @@ -1,61 +1,91 @@ +extern crate sdl2; + +use sdl2::{ + event::Event, + keyboard::Keycode, + pixels::PixelFormatEnum, + rect::Rect, + render::{Canvas, Texture, TextureValueError}, + video::Window, + EventPump, Sdl, +}; use std::error::Error; use std::fs::File; use std::{io, io::Write}; -#[derive(Debug)] -pub struct Demo { - width: u32, - height: u32, - file_name: String, +pub struct Demo<'a> { + pub width: usize, + pub height: usize, + pub project_name: &'a str, + pub canvas: Canvas, + pub sdl_ctx: Sdl, } -impl Demo { - pub fn new(file_name: &str) -> Demo { - let mut height = 100; - let mut width = 200; +impl<'a> Demo<'a> { + pub fn new(project_name: &str, width: usize, height: usize) -> Result { + let sdl_ctx = sdl2::init()?; + let video_subsys = sdl_ctx.video()?; - println!("Enter width and height seperated by space"); + let window = video_subsys + .window(project_name, width as u32, height as u32) + .position_centered() + .build() + .map_err(|e| e.to_string())?; + let mut canvas = window + .into_canvas() + .target_texture() + .build() + .map_err(|e| e.to_string())?; - let mut input = String::new(); - io::stdin() - .read_line(&mut input) - .expect("error in reading input"); - - let input = input - .trim() - .split(" ") - .map(|v| v.parse::().expect("error in parsing input")) - .collect::>(); - - if input.len() >= 2 { - height = input[1]; - width = input[0]; - } - let file_name = format!("{}-{}x{}.ppm", file_name, width, height); - - Demo { + Ok(Demo { width, height, - file_name, - } + canvas, + project_name, + sdl_ctx, + }) } - pub fn save_as_ppm(&self, buf: String) { + pub fn save_as_ppm(&self, buf: &[u8]) { let mut header = format!("P3\n{} {}\n255\n", self.width, self.height); - let mut file = match File::create(&self.file_name) { + let mut file = match File::create(&format!( + "{}-{}x{}.ppm", + self.project_name, self.width, self.height + )) { Ok(file) => file, - Err(e) => panic!("couldn't create {}: {}", self.file_name, e.description()), + Err(e) => panic!("couldn't create {}: {}", self.project_name, e.description()), }; file.write(header.as_bytes()) .expect("error in writing file header"); - match file.write_all(buf.as_bytes()) { - Ok(_) => println!("Succesfully wrote to {}", self.file_name), - Err(e) => panic!("couldn't write to {}: {}", self.file_name, e.description()), + match file.write_all(&buf) { + Ok(_) => println!("Succesfully wrote to {}", self.project_name), + Err(e) => panic!( + "couldn't write to {}: {}", + self.project_name, + e.description() + ), } } - pub fn dimensions(&self) -> (u32, u32) { + pub fn start(&mut self) -> Result<(), String> { + let mut event_pump = self.sdl_ctx.event_pump()?; + + loop { + for event in event_pump.poll_iter() { + match event { + Event::Quit { .. } + | Event::KeyDown { + keycode: Some(Keycode::Escape), + .. + } => return Ok(()), + _ => {} + }; + } + } + } + + pub fn dimensions(&self) -> (usize, usize) { (self.width, self.height) } } diff --git a/ria-weekend/src/lib.rs b/ria-weekend/src/lib.rs index acab4a1..ba1572e 100644 --- a/ria-weekend/src/lib.rs +++ b/ria-weekend/src/lib.rs @@ -2,4 +2,4 @@ pub mod ppm; pub mod vec3; pub mod ray; pub mod demo; - +pub mod stage; diff --git a/ria-weekend/src/ray.rs b/ria-weekend/src/ray.rs index 4304619..8fb1495 100644 --- a/ria-weekend/src/ray.rs +++ b/ria-weekend/src/ray.rs @@ -20,7 +20,7 @@ impl Ray { } } -pub fn create_ray_demo(buf: &mut String, dimensions: (u32, u32), op: F) +pub fn create_ray_demo(buf: &mut Vec, dimensions: (u32, u32), op: F) where F: Fn(Ray) -> Vec3, { @@ -44,11 +44,10 @@ where let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v); let color = op(ray); - let ir = (255.99 * color[0]) as u32; - let ig = (255.99 * color[1]) as u32; - let ib = (255.99 * color[2]) as u32; - let output = format!("{} {} {}\n", ir, ig, ib); - buf.push_str(&output); + let ir = (255.99 * color[0]) as u8; + let ig = (255.99 * color[1]) as u8; + let ib = (255.99 * color[2]) as u8; + buf.extend([ir, ig, ib].iter()); } } }