From bfb048698ecbec09e745f5733b8f5df45225d268 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Sat, 18 Jul 2026 14:53:11 +0400 Subject: feat(render): bridge legacy camera to Vulkan --- adapters/fparkan-render-vulkan/src/ffi/smoke.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'adapters/fparkan-render-vulkan/src/ffi/smoke.rs') diff --git a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs index 11c3377..5db7e3b 100644 --- a/adapters/fparkan-render-vulkan/src/ffi/smoke.rs +++ b/adapters/fparkan-render-vulkan/src/ffi/smoke.rs @@ -111,6 +111,11 @@ impl VulkanSmokeRenderer { .mesh .validate() .map_err(|context| VulkanSmokeRendererError::InvalidStaticMesh { context })?; + if !create_info.camera.is_finite() { + return Err(VulkanSmokeRendererError::InvalidStaticCamera { + context: "non-finite clip_from_world matrix", + }); + } let draw_texture_indices = resolve_draw_texture_indices(&create_info.mesh.draw_ranges, &create_info.materials) .map_err(|context| VulkanSmokeRendererError::InvalidStaticMesh { context })?; @@ -226,6 +231,7 @@ impl VulkanSmokeRenderer { textures, draw_ranges: create_info.mesh.draw_ranges.clone(), draw_texture_indices, + camera: create_info.camera, frame_sync: Vec::new(), images_in_flight: Vec::new(), current_frame: 0, @@ -671,6 +677,14 @@ impl VulkanSmokeRenderer { 0, vk::IndexType::UINT16, ); + let clip_from_world = matrix_bytes(self.camera.clip_from_world); + device.device().cmd_push_constants( + command_buffer, + resources.pipeline_layout, + vk::ShaderStageFlags::VERTEX, + 0, + &clip_from_world, + ); for (range, &texture_index) in self.draw_ranges.iter().zip(&self.draw_texture_indices) { let pipeline = resources.pipelines.get(&range.pipeline_key()).ok_or( VulkanSmokeRendererError::InvariantViolation { @@ -700,7 +714,7 @@ impl VulkanSmokeRenderer { command_buffer, resources.pipeline_layout, vk::ShaderStageFlags::FRAGMENT, - 0, + 64, &alpha_cutoff, ); device.device().cmd_draw_indexed( @@ -928,6 +942,14 @@ impl VulkanSmokeRenderer { } } +fn matrix_bytes(matrix: [f32; 16]) -> [u8; 64] { + let mut bytes = [0; 64]; + for (index, value) in matrix.into_iter().enumerate() { + bytes[index * 4..(index + 1) * 4].copy_from_slice(&value.to_ne_bytes()); + } + bytes +} + fn fnv1a64(bytes: &[u8]) -> u64 { bytes.iter().fold(0xcbf2_9ce4_8422_2325_u64, |hash, byte| { (hash ^ u64::from(*byte)).wrapping_mul(0x0000_0100_0000_01b3) -- cgit v1.2.3