From 68e111bd994787c583949d9327cd87dd357eb9e8 Mon Sep 17 00:00:00 2001 From: Marco Thomas Date: Mon, 23 Aug 2021 18:35:32 +0200 Subject: [PATCH] First half of buffers --- Cargo.lock | 15 +++++++++++++ Cargo.toml | 1 + src/challenge_shader.wgsl | 28 ++++++++++------------- src/main.rs | 1 + src/shader.wgsl | 23 ++++++++++--------- src/state.rs | 40 ++++++++++++++++++++++++++------- src/vertex.rs | 47 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 120 insertions(+), 35 deletions(-) create mode 100644 src/vertex.rs diff --git a/Cargo.lock b/Cargo.lock index e1bf3b6..500aa30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,6 +127,20 @@ name = "bytemuck" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e215f8c2f9f79cb53c8335e687ffd07d5bfcb6fe5fc80723762d0be46e7cc54" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "byteorder" @@ -1902,6 +1916,7 @@ dependencies = [ name = "wgpu-rs-learning" version = "0.1.0" dependencies = [ + "bytemuck", "cgmath", "env_logger", "image", diff --git a/Cargo.toml b/Cargo.toml index 63edd7f..6351092 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,4 @@ env_logger = "0.9" log = "0.4" wgpu = "0.9" pollster = "0.2" +bytemuck = { version = "1.4", features = [ "derive" ] } diff --git a/src/challenge_shader.wgsl b/src/challenge_shader.wgsl index d1b9b86..74b92fe 100644 --- a/src/challenge_shader.wgsl +++ b/src/challenge_shader.wgsl @@ -1,27 +1,23 @@ // Vertex shader - struct VertexOutput { - [[builtin(position)]] clip_coordinates: vec4; - [[location(0)]] position: vec2; + [[builtin(position)]] clip_coordinates: vec4; + [[location(0)]] position: vec2; }; [[stage(vertex)]] -fn main( - [[builtin(vertex_index)]] in_vertex_index: u32, -) -> 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_coordinates = vec4(x, y, 0.0, 1.0); - out.position = vec2(x, y); - return out; +fn main([[builtin(vertex_index)]] in_vertex_index: u32) -> 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_coordinates = vec4(x, y, 0.0, 1.0); + out.position = vec2(x, y); + return out; } // Fragment shader - [[stage(fragment)]] fn main(in: VertexOutput) -> [[location(0)]] vec4 { - let r = in.position.x; - let g = in.position.y; - return vec4(r, g, 0.1, 1.0); + let r = in.position.x; + let g = in.position.y; + return vec4(r, g, 0.1, 1.0); } diff --git a/src/main.rs b/src/main.rs index 7920aed..eceb3b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use winit::{ }; mod state; +mod vertex; use crate::state::State; diff --git a/src/shader.wgsl b/src/shader.wgsl index 372ee89..08c79e9 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -1,23 +1,24 @@ // Vertex shader +struct VertexInput { + [[location(0)]] position: vec3; + [[location(1)]] color: vec3; +}; struct VertexOutput { - [[builtin(position)]] clip_position: vec4; + [[builtin(position)]] clip_coordinate: vec4; + [[location(0)]] color: vec3; }; [[stage(vertex)]] -fn main( - [[builtin(vertex_index)]] in_vertex_index: u32, -) -> 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); - return out; +fn main(model: VertexInput) -> VertexOutput { + var out: VertexOutput; + out.clip_coordinate = vec4(model.position, 1.0); + out.color = model.color; + return out; } // Fragment shader - [[stage(fragment)]] fn main(in: VertexOutput) -> [[location(0)]] vec4 { - return vec4(0.3, 0.2, 0.1, 1.0); + return vec4(in.color, 1.0); } diff --git a/src/state.rs b/src/state.rs index e910b4b..9888df1 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,9 +1,14 @@ -use wgpu::PrimitiveTopology; +use wgpu::{ + PrimitiveTopology, + util::DeviceExt, +}; use winit::{ event::*, window::Window, }; +use crate::vertex::Vertex; + /// Hold state with important information pub struct State { surface: wgpu::Surface, @@ -14,8 +19,10 @@ pub struct State { pub size: winit::dpi::PhysicalSize, clear_color: wgpu::Color, render_pipeline: wgpu::RenderPipeline, - challenge_render_pipeline: wgpu::RenderPipeline, + //challenge_render_pipeline: wgpu::RenderPipeline, use_challenge_render_pipeline: bool, + vertex_buffer: wgpu::Buffer, + num_vertices: u32, } impl State { @@ -93,8 +100,8 @@ impl State { module: &shader, // function name in shader.wgsl for [[stage(vertex)]] entry_point: "main", - // already specified in the shader - buffers: &[], + // specify memory layout + buffers: &[Vertex::desc()], }, // needed to sotre color data to swap_chain @@ -129,7 +136,7 @@ impl State { } } ); - + /* // overwrite challenge shader file to shader let shader = device.create_shader_module( &wgpu::ShaderModuleDescriptor { @@ -194,6 +201,17 @@ impl State { } } ); + */ + + let vertex_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(crate::vertex::VERTICES), + usage: wgpu::BufferUsage::VERTEX, + } + ); + + let num_vertices = crate::vertex::VERTICES.len() as u32; Self { surface, @@ -204,8 +222,10 @@ impl State { size, clear_color: wgpu::Color { r: 0.6, g: 0.6, b: 0.1, a: 1.0 }, render_pipeline, - challenge_render_pipeline, + //challenge_render_pipeline, use_challenge_render_pipeline: false, + vertex_buffer, + num_vertices, } } @@ -277,13 +297,17 @@ impl State { }); // set pipeline + /* if self.use_challenge_render_pipeline { render_pass.set_pipeline(&self.challenge_render_pipeline); } else { render_pass.set_pipeline(&self.render_pipeline); - } + } + */ + render_pass.set_pipeline(&self.render_pipeline); + render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); // draw triangle - render_pass.draw(0..3, 0..1); + render_pass.draw(0..self.num_vertices, 0..1); // drop so encoder isn't borrowed mutually anymore drop(render_pass); diff --git a/src/vertex.rs b/src/vertex.rs new file mode 100644 index 0000000..0ab3037 --- /dev/null +++ b/src/vertex.rs @@ -0,0 +1,47 @@ +#[repr(C)] +#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] +pub struct Vertex { + position: [f32; 3], + color: [f32; 3], +} + +impl Vertex { + pub fn desc<'a>() -> wgpu::VertexBufferLayout<'a> { + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + // this oculd be shortened with: + // attributes: &wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3], + 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, + }, + ], + } + } +} + +pub const VERTICES: &[Vertex] = &[ + // Top + Vertex { + position: [0.0, 0.5, 0.0], + color: [1.0, 0.0, 0.0], + }, + // Left + Vertex { + position: [-0.5, -0.5, 0.0], + color: [0.0, 1.0, 0.0], + }, + // Right + Vertex { + position: [0.5, -0.5, 0.0], + color: [0.0, 0.0, 1.0], + }, +];