From e6034cefbe09ccab29084cd7488498b1e9667c0d Mon Sep 17 00:00:00 2001 From: John Doty Date: Sat, 17 Jun 2023 08:38:46 -0700 Subject: [PATCH] [oden] Buffers and Indices --- Cargo.lock | 15 +++++++++ Cargo.toml | 1 + src/lib.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++++-- src/shader.wgsl | 15 ++++++--- 4 files changed, 106 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 396d7028..e45b4338 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,6 +191,20 @@ name = "bytemuck" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] [[package]] name = "calloop" @@ -905,6 +919,7 @@ dependencies = [ name = "oden" version = "0.1.0" dependencies = [ + "bytemuck", "env_logger", "log", "pollster", diff --git a/Cargo.toml b/Cargo.toml index 5cbdfe2a..2ff77136 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ log = "0.4" wgpu = "0.16" winit = "0.28" pollster = "0.3" +bytemuck = { version = "1.13", features = ["derive"] } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 52839d34..9c4d677d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +use bytemuck; +use wgpu::util::DeviceExt; use winit::{ event::*, event_loop::{ControlFlow, EventLoop}, @@ -5,6 +7,60 @@ use winit::{ window::WindowBuilder, }; +#[repr(C)] +#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] +struct Vertex { + position: [f32; 3], + color: [f32; 3], +} + +// lib.rs +impl Vertex { + fn desc() -> wgpu::VertexBufferLayout<'static> { + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &[ + wgpu::VertexAttribute { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float32x3, + }, + wgpu::VertexAttribute { + offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, + shader_location: 1, + format: wgpu::VertexFormat::Float32x3, + }, + ], + } + } +} + +const VERTICES: &[Vertex] = &[ + Vertex { + position: [-0.0868241, 0.49240386, 0.0], + color: [0.5, 0.0, 0.5], + }, // A + Vertex { + position: [-0.49513406, 0.06958647, 0.0], + color: [0.5, 0.0, 0.5], + }, // B + Vertex { + position: [-0.21918549, -0.44939706, 0.0], + color: [0.5, 0.0, 0.5], + }, // C + Vertex { + position: [0.35966998, -0.3473291, 0.0], + color: [0.5, 0.0, 0.5], + }, // D + Vertex { + position: [0.44147372, 0.2347359, 0.0], + color: [0.5, 0.0, 0.5], + }, // E +]; + +const INDICES: &[u16] = &[0, 1, 4, 1, 2, 4, 2, 3, 4]; + struct State { surface: wgpu::Surface, device: wgpu::Device, @@ -14,6 +70,10 @@ struct State { window: Window, render_pipeline: wgpu::RenderPipeline, + vertex_buffer: wgpu::Buffer, + index_buffer: wgpu::Buffer, + num_indices: u32, // Indices in index_buffer + // Garbage mouse_x: f64, mouse_y: f64, @@ -107,7 +167,7 @@ impl State { vertex: wgpu::VertexState { module: &shader, entry_point: "vs_main", - buffers: &[], + buffers: &[Vertex::desc()], }, fragment: Some(wgpu::FragmentState { module: &shader, @@ -139,6 +199,18 @@ impl State { multiview: None, }); + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(VERTICES), + usage: wgpu::BufferUsages::VERTEX, + }); + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(INDICES), + usage: wgpu::BufferUsages::INDEX, + }); + let num_indices = INDICES.len() as u32; + Self { window, surface, @@ -147,6 +219,10 @@ impl State { config, size, render_pipeline, + vertex_buffer, + index_buffer, + num_indices, + mouse_x: 0.0, mouse_y: 0.0, } @@ -207,7 +283,9 @@ impl State { }); render_pass.set_pipeline(&self.render_pipeline); - render_pass.draw(0..3, 0..1); + render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); + render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); + render_pass.draw_indexed(0..self.num_indices, 0, 0..1); } // Submit will accept anything that implements IntoIter diff --git a/src/shader.wgsl b/src/shader.wgsl index 36d33bb3..cc394ed9 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -1,17 +1,22 @@ // Vertex shader +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; } @@ -19,5 +24,5 @@ fn vs_main( @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { - return vec4(0.3, 0.2, 0.1, 1.0); + return vec4(in.color, 1.0); }