migrated pong code

pull/90/head
Ben Hansen 4 years ago
parent 801ee97038
commit 18bbd52f0e

90
Cargo.lock generated

@ -1,5 +1,19 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "ab_glyph"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ab_glyph_rasterizer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"owned_ttf_parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ab_glyph_rasterizer"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "addr2line"
version = "0.13.0"
@ -442,6 +456,15 @@ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-channel"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-deque"
version = "0.7.3"
@ -1051,24 +1074,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "glyph_brush"
version = "0.6.3"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"glyph_brush_layout 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"glyph_brush_draw_cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glyph_brush_layout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"ordered-float 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rusttype 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
"twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glyph_brush_draw_cache"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ab_glyph 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"linked-hash-map 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glyph_brush_layout"
version = "0.1.9"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ab_glyph 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rusttype 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
"xi-unicode 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1668,6 +1704,14 @@ dependencies = [
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "owned_ttf_parser"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ttf-parser 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot"
version = "0.10.2"
@ -1817,15 +1861,17 @@ dependencies = [
name = "pong"
version = "0.1.0"
dependencies = [
"anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
"bytemuck 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rodio 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"shaderc 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu_glyph 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu_glyph 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winit 0.22.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2132,12 +2178,7 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"linked-hash-map 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ordered-float 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"stb_truetype 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2396,6 +2437,11 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ttf-parser"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "tutorial1-window"
version = "0.1.0"
@ -2905,12 +2951,12 @@ dependencies = [
[[package]]
name = "wgpu_glyph"
version = "0.8.0"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"glyph_brush 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"glyph_brush 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zerocopy 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3094,6 +3140,8 @@ dependencies = [
]
[metadata]
"checksum ab_glyph 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5b50c188ff14b5a6efeb38eee8ccbc505cdf61e347a3d5eb04dc55d74ae4f20e"
"checksum ab_glyph_rasterizer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2692800d602527d2b8fea50036119c37df74ab565b10e285706a3dcec0ec3e16"
"checksum addr2line 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
"checksum adler 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
"checksum adler32 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
@ -3146,6 +3194,7 @@ dependencies = [
"checksum coreaudio-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d6570ee6e089131e928d5ec9236db9e818aa3cf850f48b0eec6ef700571271d4"
"checksum cpal 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b55d55d69f403f62a95bd3c04b431e0aedf5120c70f15d07a8edd234443dd59"
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
"checksum crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
"checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
"checksum crossbeam-queue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
@ -3200,8 +3249,9 @@ dependencies = [
"checksum gif 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af"
"checksum gimli 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum glyph_brush 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5fca6f9d679bff1322c76c9a1ad4b8553b30a94f3f75bea6936e19032c2f2ec3"
"checksum glyph_brush_layout 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "8b70adc570f1dc71b6b32e241cbcc2b42175f5aea71951fbf41e68b04aec24c7"
"checksum glyph_brush 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afd3e2cfd503a5218dd56172a8bf7c8655a4a7cf745737c606a6edfeea1b343f"
"checksum glyph_brush_draw_cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e5f15abf9569e0b4440797efc0d565c8f30c4a1ca8b0b0c10c0fb7fb2a343c82"
"checksum glyph_brush_layout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9aa49abf7dcf7bfe68f42c1c8ab7473505aaba14de84afb8899a0109b6c61717"
"checksum hermit-abi 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
"checksum hibitset 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "93a1bb8316a44459a7d14253c4d28dd7395cbd23cc04a68c46e851b8e46d64b1"
"checksum hound 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549"
@ -3268,6 +3318,7 @@ dependencies = [
"checksum ogg 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d79f1db9148be9d0e174bb3ac890f6030fcb1ed947267c5a91ee4c91b5a91e15"
"checksum once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
"checksum ordered-float 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3741934be594d77de1c8461ebcbbe866f585ea616a9753aa78f2bdc69f0e4579"
"checksum owned_ttf_parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb477c7fd2a3a6e04e1dc6ca2e4e9b04f2df702021dc5a5d1cf078c587dc59f7"
"checksum parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
"checksum parking_lot 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
"checksum parking_lot_core 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
@ -3351,6 +3402,7 @@ dependencies = [
"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
"checksum tracing 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
"checksum tracing-core 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "db63662723c316b43ca36d833707cc93dff82a02ba3d7e354f342682cc8b3545"
"checksum ttf-parser 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d973cfa0e6124166b50a1105a67c85de40bbc625082f35c0f56f84cb1fb0a827"
"checksum twox-hash 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56"
"checksum typed-arena 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
@ -3379,7 +3431,7 @@ dependencies = [
"checksum wgpu-native 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f1ac9838b0715d7911352db1268e34dfd05ef347fbef0b65ae211268316a432"
"checksum wgpu-types 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3474b5ce2ed628e158c2fe4387a469b2ee119604556aa2debd10d830cedc3bc"
"checksum wgpu-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6fb82203cfaa5165e6eb9f1daca5b0ba8a2b8d632f6c9a7f9b10463b145deb2b"
"checksum wgpu_glyph 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7fabe70968bf2cadd4055d2f36c38233936c3344db4597c542ec185df05dd97a"
"checksum wgpu_glyph 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27812a263e1298d3330795af62faf5daf5852beb632794acf93e4494234fc9f4"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"

@ -1,262 +0,0 @@
use anyhow::Result;
use cgmath::*;
use rand::Rng;
use std::path::Path;
use std::time::Duration;
use framework::prelude::*;
#[derive(Debug, Copy, Clone)]
#[repr(C)]
struct InstanceData {
model_matrix: Matrix4<f32>,
}
unsafe impl bytemuck::Pod for InstanceData {}
unsafe impl bytemuck::Zeroable for InstanceData {}
struct StorageBuffersDemo<'a> {
depth_texture: framework::Texture<'a>,
cube_model: framework::Model<'a>,
model_pipeline: wgpu::RenderPipeline,
instances: Vec<InstanceData>,
instance_buffer: wgpu::Buffer,
instance_bind_group: wgpu::BindGroup,
uniforms: framework::Uniforms,
uniform_binding: framework::UniformBinding,
camera: framework::Camera,
controller: framework::CameraController,
projection: framework::Projection,
}
impl framework::Demo for StorageBuffersDemo<'static> {
fn init(display: &framework::Display) -> Result<Self> {
let texture_layout = display.device.create_bind_group_layout(
&wgpu::BindGroupLayoutDescriptor {
bindings: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::SampledTexture {
multisampled: false,
component_type: wgpu::TextureComponentType::Float,
dimension: wgpu::TextureViewDimension::D2,
}
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler { comparison: false },
},
// normal map
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::SampledTexture {
multisampled: false,
component_type: wgpu::TextureComponentType::Float,
dimension: wgpu::TextureViewDimension::D2,
},
},
wgpu::BindGroupLayoutEntry {
binding: 3,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler { comparison: false },
},
],
label: Some("texture_layout")
}
);
let depth_texture = framework::Texture::create_depth_texture(&display.device, &display.sc_desc);
let mut res_cmds = Vec::new();
let res_dir = Path::new(env!("OUT_DIR")).join("res");
let (cube_model, cmds) = framework::Model::load(
&display.device,
&texture_layout,
res_dir.join("cube.obj")
)?;
res_cmds.extend(cmds);
let mut encoder = display.device.create_command_encoder(
&wgpu::CommandEncoderDescriptor {
label: Some("init::encoder")
}
);
let (camera, projection, controller) = framework::camera_setup(
(0.0, 5.0, 10.0),
cgmath::Deg(-90.0),
cgmath::Deg(-20.0),
display.sc_desc.width,
display.sc_desc.height,
);
let mut uniforms = framework::Uniforms::new(&display.device);
uniforms.update_view_proj(&camera, &projection);
uniforms.update_buffer(&display.device, &mut encoder);
let uniform_binding = framework::UniformBinding::new(&display.device, &uniforms);
const NUM_INSTANCES: u32 = 100;
const RADIUS: f32 = 50.0;
let instances = (0..NUM_INSTANCES).map(|_| {
let mut rng = rand::thread_rng();
let position = Vector3::new(
rng.gen_range(-RADIUS, RADIUS),
rng.gen_range(-RADIUS, RADIUS),
rng.gen_range(-RADIUS, RADIUS),
);
let model_matrix = Matrix4::from_translation(position);
InstanceData { model_matrix }
}).collect::<Vec<_>>();
let instance_buffer = display.device.create_buffer_with_data(
bytemuck::cast_slice(&instances),
wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::STORAGE_READ,
);
let instance_layout = display.device.create_bind_group_layout(
&wgpu::BindGroupLayoutDescriptor {
label: Some("instance_layout"),
bindings: &[
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX,
ty: wgpu::BindingType::StorageBuffer {
dynamic: false,
readonly: true,
},
},
]
}
);
let instance_buffer_size = instances.len() * std::mem::size_of::<InstanceData>();
let instance_bind_group = display.device.create_bind_group(
&wgpu::BindGroupDescriptor {
label: Some("instance_bind_group"),
layout: &instance_layout,
bindings: &[
wgpu::Binding {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: &instance_buffer,
range: 0..instance_buffer_size as _,
},
},
]
}
);
let model_layout = display.device.create_pipeline_layout(
&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[
&texture_layout,
&uniform_binding.layout,
&instance_layout,
],
}
);
let model_pipeline = framework::RenderPipelineBuilder::new()
.layout(&model_layout)
.depth_format(framework::Texture::DEPTH_FORMAT)
.color_solid(display.sc_desc.format)
.vertex_buffer::<framework::ModelVertex>()
.vertex_shader(include_bytes!("shader.vert.spv"))
.fragment_shader(include_bytes!("shader.frag.spv"))
.build(&display.device)?;
res_cmds.push(encoder.finish());
display.queue.submit(&res_cmds);
Ok(Self {
depth_texture,
cube_model,
model_pipeline,
instances,
instance_buffer,
instance_bind_group,
uniforms,
uniform_binding,
camera,
controller,
projection,
})
}
fn process_mouse(&mut self, dx: f64, dy: f64) {
self.controller.process_mouse(dx, dy);
}
fn resize(&mut self, display: &framework::Display) {
}
fn update(&mut self, display: &framework::Display, dt: Duration) {
self.controller.update_camera(&mut self.camera, dt);
self.uniforms.update_view_proj(&self.camera, &self.projection);
let mut encoder = display.device.create_command_encoder(
&wgpu::CommandEncoderDescriptor {
label: Some("update::encoder")
}
);
self.uniforms.update_buffer(&display.device, &mut encoder);
display.queue.submit(&[encoder.finish()]);
}
fn render(&mut self, display: &mut framework::Display) {
let mut encoder = display.device.create_command_encoder(
&wgpu::CommandEncoderDescriptor { label: Some("render::encoder")}
);
let mut frame = display.swap_chain.get_next_texture().expect("Timeout");
{
let mut pass = encoder.begin_render_pass(
&wgpu::RenderPassDescriptor {
color_attachments: &[
wgpu::RenderPassColorAttachmentDescriptor {
attachment: &frame.view,
resolve_target: None,
load_op: wgpu::LoadOp::Clear,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color {
r: 0.1,
g: 0.2,
b: 0.3,
a: 1.0,
},
}
],
depth_stencil_attachment: Some(
wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &self.depth_texture.view,
depth_load_op: wgpu::LoadOp::Clear,
depth_store_op: wgpu::StoreOp::Store,
clear_depth: 1.0,
stencil_load_op: wgpu::LoadOp::Clear,
stencil_store_op: wgpu::StoreOp::Store,
clear_stencil: 0,
}
)
}
);
pass.set_pipeline(&self.model_pipeline);
pass.set_bind_group(0, &self.uniform_binding.bind_group, &[]);
// pass.set_bind_group(1, &self.light_binding.bind_group, &[]);
for mesh in &self.cube_model.meshes {
let mat = &self.cube_model.materials[mesh.material];
pass.set_bind_group(2, &mat.bind_group, &[]);
pass.draw_indexed(0..mesh.num_elements, 0, 0..self.instances.len() as _);
}
}
}
}
fn main() -> Result<()> {
futures::executor::block_on(framework::run::<StorageBuffersDemo>())
}

