Added sdl2. Changed buffer type from String to Vec<u8> and refactored demo.rs

This commit is contained in:
Ishan Jain 2019-03-05 23:10:46 +05:30
parent a1f040d307
commit 21b7439098
7 changed files with 340 additions and 95 deletions

245
ria-weekend/Cargo.lock generated
View File

@ -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"

View File

@ -5,3 +5,4 @@ authors = ["ishanjain28 <ishanjain28@gmail.com>"]
edition = "2018"
[dependencies]
sdl2 = "*"

View File

@ -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();
}

View File

@ -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
}

View File

@ -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<Window>,
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<Demo, String> {
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::<u32>().expect("error in parsing input"))
.collect::<Vec<u32>>();
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)
}
}

View File

@ -2,4 +2,4 @@ pub mod ppm;
pub mod vec3;
pub mod ray;
pub mod demo;
pub mod stage;

View File

@ -20,7 +20,7 @@ impl Ray {
}
}
pub fn create_ray_demo<F>(buf: &mut String, dimensions: (u32, u32), op: F)
pub fn create_ray_demo<F>(buf: &mut Vec<u8>, 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());
}
}
}