Skip to content

Commit

Permalink
feat(demo): add demo subcommand
Browse files Browse the repository at this point in the history
WARNING: this is **only** a preview of what the real
subcommand `render` will do. So no documentation or
optimization upgrade needed for these files
  • Loading branch information
andros21 committed May 4, 2022
1 parent 2c663b6 commit 35fbd1e
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 1 deletion.
82 changes: 82 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const FACTOR: &str = "0.2";
/// When no arguments are provided to `--gamma` flag of `convert` subcommand.
const GAMMA: &str = "1.0";

const WIDTH: &str = "640";
const HEIGHT: &str = "480";
const ANGLE_DEG: &str = "0.0";

/// Build a [`clap::Command`](https://docs.rs/clap/latest/clap/type.Command.html)
/// for [`rustracer`](..) crate.
pub fn build_cli() -> Command<'static> {
Expand Down Expand Up @@ -69,6 +73,84 @@ pub fn build_cli() -> Command<'static> {
.help("Gamma parameter")
.long_help("Gamma transfer function parameter"),
),
)
.subcommand(
Command::new("demo")
.arg_required_else_help(true)
.dont_collapse_args_in_usage(true)
.about("Render subcommand demo (devel in progress)")
.arg(
Arg::new("OUTPUT")
.required(true)
.help("Output image")
.long_help("Output ldr image (ff|png) file path"),
)
.arg(
Arg::new("verbose")
.short('v')
.long("verbose")
.help("Print stdout information")
.long_help("Print stdout information"),
)
.arg(
Arg::new("output-pfm")
.long("output-pfm")
.help("Output also hdr image")
.long_help("Output also pfm file in combination with (ff|png) file"),
)
.arg(
Arg::new("orthogonal")
.long("orthogonal")
.help("Use orthogonal camera instead of perspective camera")
.long_help("Render image with orthogonal view of the scene"),
)
.arg(
Arg::new("width")
.long("width")
.value_name("WIDTH")
.default_value(WIDTH)
.number_of_values(1)
.help("Image width")
.long_help("Width of the image to render"),
)
.arg(
Arg::new("height")
.long("height")
.value_name("HEIGHT")
.default_value(HEIGHT)
.number_of_values(1)
.help("Image height")
.long_help("Height of the image to render"),
)
.arg(
Arg::new("angle-deg")
.long("angle-deg")
.value_name("angle-deg")
.default_value(ANGLE_DEG)
.number_of_values(1)
.help("View angle (in degrees)")
.long_help("Render the image with this angle (in degrees) of view"),
)
.arg(
Arg::new("factor")
.short('f')
.long("factor")
.value_name("FACTOR")
.default_value(FACTOR)
.number_of_values(1)
.help("Normalization factor")
.long_help("Luminosity normalization factor"),
)
.arg(
Arg::new("gamma")
.short('g')
.long("gamma")
.value_name("GAMMA")
.default_value(GAMMA)
.number_of_values(1)
.help("Gamma parameter")
.long_help("Gamma transfer function parameter"),
),
);

cli
Expand Down
10 changes: 10 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,13 @@ pub enum GeometryErr {
#[error("object with norm {0} can't be normalized")]
UnableToNormalize(f32),
}

#[derive(Error, Debug)]
pub enum DemoErr {
#[error("invalid {1}, expected floating-point number: {0}")]
IntParseFailure(#[source] std::num::ParseIntError, String),
#[error("invalid {1}, expected floating-point number: {0}")]
FloatParseFailure(#[source] std::num::ParseFloatError, String),
#[error("{0}")]
IoError(#[source] HdrImageErr),
}
85 changes: 84 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,17 @@ use std::path::Path;
use std::process::exit;
use std::str::FromStr;

use crate::error::ConvertErr;
use crate::camera::{OrthogonalCamera, PerspectiveCamera};
use crate::color::{BLACK, WHITE};
use crate::error::{ConvertErr, DemoErr};
use crate::hdrimage::{HdrImage, Luminosity};
use crate::imagetracer::ImageTracer;
use crate::misc::ByteOrder;
use crate::render::OnOffRenderer;
use crate::shape::Sphere;
use crate::transformation::{rotation_z, scaling, translation};
use crate::vector::Vector;
use crate::world::World;

/// Crate main function.
///
Expand All @@ -40,6 +49,13 @@ fn main() {
exit(1)
}
},
Some("demo") => match demo(cli_m.subcommand_matches("demo").unwrap()) {
Ok(()) => exit(0),
Err(e) => {
eprintln!("[error] {:#}", e);
exit(1)
}
},
_ => exit(1),
}
}
Expand Down Expand Up @@ -68,3 +84,70 @@ fn convert(sub_m: &clap::ArgMatches) -> Result<(), ConvertErr> {
}
Ok(())
}