@ -7,14 +7,17 @@ edition = "2018"
[dependencies]
winit = "0.22"
shaderc = "0.6"
failure = "0.1"
bytemuck = "1.2"
futures = "0.3.5"
wgpu = "0.5.0"
wgpu_glyph = "0.8.0"
rand = "0.7.3"
rodio = "0.11.0"
anyhow = "1.0"
bytemuck = "1.4"
cgmath = "0.17"
futures = "0.3"
wgpu = "0.6"
wgpu_glyph = "0.10"
rand = "0.7"
rodio = "0.11"
[dependencies.cgmath]
version = "0.17"
features = ["swizzle"]
[build-dependencies]
anyhow = "1.0"
fs_extra = "1.2"
glob = "0.3"
shaderc = "0.6"

@ -0,0 +1,91 @@
use anyhow::*;
use fs_extra::copy_items;
use fs_extra::dir::CopyOptions;
use glob::glob;
use std::env;
use std::fs::{read_to_string, write};
use std::path::{PathBuf};
struct ShaderData {
src: String,
src_path: PathBuf,
spv_path: PathBuf,
kind: shaderc::ShaderKind,
}
impl ShaderData {
pub fn load(src_path: PathBuf) -> Result<Self> {
let extension = src_path.extension()
.context("File has no extension")?
.to_str()
.context("Extension cannot be converted to &str")?;
let kind = match extension {
"vert" => shaderc::ShaderKind::Vertex,
"frag" => shaderc::ShaderKind::Fragment,
"comp" => shaderc::ShaderKind::Compute,
_ => bail!("Unsupported shader: {}", src_path.display()),
};
let src = read_to_string(src_path.clone())?;
let spv_path = src_path.with_extension(format!("{}.spv", extension));
Ok(Self { src, src_path, spv_path, kind })
}
}
fn main() -> Result<()> {
// This tells cargo to rerun this script if something in /src/ changes.
println!("cargo:rerun-if-changed=res/*");
// Collect all shaders recursively within /src/
let mut shader_paths = [
glob("./res/**/*.vert")?,
glob("./res/**/*.frag")?,
glob("./res/**/*.comp")?,
];
// This could be parallelized
let shaders = shader_paths.iter_mut()
.flatten()
.map(|glob_result| {
ShaderData::load(glob_result?)
})
.collect::<Vec<Result<_>>>()
.into_iter()
.collect::<Result<Vec<_>>>();
let mut compiler = shaderc::Compiler::new()
.context("Unable to create shader compiler")?;
// This can't be parallelized. The [shaderc::Compiler] is not
// thread safe. Also, it creates a lot of resources. You could
// spawn multiple processes to handle this, but it would probably
// be better just to only compile shaders that have been changed
// recently.
for shader in shaders? {
let compiled = compiler.compile_into_spirv(
&shader.src,
shader.kind,
&shader.src_path.to_str().unwrap(),
"main",
None
)?;
write(shader.spv_path, compiled.as_binary_u8())?;
}
// This tells cargo to rerun this script if something in /res/ changes.
println!("cargo:rerun-if-changed=res/*");
let out_dir = env::var("OUT_DIR")?;
let mut copy_options = CopyOptions::new();
copy_options.overwrite = true;
let mut paths_to_copy = Vec::new();
paths_to_copy.push("res/");
match copy_items(&paths_to_copy, out_dir, &copy_options) {
Ok(_) => {}
Err(e) => eprintln!("{}", e),
}
Ok(())
}

