use rapier2d::pipeline::DebugRenderMode; use crate::sim::{rb_manager::debug_render::DebugVertex, sim_manager::SimManager}; const DEBUG_VERTEX_ATTRIBUTES: [wgpu::VertexAttribute; 2] = wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x4]; fn create_debug_vertex_buffer(device: &wgpu::Device, capacity: usize) -> wgpu::Buffer { device.create_buffer(&wgpu::BufferDescriptor { label: Some("Debug vertex buffer"), size: (capacity * size_of::()) as u64, usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, mapped_at_creation: false, }) } pub struct PhysicsDebugRendererState { debug_pipeline: wgpu::RenderPipeline, debug_bind_group: wgpu::BindGroup, debug_vertex_buffer: wgpu::Buffer, debug_vertex_capacity: usize, debug_vertex_count: usize, } impl PhysicsDebugRendererState { pub fn update_buffers( &mut self, device: &wgpu::Device, queue: &wgpu::Queue, sim: &mut SimManager, debug_render_mode: DebugRenderMode, ) { puffin::profile_function!(); let vertices = sim.rb_manager.debug_render(debug_render_mode); if vertices.len() > self.debug_vertex_capacity { self.debug_vertex_capacity = vertices.len().next_power_of_two(); self.debug_vertex_buffer = create_debug_vertex_buffer(&device, self.debug_vertex_capacity); } queue.write_buffer(&self.debug_vertex_buffer, 0, bytemuck::cast_slice(vertices)); self.debug_vertex_count = vertices.len(); } pub fn render(&self, render_pass: &mut wgpu::RenderPass) { render_pass.set_pipeline(&self.debug_pipeline); render_pass.set_bind_group(0, &self.debug_bind_group, &[]); render_pass.set_vertex_buffer(0, self.debug_vertex_buffer.slice(..)); render_pass.draw(0..self.debug_vertex_count as u32, 0..1); } pub fn new( device: &wgpu::Device, surface_config: &wgpu::SurfaceConfiguration, camera_uniform_buffer: &wgpu::Buffer, ) -> Self { let debug_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: Some("Debug bind group layout"), entries: &[ // camera uniform wgpu::BindGroupLayoutEntry { ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false, min_binding_size: None, }, binding: 0, count: None, visibility: wgpu::ShaderStages::VERTEX, }, ], }); let debug_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { label: Some("Debug bind group"), layout: &debug_bind_group_layout, entries: &[wgpu::BindGroupEntry { binding: 0, resource: camera_uniform_buffer.as_entire_binding(), }], }); let debug_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("Debug shader"), source: wgpu::ShaderSource::Wgsl(include_str!("../shader/debug.wgsl").into()), }); let debug_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Debug pipeline layout"), immediate_size: 0, bind_group_layouts: &[Some(&debug_bind_group_layout)], }); let debug_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Debug pipeline"), layout: Some(&debug_pipeline_layout), vertex: wgpu::VertexState { module: &debug_shader, entry_point: Some("vs_main"), buffers: &[wgpu::VertexBufferLayout { array_stride: size_of::() as wgpu::BufferAddress, step_mode: wgpu::VertexStepMode::Vertex, attributes: &DEBUG_VERTEX_ATTRIBUTES, }], compilation_options: wgpu::PipelineCompilationOptions::default(), }, fragment: Some(wgpu::FragmentState { module: &debug_shader, entry_point: Some("fs_main"), targets: &[Some(wgpu::ColorTargetState { format: surface_config.format, blend: Some(wgpu::BlendState::ALPHA_BLENDING), write_mask: wgpu::ColorWrites::ALL, })], compilation_options: wgpu::PipelineCompilationOptions::default(), }), primitive: wgpu::PrimitiveState { topology: wgpu::PrimitiveTopology::LineList, strip_index_format: None, front_face: wgpu::FrontFace::Ccw, cull_mode: None, polygon_mode: wgpu::PolygonMode::Fill, unclipped_depth: false, conservative: false, }, depth_stencil: None, multisample: wgpu::MultisampleState::default(), multiview_mask: None, cache: None, }); let debug_vertex_capacity = 4096; let debug_vertex_buffer = create_debug_vertex_buffer(&device, debug_vertex_capacity); PhysicsDebugRendererState { debug_pipeline, debug_bind_group, debug_vertex_buffer, debug_vertex_capacity, debug_vertex_count: 0, } } }