fn demo(sub_m: &clap::ArgMatches) -> Result<(), DemoErr> {
let ldr_file = Path::new(sub_m.value_of("OUTPUT").unwrap());
let factor = f32::from_str(sub_m.value_of("factor").unwrap())
.map_err(|e| DemoErr::FloatParseFailure(e, String::from("factor")))?;
let gamma = f32::from_str(sub_m.value_of("gamma").unwrap())
.map_err(|e| DemoErr::FloatParseFailure(e, String::from("gamma")))?;
let width = u32::from_str(sub_m.value_of("width").unwrap())
.map_err(|e| DemoErr::IntParseFailure(e, String::from("width")))?;
let height = u32::from_str(sub_m.value_of("height").unwrap())
.map_err(|e| DemoErr::IntParseFailure(e, String::from("height")))?;
let angle_deg = f32::from_str(sub_m.value_of("angle-deg").unwrap())
.map_err(|e| DemoErr::FloatParseFailure(e, String::from("angle-deg")))?;
let mut hdr_img = HdrImage::new(width, height);
if sub_m.is_present("verbose") {
println!("[info] generating an image ({}, {})", width, height);
}
let mut world = World::default();
for x in [-0.5, 0.5].into_iter() {
for y in [-0.5, 0.5].into_iter() {
for z in [-0.5, 0.5].into_iter() {
world.add(Box::new(Sphere::new(
translation(Vector::from((x, y, z))) * scaling(Vector::from((0.1, 0.1, 0.1))),
)));
}
}
}
world.add(Box::new(Sphere::new(
translation(Vector::from((0.0, 0.0, -0.5))) * scaling(Vector::from((0.1, 0.1, 0.1))),
)));
world.add(Box::new(Sphere::new(
translation(Vector::from((0.0, 0.5, 0.0))) * scaling(Vector::from((0.1, 0.1, 0.1))),
)));
let camera_tr =
rotation_z(f32::to_radians(angle_deg)) * translation(Vector::from((-1.0, 0.0, 0.0)));
if sub_m.is_present("orthogonal") {
let mut tracer = ImageTracer::new(
&mut hdr_img,
OrthogonalCamera::new(width as f32 / height as f32, camera_tr),
);
tracer.fire_all_rays(OnOffRenderer::new(&world, BLACK, WHITE));
} else {
let mut tracer = ImageTracer::new(
&mut hdr_img,
PerspectiveCamera::new(1.0, width as f32 / height as f32, camera_tr),
);
tracer.fire_all_rays(OnOffRenderer::new(&world, BLACK, WHITE));
}
if sub_m.is_present("output-pfm") {
let hdr_file = ldr_file.with_extension("").with_extension("pfm");
hdr_img
.write_pfm_file(&hdr_file, ByteOrder::LittleEndian)
.map_err(DemoErr::IoError)?;
if sub_m.is_present("verbose") {
println!("[info] {:?} has been written to disk", hdr_file);
}
}
hdr_img.normalize_image(factor, Luminosity::AverageLuminosity);
hdr_img.clamp_image();
hdr_img
.write_ldr_file(ldr_file, gamma)
.map_err(DemoErr::IoError)?;
if sub_m.is_present("verbose") {
println!("[info] {:?} has been written to disk", ldr_file);
}
Ok(())
}

0 comments on commit 35fbd1e

Please sign in to comment.