@ -1,5 +1,6 @@
use crate::util::size_of_slice;
use crate::state;
use wgpu::util::{BufferInitDescriptor, DeviceExt};
pub const U32_SIZE: wgpu::BufferAddress = std::mem::size_of::<u32>() as wgpu::BufferAddress;
@ -108,9 +109,12 @@ pub struct StagingBuffer {
impl StagingBuffer {
pub fn new<T: bytemuck::Pod + Sized>(device: &wgpu::Device, data: &[T]) -> StagingBuffer {
StagingBuffer {
buffer: device.create_buffer_with_data(
bytemuck::cast_slice(data),
wgpu::BufferUsage::COPY_SRC,
buffer: device.create_buffer_init(
&BufferInitDescriptor {
contents: bytemuck::cast_slice(data),
usage: wgpu::BufferUsage::COPY_SRC,
label: Some("Staging Buffer"),
}
),
size: size_of_slice(data) as wgpu::BufferAddress
}

@ -2,6 +2,7 @@ mod buffer;
use winit::window::{Window};
use winit::monitor::{VideoMode};
use wgpu_glyph::{ab_glyph, Section, Text};
use buffer::*;
@ -14,7 +15,6 @@ pub struct Render {
surface: wgpu::Surface,
#[allow(dead_code)]
adapter: wgpu::Adapter,
device: wgpu::Device,
queue: wgpu::Queue,
sc_desc: wgpu::SwapChainDescriptor,
@ -22,7 +22,8 @@ pub struct Render {
pipeline: wgpu::RenderPipeline,
vertex_buffer: wgpu::Buffer,
index_buffer: wgpu::Buffer,
glyph_brush: wgpu_glyph::GlyphBrush<'static, ()>,
glyph_brush: wgpu_glyph::GlyphBrush<()>,
staging_belt: wgpu::util::StagingBelt,
}
impl Render {
@ -36,20 +37,24 @@ impl Render {
}
pub async fn new(window: &Window, video_mode: &VideoMode) -> Self {
let surface = wgpu::Surface::create(window);
let adapter = wgpu::Adapter::request(
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
let surface = unsafe { instance.create_surface(window) };
let adapter = instance.request_adapter(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY,
},
).await.unwrap();
let (device, queue) = adapter.request_device(
&wgpu::DeviceDescriptor {
features: wgpu::Features::empty(),
limits: wgpu::Limits::default(),
shader_validation: true,
},
None, // Trace path
).await.unwrap();
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {
extensions: Default::default(),
limits: Default::default(),
}).await;
let size = video_mode.size();
let sc_desc = wgpu::SwapChainDescriptor {
@ -61,33 +66,40 @@ impl Render {
};
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[]
});
let pipeline_layout = device.create_pipeline_layout(
&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[],
push_constant_ranges: &[],
label: Some("Pipeline Layout"),
}
);
let pipeline = create_render_pipeline(
&device,
&pipeline_layout,
sc_desc.format,
&[Vertex::DESC],
include_str!("../../res/shaders/textured.vert"),
include_str!("../../res/shaders/textured.frag"),
wgpu::include_spirv!("../../res/shaders/textured.vert.spv"),
wgpu::include_spirv!("../../res/shaders/textured.frag.spv"),
);
let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: Vertex::SIZE * 4 * 3,
usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
let index_buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: U32_SIZE * 6 * 3,
usage: wgpu::BufferUsage::INDEX | wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
let font = wgpu_glyph::Font::from_bytes(FONT_BYTES).unwrap();
let font = ab_glyph::FontArc::try_from_slice(FONT_BYTES).unwrap();
let glyph_brush = wgpu_glyph::GlyphBrushBuilder::using_font(font)
.build(&device, sc_desc.format);
let staging_belt = wgpu::util::StagingBelt::new(1024);
Self {
surface,
@ -100,6 +112,7 @@ impl Render {
vertex_buffer,
index_buffer,
glyph_brush,
staging_belt,
}
}
@ -125,64 +138,72 @@ impl Render {
0
};
let frame = self.swap_chain.get_next_texture().unwrap();
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[
wgpu::RenderPassColorAttachmentDescriptor {
attachment: &frame.view,
resolve_target: None,
load_op: wgpu::LoadOp::Clear,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color::BLACK,
},
],
depth_stencil_attachment: None,
});
if num_indices != 0 {
render_pass.set_vertex_buffer(0, &self.vertex_buffer, 0, 0);
render_pass.set_index_buffer(&self.index_buffer, 0, 0);
render_pass.set_pipeline(&self.pipeline);
render_pass.draw_indexed(0..num_indices, 0, 0..1);
}
drop(render_pass);
if state.title_text.visible {
draw_text(&state.title_text, &mut self.glyph_brush);
}
if state.play_button.visible {
draw_text(&state.play_button, &mut self.glyph_brush);
}
if state.quit_button.visible {
draw_text(&state.quit_button, &mut self.glyph_brush);
}
if state.player1_score.visible {
draw_text(&state.player1_score, &mut self.glyph_brush);
}
if state.player2_score.visible {
draw_text(&state.player2_score, &mut self.glyph_brush);
}
if state.win_text.visible {
draw_text(&state.win_text, &mut self.glyph_brush);
match self.swap_chain.get_current_frame() {
Ok(frame) => {
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[
wgpu::RenderPassColorAttachmentDescriptor {
attachment: &frame.output.view,
resolve_target: None,
ops: wgpu::Operations::default(),
},
],
depth_stencil_attachment: None,
});
if num_indices != 0 {
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
render_pass.set_index_buffer(self.index_buffer.slice(..));
render_pass.set_pipeline(&self.pipeline);
render_pass.draw_indexed(0..num_indices, 0, 0..1);
}
drop(render_pass);
if state.title_text.visible {
draw_text(&state.title_text, &mut self.glyph_brush);
}
if state.play_button.visible {
draw_text(&state.play_button, &mut self.glyph_brush);
}
if state.quit_button.visible {
draw_text(&state.quit_button, &mut self.glyph_brush);
}
if state.player1_score.visible {
draw_text(&state.player1_score, &mut self.glyph_brush);
}
if state.player2_score.visible {
draw_text(&state.player2_score, &mut self.glyph_brush);
}
if state.win_text.visible {
draw_text(&state.win_text, &mut self.glyph_brush);
}
self.glyph_brush.draw_queued(
&self.device,
&mut self.staging_belt,
&mut encoder,
&frame.output.view,
self.sc_desc.width,
self.sc_desc.height,
).unwrap();
self.staging_belt.finish();
self.queue.submit(Some(encoder.finish()));
}
Err(wgpu::SwapChainError::Outdated) => {
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
}
Err(e) => {
eprintln!("Error: {}", e);
}
}
self.glyph_brush.draw_queued(
&self.device,
&mut encoder,
&frame.view,
self.sc_desc.width,
self.sc_desc.height,
).unwrap();
self.queue.submit(&[encoder.finish()]);
}
}
fn draw_text(
text: &state::Text,
glyph_brush: &mut wgpu_glyph::GlyphBrush<'static, ()>,
glyph_brush: &mut wgpu_glyph::GlyphBrush<()>,
) {
let layout = wgpu_glyph::Layout::default()
.h_align(
@ -192,22 +213,21 @@ fn draw_text(
wgpu_glyph::HorizontalAlign::Left
}
);
let scale = {
let mut size = text.size;
if text.focused {
size += 8.0;
}
wgpu_glyph::Scale::uniform(size)
};
let section = wgpu_glyph::Section {
text: &text.text,
screen_position: (text.position.x, text.position.y),
bounds: (text.bounds.x, text.bounds.y),
color: text.color.into(),
scale,
let section = Section {
screen_position: text.position.into(),
bounds: text.bounds.into(),
layout,
..Default::default()
};
..Section::default()
}.add_text(
Text::new(&text.text)
.with_color(text.color)
.with_scale(if text.focused {
text.size + 8.0
} else {
text.size
})
);
glyph_brush.queue(section);
}
@ -217,19 +237,15 @@ fn create_render_pipeline(
layout: &wgpu::PipelineLayout,
color_format: wgpu::TextureFormat,
vertex_descs: &[wgpu::VertexBufferDescriptor],
vs_src: &str,
fs_src: &str,
vs_src: wgpu::ShaderModuleSource,
fs_src: wgpu::ShaderModuleSource,
) -> wgpu::RenderPipeline {
let mut compiler = shaderc::Compiler::new().unwrap();
let vs_spirv = compiler.compile_into_spirv(vs_src, shaderc::ShaderKind::Vertex, "vert", "main", None).unwrap();
let fs_spirv = compiler.compile_into_spirv(fs_src, shaderc::ShaderKind::Fragment, "frag", "main", None).unwrap();
let vs_data = wgpu::read_spirv(std::io::Cursor::new(vs_spirv.as_binary_u8())).unwrap();
let fs_data = wgpu::read_spirv(std::io::Cursor::new(fs_spirv.as_binary_u8())).unwrap();
let vs_module = device.create_shader_module(&vs_data);
let fs_module = device.create_shader_module(&fs_data);
let vs_module = device.create_shader_module(vs_src);
let fs_module = device.create_shader_module(fs_src);
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
layout: &layout,
label: Some("Render Pipeline"),
layout: Some(&layout),
vertex_stage: wgpu::ProgrammableStageDescriptor {
module: &vs_module,
entry_point: "main",
@ -238,13 +254,7 @@ fn create_render_pipeline(
module: &fs_module,
entry_point: "main",
}),
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::Back,
depth_bias: 0,
depth_bias_slope_scale: 0.0,
depth_bias_clamp: 0.0,
}),
rasterization_state: None,
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
color_states: &[wgpu::ColorStateDescriptor {
format: color_format,

Loading…
Cancel
Save