From a1f07f9260e40856be4544efa76c462a612ebc0c Mon Sep 17 00:00:00 2001 From: UnderSampled Date: Sat, 9 Sep 2023 01:23:15 -0400 Subject: [PATCH] Add camera render code for client buffers --- src/nodes/items/camera.rs | 95 +++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 29 deletions(-) diff --git a/src/nodes/items/camera.rs b/src/nodes/items/camera.rs index 0bccc00..dde195b 100644 --- a/src/nodes/items/camera.rs +++ b/src/nodes/items/camera.rs @@ -46,7 +46,7 @@ lazy_static! { struct FrameInfo { proj_matrix: Mat4, - px_size: Vector2, + preview_size: Vector2, } pub struct CameraItem { @@ -54,14 +54,14 @@ pub struct CameraItem { frame_info: Mutex, sk_textures: Mutex>, sk_mat: OnceCell>, - render_requests_tx: mpsc::Sender<(usize, oneshot::Sender<()>)>, - render_requests_rx: mpsc::Receiver<(usize, oneshot::Sender<()>)>, + render_requests_tx: mpsc::Sender<((usize, usize), oneshot::Sender<()>)>, + render_requests_rx: Mutex)>>, rendered_notifiers: Mutex>>, applied_to: Registry, apply_to: Registry, } impl CameraItem { - pub fn add_to(node: &Arc, proj_matrix: Mat4, px_size: Vector2) { + pub fn add_to(node: &Arc, proj_matrix: Mat4, preview_size: Vector2) { let (render_requests_tx, render_requests_rx) = mpsc::channel(5); Item::add_to( node, @@ -71,12 +71,12 @@ impl CameraItem { space: node.spatial.get().unwrap().clone(), frame_info: Mutex::new(FrameInfo { proj_matrix, - px_size, + preview_size, }), sk_textures: Mutex::new(FxHashMap::default()), sk_mat: OnceCell::new(), render_requests_tx, - render_requests_rx, + render_requests_rx: Mutex::new(render_requests_rx), rendered_notifiers: Mutex::new(Vec::new()), applied_to: Registry::new(), apply_to: Registry::new(), @@ -89,9 +89,21 @@ impl CameraItem { ); } + fn import_buffers_flex( + node: &Node, + calling_client: Arc, + message: Message, + ) -> Result<()> { + let ItemType::Camera(camera) = &node.item.get().unwrap().specialization else { + bail!("Wrong item type?") + }; + + Ok(()) + } + fn render_flex( node: &Node, - _calling_client: Arc, + calling_client: Arc, message: Message, response: MethodResponseSender, ) { @@ -104,7 +116,7 @@ impl CameraItem { let (rendered_tx, rendered_rx) = oneshot::channel(); - let buffer_to_render: usize = deserialize(&message.data).unwrap(); + let buffer_to_render: (usize, usize) = (Arc::as_ptr(&calling_client) as usize, deserialize(&message.data).unwrap()); tokio::task::spawn(async move { camera @@ -146,31 +158,56 @@ impl CameraItem { pub fn update(&self, sk: &impl StereoKitDraw) { let frame_info = self.frame_info.lock(); - let sk_tex = self.sk_tex.get_or_init(|| { - sk.tex_gen_color( - Color128::default(), - frame_info.px_size.x as i32, - frame_info.px_size.y as i32, - TextureType::RENDER_TARGET, - stereokit::TextureFormat::RGBA32Linear, - ) - }); - let sk_mat = self.sk_mat.get_or_init(|| { - let shader = sk.shader_create_mem(&UNLIT_SHADER_BYTES).unwrap(); - let mat = sk.material_create(&shader); - sk.material_set_texture(&mat, "diffuse", sk_tex.as_ref()); - sk.material_set_transparency(&mat, Transparency::Blend); - Arc::new(mat) - }); - for model_part in self.apply_to.take_valid_contents() { - model_part.replace_material(sk_mat.clone()) + let mut sk_textures = self.sk_textures.lock(); + + if !self.apply_to.is_empty() { + let sk_tex = sk_textures.entry((0, 0)).or_insert_with(|| { + sk.tex_gen_color( + Color128::default(), + frame_info.preview_size.x as i32, + frame_info.preview_size.y as i32, + TextureType::RENDER_TARGET, + stereokit::TextureFormat::RGBA32Linear, + ) + }); + let sk_mat = self.sk_mat.get_or_init(|| { + let shader = sk.shader_create_mem(&UNLIT_SHADER_BYTES).unwrap(); + let mat = sk.material_create(&shader); + sk.material_set_texture(&mat, "diffuse", sk_tex.as_ref()); + sk.material_set_transparency(&mat, Transparency::Blend); + Arc::new(mat) + }); + for model_part in self.apply_to.take_valid_contents() { + model_part.replace_material(sk_mat.clone()) + } } - //if !self.applied_to.is_empty() { - //} + if !self.applied_to.is_empty() { + sk.render_to( + sk_textures.get(&(0, 0)).unwrap(), + frame_info.proj_matrix, + self.space.global_transform(), + RenderLayer::all(), + stereokit::RenderClear::All, + Rect { + x: 0.0, + y: 0.0, + w: 0.0, + h: 0.0, + }, + ); + } let mut render_notifiers = self.rendered_notifiers.lock(); - while let Ok((buffer_to_render, rendered_tx)) = self.render_requests_rx.try_recv() { + let mut render_requests_rx = self.render_requests_rx.lock(); + while let Ok((buffer_to_render, rendered_tx)) = render_requests_rx.try_recv() { + let Some(sk_tex) = sk_textures.get(&buffer_to_render).take() else { + // TODO: Consider allocating a new buffer in a or_insert_with (requires desired formats and a size) + // For now, rendering to no buffer means not rendering at all. + render_notifiers.push(rendered_tx); + continue; + }; + sk.render_to( sk_tex, frame_info.proj_matrix,