From f93d215fc24f16418e7d7705534714516b1ede68 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sun, 29 Oct 2023 10:44:59 -0700 Subject: [PATCH] rtiow: add support to send rendering output to https://github.com/Tom94/tev --- rtiow/Cargo.lock | 7 ++++++ rtiow/renderer/Cargo.toml | 1 + rtiow/renderer/src/output.rs | 43 ++++++++++++++++++++++++++++++---- rtiow/renderer/src/renderer.rs | 8 +++++-- rtiow/tracer/src/main.rs | 2 +- 5 files changed, 53 insertions(+), 8 deletions(-) diff --git a/rtiow/Cargo.lock b/rtiow/Cargo.lock index 0452bdf..605ce97 100644 --- a/rtiow/Cargo.lock +++ b/rtiow/Cargo.lock @@ -2591,6 +2591,7 @@ dependencies = [ "structopt 0.2.18", "strum", "strum_macros", + "tev_client", "thiserror", "vec3", ] @@ -3083,6 +3084,12 @@ dependencies = [ "redox_termios", ] +[[package]] +name = "tev_client" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c845c2d56d4f732d09a32c9ea2cd3f01923be7a5f98d9f7f0a347205c3141036" + [[package]] name = "textwrap" version = "0.11.0" diff --git a/rtiow/renderer/Cargo.toml b/rtiow/renderer/Cargo.toml index cd0e504..fc80dc0 100644 --- a/rtiow/renderer/Cargo.toml +++ b/rtiow/renderer/Cargo.toml @@ -30,6 +30,7 @@ stl = {path = "../../../stl"} strum = { version = "0.24.1", features = ["derive"] } strum_macros = "0.24.3" thiserror = "1.0.38" +tev_client = "0.5.2" #stl = {git = "https://git-private.z.xinu.tv/wathiede/stl"} [dev-dependencies] diff --git a/rtiow/renderer/src/output.rs b/rtiow/renderer/src/output.rs index 3d2f2f3..115322c 100644 --- a/rtiow/renderer/src/output.rs +++ b/rtiow/renderer/src/output.rs @@ -2,6 +2,7 @@ use std::{ collections::HashMap, fs::File, io::BufWriter, + net::TcpStream, path::Path, sync::{Arc, Mutex}, time, @@ -9,9 +10,9 @@ use std::{ use chrono::Local; use image; -use lazy_static::lazy_static; use log::info; use serde_derive::Serialize; +use tev_client::{PacketCreateImage, PacketUpdateImage, TevClient}; use crate::{renderer::Scene, vec3::Vec3}; @@ -72,18 +73,36 @@ impl Image { pub struct OutputManager { images: Arc>>, + tev_client: Option>>, } impl OutputManager { - pub fn new() -> OutputManager { - OutputManager { + pub fn new(tev_addr: &Option) -> std::io::Result { + let tev_client = if let Some(addr) = tev_addr { + Some(Arc::new(Mutex::new(TevClient::wrap(TcpStream::connect( + addr, + )?)))) + } else { + None + }; + Ok(OutputManager { images: Arc::new(Mutex::new(HashMap::new())), - } + tev_client, + }) } pub fn register_image(&self, name: String, dimensions: (usize, usize), it: ImageType) { let mut images = self.images.lock().unwrap(); - images.insert(name, (it, Image::new(dimensions.0, dimensions.1))); + images.insert(name.clone(), (it, Image::new(dimensions.0, dimensions.1))); + self.tev_client.clone().map(|c| { + c.lock().unwrap().send(PacketCreateImage { + image_name: &name, + grab_focus: false, + width: dimensions.0 as u32, + height: dimensions.1 as u32, + channel_names: &["R", "G", "B"], + }) + }); } pub fn set_pixel(&self, name: &str, x: usize, y: usize, pixel: Vec3) { @@ -93,6 +112,20 @@ impl OutputManager { .unwrap_or_else(|| panic!("couldn't find image named '{}'", name)); let y_inv = img.h - y - 1; img.put_pixel(x, y_inv, pixel); + self.tev_client.clone().map(|c| { + c.lock().unwrap().send(PacketUpdateImage { + image_name: &name, + grab_focus: false, + channel_names: &["R", "G", "B"], + channel_offsets: &[0, 1, 2], + channel_strides: &[0, 0, 0], + x: x as u32, + y: y_inv as u32, + width: 1, + height: 1, + data: &[pixel.x, pixel.y, pixel.z], + }) + }); } pub fn set_pixel_grey(&self, name: &str, x: usize, y: usize, grey: f32) { diff --git a/rtiow/renderer/src/renderer.rs b/rtiow/renderer/src/renderer.rs index 7d0334f..278dfe1 100644 --- a/rtiow/renderer/src/renderer.rs +++ b/rtiow/renderer/src/renderer.rs @@ -529,7 +529,11 @@ lazy_static! { } */ -pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::io::Error> { +pub fn render( + scene: Scene, + output_dir: &Path, + tev_addr: &Option, +) -> std::result::Result<(), std::io::Error> { // Default to half the cores to disable hyperthreading. let num_threads = scene.num_threads.unwrap_or_else(|| num_cpus::get() / 2); let (pixel_req_tx, pixel_req_rx) = sync_channel(2 * num_threads); @@ -545,7 +549,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i } else { core_ids }; - let output = output::OutputManager::new(); + let output = output::OutputManager::new(tev_addr)?; let output = Arc::new(output); info!("Creating {} render threads", core_ids.len()); diff --git a/rtiow/tracer/src/main.rs b/rtiow/tracer/src/main.rs index 181d351..1ce0e94 100644 --- a/rtiow/tracer/src/main.rs +++ b/rtiow/tracer/src/main.rs @@ -80,7 +80,7 @@ fn main() -> Result<()> { .start(pprof_path.to_str().unwrap().as_bytes()) .unwrap(); } - let res = render(scene, &opt.output); + let res = render(scene, &opt.output, &opt.tev_addr); if let Some(pprof_path) = &opt.pprof { info!("Saving pprof to {}", pprof_path.to_string_lossy()); PROFILER.lock().unwrap().stop().unwrap();