summaryrefslogtreecommitdiffstats
path: root/src/bin
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2026-04-22 11:52:07 +0000
committers-ol <s+removethis@s-ol.nu>2026-05-14 15:00:13 +0000
commit76e48cc66816a1ec064c12a7181b7751d1c783b2 (patch)
tree7368d6ab24518d25eea7e6cf1bf8559519121cb7 /src/bin
parentrebind outdated textures (diff)
downloadwgsl-view-76e48cc66816a1ec064c12a7181b7751d1c783b2.tar.gz
wgsl-view-76e48cc66816a1ec064c12a7181b7751d1c783b2.zip
switch to WESL shaders
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/wgsl_render.rs115
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}'"))
- }
-}