summaryrefslogtreecommitdiff
path: root/src/renderer/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer/mod.rs')
-rw-r--r--src/renderer/mod.rs145
1 files changed, 143 insertions, 2 deletions
diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs
index 9bdbe46..7dd1802 100644
--- a/src/renderer/mod.rs
+++ b/src/renderer/mod.rs
@@ -10,7 +10,11 @@ use crate::{
camera::Camera,
config::{CELLS_IN_CHUNK, CHUNK_SIZE},
renderer::ui::draw_egui,
- sim::{cell::materials::MaterialId, cell_sim::world::World, rb_sim::RbSimManager},
+ sim::{
+ cell::materials::MaterialId,
+ cell_sim::world::World,
+ rb_sim::{RbSimManager, debug_render::DebugVertex},
+ },
};
// TODO derive from shared chunk config
@@ -18,6 +22,8 @@ const CHUNK_SLOTS: usize = 11 * 200;
const RB_ENTITY_SLOTS: usize = 64;
const CELL_SLOTS: usize = CHUNK_SLOTS + RB_ENTITY_SLOTS;
+const INITIAL_DEBUG_VERTEX_CAPACITY: usize = 4096;
+
#[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
struct Instance {
@@ -38,6 +44,18 @@ fn srgb_to_linear(channel: u8) -> f32 {
}
}
+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::<DebugVertex>()) as u64,
+ usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
+ mapped_at_creation: false,
+ })
+}
+
pub struct RendererState {
window: Arc<Window>,
surface: wgpu::Surface<'static>,
@@ -59,6 +77,12 @@ pub struct RendererState {
cell_buffer: wgpu::Buffer,
pixels_bind_group: wgpu::BindGroup,
+ // physics debug lines
+ debug_pipeline: wgpu::RenderPipeline,
+ debug_bind_group: wgpu::BindGroup,
+ debug_vertex_buffer: wgpu::Buffer,
+ debug_vertex_capacity: usize,
+
renderer_rb_entities: FxHashMap<u32, usize>,
}
@@ -293,6 +317,86 @@ impl RendererState {
],
});
+ 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::<DebugVertex>() 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: 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 = INITIAL_DEBUG_VERTEX_CAPACITY;
+ let debug_vertex_buffer = create_debug_vertex_buffer(&device, debug_vertex_capacity);
+
RendererState {
window,
surface,
@@ -311,6 +415,11 @@ impl RendererState {
cell_buffer,
pixels_bind_group,
+ debug_pipeline,
+ debug_bind_group,
+ debug_vertex_buffer,
+ debug_vertex_capacity,
+
renderer_rb_entities: FxHashMap::default(),
}
}
@@ -327,7 +436,7 @@ impl RendererState {
pub fn render(
&mut self,
world: &mut World,
- rb_sim_manager: &RbSimManager,
+ rb_sim_manager: &mut RbSimManager,
camera: &mut Camera,
config: &mut Config,
diagnostics: &Diagnostics,
@@ -510,6 +619,31 @@ impl RendererState {
.write_buffer(&self.instance_buffer, 0, bytemuck::cast_slice(&instances));
}
+ let debug_vertex_count = if config.debug_render {
+ puffin::profile_scope!("Build physics debug lines");
+ let vertices = rb_sim_manager.debug_render(config.debug_render_mode);
+
+ if vertices.is_empty() {
+ 0
+ } else {
+ 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(&self.device, self.debug_vertex_capacity);
+ }
+
+ self.queue.write_buffer(
+ &self.debug_vertex_buffer,
+ 0,
+ bytemuck::cast_slice(vertices),
+ );
+
+ vertices.len() as u32
+ }
+ } else {
+ 0
+ };
+
{
puffin::profile_scope!("Main render pass");
let mut render_pass: wgpu::RenderPass<'_> =
@@ -538,6 +672,13 @@ impl RendererState {
render_pass.set_pipeline(&self.pixels_pipeline);
render_pass.set_bind_group(0, &self.pixels_bind_group, &[]);
render_pass.draw(0..4, 0..instances.len() as u32);
+
+ if debug_vertex_count > 0 {
+ 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..debug_vertex_count, 0..1);
+ }
}
{