From dac885748a8b822e197a4798ba6ec0a6a47698f8 Mon Sep 17 00:00:00 2001 From: Verox001 Date: Sun, 4 May 2025 11:27:55 +0200 Subject: [PATCH] Added Shader Input and vertex buffering --- simulator/src/main.rs | 58 +++++++++++++++++++++++++++++++++++---- simulator/src/shader.wgsl | 17 ++++++++---- 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/simulator/src/main.rs b/simulator/src/main.rs index 541f248..e3e9301 100644 --- a/simulator/src/main.rs +++ b/simulator/src/main.rs @@ -2,6 +2,7 @@ use std::cmp::max; use std::sync::Arc; use pollster::FutureExt; +use wgpu::util::DeviceExt; use wgpu::{Adapter, Device, Instance, PresentMode, Queue, Surface, SurfaceCapabilities}; use winit::application::ApplicationHandler; use winit::dpi::PhysicalSize; @@ -16,6 +17,32 @@ pub async fn run() { let _ = event_loop.run_app(&mut window_state); } +#[repr(C)] +#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] +struct Vertex { + position: [f32; 3], + color: [f32; 3], +} + +impl Vertex { + const ATTRIBS: [wgpu::VertexAttribute; 2] = + wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3]; + + fn desc() -> wgpu::VertexBufferLayout<'static> { + wgpu::VertexBufferLayout { + array_stride: size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &Self::ATTRIBS, + } + } +} + +const VERTICES: &[Vertex] = &[ + Vertex { position: [0.0, 0.5, 0.0], color: [1.0, 0.0, 0.0] }, + Vertex { position: [-0.5, -0.5, 0.0], color: [0.0, 1.0, 0.0] }, + Vertex { position: [0.5, -0.5, 0.0], color: [0.0, 0.0, 1.0] }, +]; + struct StateApplication<'a> { state: Option>, } @@ -77,6 +104,8 @@ struct State<'a> { window: Arc, render_pipeline: wgpu::RenderPipeline, + vertex_buffer: wgpu::Buffer, + num_vertices: u32, } impl<'a> State<'a> { @@ -92,6 +121,9 @@ impl<'a> State<'a> { surface.configure(&device, &config); let render_pipeline = Self::create_render_pipeline(&device, &config); + let vertex_buffer = Self::create_vertex_buffer(&device); + + let num_vertices = VERTICES.len() as u32; Self { surface, @@ -102,6 +134,9 @@ impl<'a> State<'a> { window: window_arc, render_pipeline, + vertex_buffer, + + num_vertices, } } @@ -113,6 +148,16 @@ impl<'a> State<'a> { // TODO: Update logic here } + fn create_vertex_buffer(device: &Device) -> wgpu::Buffer { + device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(VERTICES), + usage: wgpu::BufferUsages::VERTEX, + } + ) + } + fn create_render_pipeline(device: &Device, config: &wgpu::SurfaceConfiguration) -> wgpu::RenderPipeline { let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("Shader"), @@ -132,8 +177,8 @@ impl<'a> State<'a> { vertex: wgpu::VertexState { module: &shader, entry_point: Some("vs_main"), - buffers: &[], - compilation_options: wgpu::PipelineCompilationOptions::default(), + buffers: &[Vertex::desc()], + compilation_options: Default::default(), }, fragment: Some(wgpu::FragmentState { module: &shader, @@ -226,7 +271,7 @@ impl<'a> State<'a> { } pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> { - let output = self.surface.get_current_texture().unwrap(); + let output = self.surface.get_current_texture()?; let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default()); let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { @@ -234,7 +279,7 @@ impl<'a> State<'a> { }); { - let mut _render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("Render Pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { view: &view, @@ -254,8 +299,9 @@ impl<'a> State<'a> { timestamp_writes: None, }); - _render_pass.set_pipeline(&self.render_pipeline); - _render_pass.draw(0..3, 0..1); + render_pass.set_pipeline(&self.render_pipeline); + render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); + render_pass.draw(0..self.num_vertices, 0..1); } self.queue.submit(std::iter::once(encoder.finish())); diff --git a/simulator/src/shader.wgsl b/simulator/src/shader.wgsl index f5a0eae..68f015a 100644 --- a/simulator/src/shader.wgsl +++ b/simulator/src/shader.wgsl @@ -1,19 +1,24 @@ +struct VertexInput { + @location(0) position: vec3, + @location(1) color: vec3, +}; + struct VertexOutput { @builtin(position) clip_position: vec4, + @location(0) color: vec3, }; @vertex fn vs_main( - @builtin(vertex_index) in_vertex_index: u32, + model: VertexInput, ) -> VertexOutput { var out: VertexOutput; - let x = f32(1 - i32(in_vertex_index)) * 0.5; - let y = f32(i32(in_vertex_index & 1u) * 2 - 1) * 0.5; - out.clip_position = vec4(x, y, 0.0, 1.0); + out.color = model.color; + out.clip_position = vec4(model.position, 1.0); return out; } @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { - return vec4(0.3, 0.2, 0.1, 1.0); -} \ No newline at end of file + return vec4(in.color, 1.0); +}