diff --git a/Cargo.lock b/Cargo.lock index 4b4fda5..0d37d52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,6 +85,26 @@ version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" +[[package]] +name = "bytemuck" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58" +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" version = "1.4.3" @@ -1677,6 +1697,7 @@ name = "wgpufun" version = "0.1.0" dependencies = [ "anyhow", + "bytemuck", "fs_extra", "futures", "glob", diff --git a/Cargo.toml b/Cargo.toml index 0135c0f..d321f23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,8 @@ edition = "2018" winit = "0.24" wgpu = "0.7" futures = "0.3" +bytemuck = { version = "1.4", features = [ "derive" ] } + [build-dependencies] anyhow = "1.0" diff --git a/src/.bin/shader.frag.spv b/src/.bin/shader.frag.spv index 232ea0e..108354f 100644 Binary files a/src/.bin/shader.frag.spv and b/src/.bin/shader.frag.spv differ diff --git a/src/.bin/shader.vert.spv b/src/.bin/shader.vert.spv index 1a167c3..3ccffd5 100644 Binary files a/src/.bin/shader.vert.spv and b/src/.bin/shader.vert.spv differ diff --git a/src/app.rs b/src/app.rs index fb9653b..2bc4fbc 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,20 @@ use winit::{window::Window, dpi::PhysicalSize, event::WindowEvent}; +use wgpu::util::DeviceExt; +use crate::vertex::Vertex; + +const VERTICES: &[Vertex] = &[ + Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [1.0, 0.0, 0.0] }, // A + Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.0, 1.0, 0.0] }, // B + Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.0, 0.0, 1.0] }, // C + Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.0, 0.5, 0.5] }, // D + Vertex { position: [0.44147372, 0.2347359, 0.0],color: [0.5, 0.5, 0.0] }, // E +]; + +const INDICES: &[u16] = &[ + 0, 1, 4, + 1, 2, 4, + 2, 3, 4, +]; pub struct App { surface: wgpu::Surface, @@ -6,14 +22,17 @@ pub struct App { queue: wgpu::Queue, swapchain_desc: wgpu::SwapChainDescriptor, swapchain: wgpu::SwapChain, - pipeline: wgpu::RenderPipeline + pipeline: wgpu::RenderPipeline, + // Buffers + vertex_buffer: wgpu::Buffer, + index_buffer: wgpu::Buffer, } impl App { pub async fn new(window: &Window) -> Self { // Select backend - let backend = wgpu::BackendBit::DX12; + let backend = wgpu::BackendBit::PRIMARY; println!("Backend: {:?}", backend); // Create surface and pick adapter (physical gpu) @@ -57,7 +76,7 @@ impl App { let vert_state = wgpu::VertexState { //vert module: &device.create_shader_module(&wgpu::include_spirv!(".bin\\shader.vert.spv")), entry_point: "main", - buffers: &[], + buffers: &[Vertex::desc()], }; let frag_state = wgpu::FragmentState { // frag module: &device.create_shader_module(&wgpu::include_spirv!(".bin\\shader.frag.spv")), @@ -93,8 +112,26 @@ impl App { multisample: multisample_state, }); + // Vertex buffer + let vertex_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(VERTICES), + usage: wgpu::BufferUsage::VERTEX, + } + ); + + // Index buffer + let index_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(INDICES), + usage: wgpu::BufferUsage::INDEX, + } + ); + // Save values in app - Self { surface, device, queue, swapchain_desc, swapchain, pipeline } + Self { surface, device, queue, swapchain_desc, swapchain, pipeline, vertex_buffer, index_buffer } } pub fn resize(&mut self, new_size: Option>) { @@ -145,7 +182,9 @@ impl App { }); render_pass.set_pipeline(&self.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..(INDICES.len() as u32), 0, 0..1); } // Submit encoder (command buffer) diff --git a/src/main.rs b/src/main.rs index 287c5e8..d268365 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use winit::{ dpi::LogicalSize }; +mod vertex; mod app; use app::App; @@ -68,6 +69,7 @@ fn main() { // The system is out of memory, we should probably quit Err(wgpu::SwapChainError::OutOfMemory) => *c = ControlFlow::Exit, // All other errors (Outdated, Timeout) should be resolved by the next frame + Err(wgpu::SwapChainError::Outdated) => (), Err(e) => eprintln!("{:?}", e), } } diff --git a/src/shader.frag b/src/shader.frag index 237a15b..9f09429 100644 --- a/src/shader.frag +++ b/src/shader.frag @@ -1,9 +1,10 @@ // shader.frag #version 450 -layout(location=0) out vec4 f_color; +layout(location=0) in vec3 vert_color; +layout(location=0) out vec4 frag_color; void main() { - f_color = vec4(0.3, 0.2, 0.1, 1.0); + frag_color = vec4(vert_color, 1.0); } \ No newline at end of file diff --git a/src/shader.vert b/src/shader.vert index 189f5c2..ecf2291 100644 --- a/src/shader.vert +++ b/src/shader.vert @@ -1,17 +1,12 @@ -// shader.vert #version 450 -const vec2 positions[3] = vec2[3]( - vec2(0.0, 0.5), - vec2(-0.5, -0.5), - vec2(0.5, -0.5) -); +layout(location=0) in vec3 in_position; +layout(location=1) in vec3 in_color; +layout(location=0) out vec3 vert_color; + void main() { - gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); -} - - - - \ No newline at end of file + vert_color = in_color; + gl_Position = vec4(in_position, 1.0); +} \ No newline at end of file diff --git a/src/vertex.rs b/src/vertex.rs new file mode 100644 index 0000000..8f26feb --- /dev/null +++ b/src/vertex.rs @@ -0,0 +1,31 @@ + + +#[repr(C)] +#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] +pub struct Vertex { + pub position: [f32; 3], + pub 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, + attributes: &[ + // position + wgpu::VertexAttribute { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float3, + }, + // color + wgpu::VertexAttribute { + offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, + shader_location: 1, + format: wgpu::VertexFormat::Float3, + } + ] + } + } +} \ No newline at end of file