@@ 1,7 1,9 @@
use fmt;
+use getopt;
use math;
use math::random;
use os;
+use strconv;
use time;
def SAMPLES: uint = 50u;
@@ 74,27 76,73 @@ fn compute_color(scene: *hittable, r: *ray, depth: uint) color = {
return C(c.r * att.r, c.g * att.g, c.b * att.b);
};
+const help: []getopt::help = [
+ ('s', "samples", "samples per pixel"),
+ ('w', "width", "output image width"),
+ ('h', "height", "output image height"),
+ ('b', "begin_range", "beginning of range of horizontal lines to be rendered in this invocation (inclusive)"),
+ ('e', "end_range", "end of range of horizontal lines to be rendered in this invocation (exclusive)"),
+ ('S', "seed", "seed the random number generator with the given value (default 0)"),
+];
+
export fn main() void = {
- rng = math::random::init(1);
+ const cmd = getopt::parse(os::args, help...);
+ defer getopt::finish(&cmd);
+
+ let seed = 0u;
+ let samples: (uint | void) = void;
+ let width: (uint | void) = void, height: (uint | void) = void;
+ for (let i = 0z; i < len(cmd.opts); i += 1) {
+ let opt = cmd.opts[i];
+ switch (opt.0) {
+ case 's' =>
+ samples = strconv::stou(opt.1) as uint;
+ case 'w' =>
+ width = strconv::stou(opt.1) as uint;
+ case 'h' =>
+ height = strconv::stou(opt.1) as uint;
+ case 'S' =>
+ seed = strconv::stou(opt.1) as uint;
+ };
+ };
+ let samples = match (samples) {
+ case void =>
+ abort();
+ case let u: uint =>
+ yield u;
+ };
+ let width = match (width) {
+ case void =>
+ abort();
+ case let u: uint =>
+ yield u;
+ };
+ let height = match (height) {
+ case void =>
+ abort();
+ case let u: uint =>
+ yield u;
+ };
+
+ rng = math::random::init(seed);
- let width = 800z, height = 600z;
let img = image_create(width, height, C(0f64, 0f64, 0f64));
defer image_free(img);
- let max_bounce = 50u;
let from = V(13.0, 2.0, 3.0);
let at = V(0.0, 0.0, 0.0);
let c = make_camera(from, at, V(0.0, 1.0, 0.0),
- 20.0, 4.0/3.0, 0.1, 10.0);
+ 20.0, width: i64: f64 / height: i64: f64, 0.1, 10.0);
let scene = init_scene();
+ let max_bounce = 50u;
let start = time::unix(time::now(time::clock::MONOTONIC));
for (let j = 0z; j < height; j += 1) {
fmt::errorf("\rProgress: {}/{}", j, height)!;
for (let i = 0z; i < width; i += 1) {
- for (let k = 0u; k < SAMPLES; k += 1) {
+ for (let k = 0u; k < samples; k += 1) {
let u = i: int: f64;
u += random(0.0, 1.0);
u /= (width: int: f64 - 1.0);
@@ 111,5 159,5 @@ export fn main() void = {
};
let end = time::unix(time::now(time::clock::MONOTONIC));
fmt::errorf("\rDone in {} s\n", end - start)!;
- write(os::stdout, img, SAMPLES)!;
+ write(os::stdout, img, samples)!;
};