diff options
Diffstat (limited to 'src/renderer.rs')
| -rw-r--r-- | src/renderer.rs | 122 |
1 files changed, 35 insertions, 87 deletions
diff --git a/src/renderer.rs b/src/renderer.rs index e3a2acd..454e81a 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -1,5 +1,4 @@ -use crate::uniform::{UniformCache, UniformError}; -use rosc::OscType; +use crate::uniform::UniformCache; const CANVAS_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8UnormSrgb; @@ -32,33 +31,34 @@ fn fs_main(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> { "; pub struct Renderer { + canvas: wgpu::Texture, canvas_view: wgpu::TextureView, vertex_module: wgpu::ShaderModule, vertex_bgl: wgpu::BindGroupLayout, vertex_bg: wgpu::BindGroup, render_pipeline: wgpu::RenderPipeline, - uniform_cache: UniformCache, + uniforms: UniformCache, } impl Renderer { pub fn new(device: &wgpu::Device, queue: &wgpu::Queue, width: u32, height: u32) -> Self { - let canvas_view = device - .create_texture(&wgpu::TextureDescriptor { - label: Some("canvas"), - size: wgpu::Extent3d { - width, - height, - depth_or_array_layers: 1, - }, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: CANVAS_FORMAT, - usage: wgpu::TextureUsages::RENDER_ATTACHMENT - | wgpu::TextureUsages::TEXTURE_BINDING, - view_formats: &[], - }) - .create_view(&Default::default()); + let canvas = device.create_texture(&wgpu::TextureDescriptor { + label: Some("canvas"), + size: wgpu::Extent3d { + width, + height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: CANVAS_FORMAT, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT + | wgpu::TextureUsages::TEXTURE_BINDING + | wgpu::TextureUsages::COPY_SRC, + view_formats: &[], + }); + let canvas_view = canvas.create_view(&Default::default()); let vertex_module = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("vertex_shader"), @@ -101,106 +101,54 @@ impl Renderer { bytemuck::cast_slice(&[width as f32, height as f32]), ); - let mut uniform_cache = UniformCache::new(); + let mut uniforms = UniformCache::new(); let render_pipeline = build_pipeline( device, &vertex_module, &vertex_bgl, DEFAULT_FRAGMENT, - &mut uniform_cache, + &mut uniforms, ) .expect("default shader"); Self { + canvas, canvas_view, vertex_module, vertex_bgl, vertex_bg, render_pipeline, - uniform_cache, + uniforms, } } + pub fn canvas_texture(&self) -> &wgpu::Texture { + &self.canvas + } + pub fn canvas_view(&self) -> &wgpu::TextureView { &self.canvas_view } + pub fn uniforms(&mut self) -> &mut UniformCache { + &mut self.uniforms + } + pub fn load_shader(&mut self, device: &wgpu::Device, source: &str) -> Result<(), String> { let pipeline = build_pipeline( device, &self.vertex_module, &self.vertex_bgl, source, - &mut self.uniform_cache, + &mut self.uniforms, )?; self.render_pipeline = pipeline; log::info!("shader loaded"); Ok(()) } - pub fn set_uniform( - &mut self, - path: &str, - args: &[OscType], - ) -> Result<(), Box<dyn std::error::Error>> { - let mut parts = path.split('/'); - let name = parts.next().ok_or("missing uniform name")?; - - let mut uref = self.uniform_cache.get(name).ok_or("uniform not found")?; - - 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(Box::new(UniformError::TypeMismatch)), - } - - Ok(()) - } - pub fn render(&mut self, device: &wgpu::Device, queue: &wgpu::Queue) { - self.uniform_cache.flush(queue); + self.uniforms.flush(queue); let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); @@ -225,7 +173,7 @@ impl Renderer { pass.set_pipeline(&self.render_pipeline); pass.set_bind_group(0, &self.vertex_bg, &[]); - if let Some(ref bg) = self.uniform_cache.bind_group { + if let Some(ref bg) = self.uniforms.bind_group { pass.set_bind_group(1, bg, &[]); } pass.draw(0..4, 0..1); |
