Added command line parsing and PPM image writing.

Also the beginnings of a Ray struct.
This commit is contained in:
Nathan Vegdahl 2015-12-27 00:13:35 -08:00
parent e239f5aaaf
commit 3f614f3728
5 changed files with 222 additions and 1 deletions

60
Cargo.lock generated
View File

@ -1,4 +1,64 @@
[root]
name = "psychopath"
version = "0.1.0"
dependencies = [
"docopt 0.6.78 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "aho-corasick"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "docopt"
version = "0.6.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"regex 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc-serialize"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "strsim"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"

View File

@ -2,3 +2,7 @@
name = "psychopath"
version = "0.1.0"
authors = ["Nathan Vegdahl <cessen@cessen.com>"]
[dependencies]
docopt = "0.6"
rustc-serialize = "0.3"

83
src/image.rs Normal file
View File

@ -0,0 +1,83 @@
#![allow(dead_code)]
use std::io;
use std::io::Write;
use std::path::Path;
use std::fs::File;
#[derive(Debug, Clone)]
pub struct Image {
data: Vec<(u8, u8, u8)>,
res: (usize, usize),
}
impl Image {
pub fn new(width: usize, height: usize) -> Image {
Image {
data: vec![(0,0,0); width * height],
res: (width, height),
}
}
pub fn width(&self) -> usize {
self.res.0
}
pub fn height(&self) -> usize {
self.res.1
}
pub fn get(&self, x: usize, y: usize) -> (u8, u8, u8) {
assert!(x < self.res.0);
assert!(y < self.res.1);
self.data[self.res.0 * y + x]
}
pub fn set(&mut self, x: usize, y: usize, value: (u8, u8, u8)) {
assert!(x < self.res.0);
assert!(y < self.res.1);
self.data[self.res.0 * y + x] = value;
}
pub fn write_ascii_ppm(&self, path: &Path) -> io::Result<()> {
// Open file.
let mut f = io::BufWriter::new(try!(File::create(path)));
// Write header
try!(write!(f, "P3\n{} {}\n255\n", self.res.0, self.res.1));
// Write pixels
for y in 0..self.res.1 {
for x in 0..self.res.0 {
let (r, g, b) = self.get(x, y);
try!(write!(f, "{} {} {} ", r, g, b));
}
try!(write!(f, "\n"));
}
// Done
Ok(())
}
pub fn write_binary_ppm(&self, path: &Path) -> io::Result<()> {
// Open file.
let mut f = io::BufWriter::new(try!(File::create(path)));
// Write header
try!(write!(f, "P6\n{} {}\n255\n", self.res.0, self.res.1));
// Write pixels
for y in 0..self.res.1 {
for x in 0..self.res.0 {
let (r, g, b) = self.get(x, y);
let d = [r, g, b];
try!(f.write_all(&d));
}
}
// Done
Ok(())
}
}

View File

@ -1,7 +1,58 @@
extern crate rustc_serialize;
extern crate docopt;
mod math;
mod lerp;
mod float4;
mod ray;
mod image;
use std::path::Path;
use docopt::Docopt;
use image::Image;
// ----------------------------------------------------------------
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const USAGE: &'static str = r#"
Psychopath <VERSION>
Usage:
psychopath <imgpath>
psychopath (-h | --help)
psychopath --version
Options:
-h --help Show this screen.
--version Show version.
"#;
#[derive(Debug, RustcDecodable)]
struct Args {
arg_imgpath: String,
flag_version: bool,
}
// ----------------------------------------------------------------
fn main() {
println!("Hello, world!");
// Parse command line arguments.
let args: Args = Docopt::new(USAGE.replace("<VERSION>", VERSION))
.and_then(|d| d.decode())
.unwrap_or_else(|e| e.exit());
// Print version and exit if requested.
if args.flag_version {
println!("Psychopath {}", VERSION);
return;
}
// Write output image
let mut img = Image::new(512, 512);
img.set(256, 256, (255, 255, 255));
let _ = img.write_binary_ppm(Path::new(&args.arg_imgpath));
}

23
src/ray.rs Normal file
View File

@ -0,0 +1,23 @@
#![allow(dead_code)]
use math::{Vector, Point, Matrix4x4};
#[derive(Debug, Copy, Clone)]
pub struct Ray {
pub orig: Point,
pub dir: Vector,
}
impl Ray {
pub fn new(orig: Point, dir: Vector) -> Ray {
Ray {
orig: orig,
dir: dir,
}
}
pub fn transform(&mut self, mat: &Matrix4x4) {
self.orig = self.orig * *mat;
self.dir = self.dir * *mat;
}
}