Improved renderer to display quad

This commit is contained in:
Steins7 2022-07-07 22:54:15 +02:00
parent 583aa10690
commit 7c01dfab75
4 changed files with 144 additions and 6 deletions

21
Cargo.lock generated
View File

@ -96,6 +96,26 @@ version = "3.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
[[package]]
name = "bytemuck"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c53dfa917ec274df8ed3c572698f381a24eef2efba9492d797301b72b6db408a"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562e382481975bc61d11275ac5e62a19abd00b0547d99516a415336f183dcd0e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.4.3" version = "1.4.3"
@ -117,6 +137,7 @@ name = "canvas"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"bytemuck",
"cgmath", "cgmath",
"chrono", "chrono",
"fern", "fern",

View File

@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
# general dependencies
log = "^0.4.17" log = "^0.4.17"
chrono = "^0.4.19" chrono = "^0.4.19"
fern = { version = "^0.6.1", features = ["colored"] } fern = { version = "^0.6.1", features = ["colored"] }
@ -13,7 +14,11 @@ bitflags = "^1.3.2"
cgmath = "^0.18.0" cgmath = "^0.18.0"
pollster = "^0.2.5" pollster = "^0.2.5"
# surface creation
winit = "^0.26.1" winit = "^0.26.1"
raw-window-handle = "^0.4.3" raw-window-handle = "^0.4.3"
# gpu API
wgpu = "^0.13.0" wgpu = "^0.13.0"
bytemuck = { version = "1.4", features = [ "derive" ] }

View File

@ -17,6 +17,7 @@ pub struct WgpuRenderer {
config: wgpu::SurfaceConfiguration, config: wgpu::SurfaceConfiguration,
size: Size, size: Size,
render_pipeline: wgpu::RenderPipeline, render_pipeline: wgpu::RenderPipeline,
quad_mesh: GpuMesh,
} }
impl WgpuRenderer { impl WgpuRenderer {
@ -62,24 +63,26 @@ impl WgpuRenderer {
let render_pipeline = { let render_pipeline = {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("test shader"), label: Some("shape shader"),
source: wgpu::ShaderSource::Wgsl(include_str!("shaders/test_shader.wgsl").into()), source: wgpu::ShaderSource::Wgsl(include_str!("shaders/shape.wgsl").into()),
}); });
let render_pipeline_layout = let render_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("test render pipeline layout"), label: Some("shape render pipeline layout"),
bind_group_layouts: &[], bind_group_layouts: &[],
push_constant_ranges: &[], push_constant_ranges: &[],
}); });
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("test render pipeline"), label: Some("shape render pipeline"),
layout: Some(&render_pipeline_layout), layout: Some(&render_pipeline_layout),
vertex: wgpu::VertexState { vertex: wgpu::VertexState {
module: &shader, module: &shader,
entry_point: "vs_main", entry_point: "vs_main",
buffers: &[], buffers: &[
Vertex::desc(),
],
}, },
fragment: Some(wgpu::FragmentState { fragment: Some(wgpu::FragmentState {
module: &shader, module: &shader,
@ -114,6 +117,8 @@ impl WgpuRenderer {
}) })
}; };
let quad_mesh = GpuMesh::create(&device, &QUAD);
Ok(Self { Ok(Self {
surface, surface,
device, device,
@ -121,6 +126,7 @@ impl WgpuRenderer {
config, config,
size, size,
render_pipeline, render_pipeline,
quad_mesh,
}) })
} }
@ -174,7 +180,10 @@ impl WgpuRenderer {
}); });
render_pass.set_pipeline(&self.render_pipeline); render_pass.set_pipeline(&self.render_pipeline);
render_pass.draw(0..3, 0..1); render_pass.set_vertex_buffer(0, self.quad_mesh.vertex_buffer.slice(..));
render_pass.set_index_buffer(self.quad_mesh.index_buffer.slice(..),
wgpu::IndexFormat::Uint16);
render_pass.draw_indexed(0..self.quad_mesh.index_number, 0, 0..1);
} }
self.queue.submit(std::iter::once(encoder.finish())); self.queue.submit(std::iter::once(encoder.finish()));
@ -182,3 +191,78 @@ impl WgpuRenderer {
} }
} }
struct GpuMesh {
vertex_buffer: wgpu::Buffer,
index_buffer: wgpu::Buffer,
index_number: u32,
}
impl GpuMesh {
pub fn create(device: &wgpu::Device, mesh: &Mesh) -> Self {
use wgpu::util::DeviceExt;
let vertex_buffer = device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: Some("Vertex Buffer"),
contents: bytemuck::cast_slice(mesh.vertices),
usage: wgpu::BufferUsages::VERTEX,
}
);
let index_buffer = device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: Some("Index Buffer"),
contents: bytemuck::cast_slice(mesh.indices),
usage: wgpu::BufferUsages::INDEX,
}
);
Self {
vertex_buffer,
index_buffer,
index_number: mesh.indices.len() as u32,
}
}
}
//--Renderer struct utils---------------------------------------------------------------------------
#[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
struct Vertex {
pub position: [f32; 2],
pub color: [f32; 3],
}
// lib.rs
impl Vertex {
const ATTRIBS: [wgpu::VertexAttribute; 2] =
wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x3];
fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &Self::ATTRIBS,
}
}
}
struct Mesh<'a> {
pub vertices: &'a[Vertex],
pub indices: &'a[u16],
}
const QUAD: Mesh<'static> = Mesh {
vertices: &[
Vertex { position: [0.0, 0.0], color: [1.0, 0.0, 0.0] },
Vertex { position: [1.0, 0.0], color: [0.0, 1.0, 0.0] },
Vertex { position: [1.0, 1.0], color: [0.0, 0.0, 1.0] },
Vertex { position: [0.0, 1.0], color: [0.5, 0.5, 0.5] },
],
indices: &[
0, 1, 2,
0, 2, 3,
],
};

28
src/shaders/shape.wgsl Normal file
View File

@ -0,0 +1,28 @@
// Vertex shader
struct VertexInput {
@location(0) position: vec2<f32>,
@location(1) color: vec3<f32>,
};
struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
@location(0) color: vec3<f32>,
};
@vertex
fn vs_main(model: VertexInput) -> VertexOutput {
var out: VertexOutput;
out.color = model.color;
out.clip_position = vec4<f32>(model.position, 0.0, 1.0);
return out;
}
// Fragment shader
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
return vec4<f32>(in.color, 1.0);
}