use obrah::data::*;
use obrah::kernel::*;
use obrah::runtime::*;
use std::fs::File;
use std::io;
use std::io::Write;
fn save_ppm(
path: &str,
width: usize,
height: usize,
pixels: &[f32],
) -> Result<(), Box<dyn std::error::Error>> {
println!("Beginning file write...");
let mut file = File::create(path)?; write!(file, "P6\n{} {}\n65535\n", width, height)?;
for chunk in pixels.chunks_exact(4) {
let r = (chunk[0].clamp(0.0, 1.0) * 65535.0) as u16;
let g = (chunk[1].clamp(0.0, 1.0) * 65535.0) as u16;
let b = (chunk[2].clamp(0.0, 1.0) * 65535.0) as u16;
file.write_all(&r.to_be_bytes())?; file.write_all(&g.to_be_bytes())?; file.write_all(&b.to_be_bytes())?; }
println!("Finished writing file!");
Ok(())
}
fn read_input(inputmsg: &str) -> f32 {
let mut input = String::new();
println!("{inputmsg}");
std::io::stdin()
.read_line(&mut input)
.expect("Failed reading input");
let trimmed = input.trim();
return match trimmed.parse::<f32>() {
Ok(val) => val,
Err(_) => panic!("Please enter a valid float."),
};
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
const WIDTH: usize = 1000;
const HEIGHT: usize = 1000;
let mut env = Env::new(0, 0)?; env.use_kernel("examples/raytrace_kernel.cl")?
.program()?
.make_kernel("raytrace")?;
let mut data = vec![0.0f32; WIDTH * HEIGHT * 4]; let mut data_buf = Buffer::new(&mut env, &data);
let mut input = String::new();
println!("Custom settings? (y/N)");
io::stdin()
.read_line(&mut input)
.expect("Failed reading input");
input = input.trim().to_string();
let mut sphere = [500.0f32, 500.0, 100.0, 300.0];
let mut light = [500.0f32, 300.0, 500.0];
if input.to_lowercase() == String::from("y") {
let sphere_x = read_input("Enter sphere x: ");
let sphere_y = read_input("Enter sphere y: ");
let sphere_z = read_input("Enter sphere z: ");
let sphere_rad = read_input("Enter sphere radius: ");
sphere = [sphere_x, sphere_y, sphere_z, sphere_rad];
let light_x = read_input("Enter light x: ");
let light_y = read_input("Enter light y: ");
let light_z = read_input("Enter light z: ");
light = [light_x, light_y, light_z];
}
setarg(&env, &data_buf, 0); setarg_scalar(&env, &WIDTH, 1); setarg_scalar(&env, &HEIGHT, 2); setarg_scalar(&env, &sphere, 3); setarg_scalar(&env, &light, 4);
println!("Starting kernel execution...");
run_kernel(&mut env, WIDTH, HEIGHT); println!("Kernel execution finished.");
data_buf.from(&mut data, &mut env);
save_ppm("out.ppm", WIDTH, HEIGHT, &data).unwrap();
println!("Output saved.");
Ok(())
}