diff options
Diffstat (limited to 'src/bin')
| -rw-r--r-- | src/bin/wgsl_render.rs | 115 |
1 files changed, 22 insertions, 93 deletions
diff --git a/src/bin/wgsl_render.rs b/src/bin/wgsl_render.rs index 2288366..bcfb393 100644 --- a/src/bin/wgsl_render.rs +++ b/src/bin/wgsl_render.rs @@ -1,3 +1,4 @@ +use std::error::Error; use std::thread; use std::time::{Duration, Instant}; @@ -6,7 +7,6 @@ use rosc::OscType; use wgsl_view::gpu; use wgsl_view::osc::OscServer; use wgsl_view::renderer::Renderer; -use wgsl_view::uniform::UniformError; fn main() { env_logger::init(); @@ -68,38 +68,44 @@ fn main() { loop { let frame_start = Instant::now(); - let handle_msg = |msg: rosc::OscMessage| -> Result<(), String> { + let handle_msg = |msg: rosc::OscMessage| -> Result<(), Box<dyn Error>> { let path: Vec<_> = msg.addr.strip_prefix("/").unwrap().split('/').collect(); match (&path[..], &msg.args[..]) { - (["shader"], [OscType::String(code)]) => renderer.load_shader(&device, code), - (["uniform", rest @ ..], args) => { - set_uniform(renderer.uniforms(), rest, args).map_err(|e| e.to_string()) + // create shaders + (["module", module_name], [OscType::String(code)]) => { + renderer.load_module(module_name, code)? } + (["entrypoint"], [OscType::String(module_name)]) => { + renderer.compile(&device, module_name)? + } + // bind values + (["uniform", module, item, rest @ ..], args) => { + renderer.set_uniform(module, item, rest, args)? + } + (["binding", module, item], [OscType::String(target)]) => { + renderer.set_binding(&device, module, item, target)? + } + // create/destroy texture resources (["texture", id], [OscType::String(tsv_name)]) => { renderer.uniforms().create_texture(&device, id, tsv_name); - Ok(()) } + (["texture", id, "destroy"], []) => { + renderer.uniforms().destroy_texture(&device, id); + } + // create/destroy sampler resources (["sampler", id], [OscType::String(filter), OscType::String(clamp)]) => { let (filter_mode, address_mode) = parse_sampler_modes(filter, clamp)?; renderer .uniforms() .create_sampler(&device, id, filter_mode, address_mode); - Ok(()) - } - (["texture", id, "destroy"], []) => { - renderer.uniforms().destroy_texture(&device, id); - Ok(()) } (["sampler", id, "destroy"], []) => { renderer.uniforms().destroy_sampler(&device, id); - Ok(()) } - (["binding", name], [OscType::String(target)]) => { - bind_resource(renderer.uniforms(), &device, name, target) - } - _ => Err(format!("unhandled OSC message {} {:?}", msg.addr, msg.args)), + _ => Err(format!("unhandled OSC message {} {:?}", msg.addr, msg.args))?, } + Ok(()) }; let dirty = if continuous { @@ -136,66 +142,6 @@ fn main() { } /// Set a uniform value from OSC args, navigating the path. -fn set_uniform( - cache: &mut wgsl_view::uniform::UniformCache, - path: &[&str], - args: &[OscType], -) -> Result<(), UniformError> { - let mut parts = path.iter(); - let name = parts.next().ok_or(UniformError::NotFound)?; - - let mut uref = cache.get(name).ok_or(UniformError::NotFound)?; - for component in parts { - uref = uref.field(component)?; - } - - let scalar = uref.leaf_scalar()?; - match scalar.kind { - naga::ScalarKind::Float => { - let values: Vec<f32> = args - .iter() - .map(|a| match a { - OscType::Float(f) => Ok(*f), - OscType::Double(d) => Ok(*d as f32), - OscType::Int(i) => Ok(*i as f32), - OscType::Bool(b) => Ok(if *b { 1.0 } else { 0.0 }), - _ => Err(UniformError::TypeMismatch), - }) - .collect::<Result<_, _>>()?; - uref.set_f32(&values)?; - } - naga::ScalarKind::Sint => { - let values: Vec<i32> = args - .iter() - .map(|a| match a { - OscType::Int(i) => Ok(*i), - OscType::Float(f) => Ok(*f as i32), - OscType::Double(d) => Ok(*d as i32), - OscType::Bool(b) => Ok(if *b { 1 } else { 0 }), - _ => Err(UniformError::TypeMismatch), - }) - .collect::<Result<_, _>>()?; - uref.set_i32(&values)?; - } - naga::ScalarKind::Uint => { - let values: Vec<u32> = args - .iter() - .map(|a| match a { - OscType::Int(i) => Ok(*i as u32), - OscType::Float(f) => Ok(*f as u32), - OscType::Double(d) => Ok(*d as u32), - OscType::Bool(b) => Ok(if *b { 1 } else { 0 }), - _ => Err(UniformError::TypeMismatch), - }) - .collect::<Result<_, _>>()?; - uref.set_u32(&values)?; - } - _ => return Err(UniformError::TypeMismatch), - } - - Ok(()) -} - fn parse_sampler_modes( filter: &str, address: &str, @@ -213,20 +159,3 @@ fn parse_sampler_modes( }; Ok((filter_mode, address_mode)) } - -fn bind_resource( - uniforms: &mut wgsl_view::uniform::UniformCache, - device: &wgpu::Device, - name: &str, - target: &str, -) -> Result<(), String> { - if let Some(id) = target.strip_prefix("/texture/") { - uniforms.bind_texture(device, name, id)?; - Ok(()) - } else if let Some(id) = target.strip_prefix("/sampler/") { - uniforms.bind_sampler(device, name, id)?; - Ok(()) - } else { - Err(format!("invalid binding target '{target}'")) - } -} |
