|
|
|
@ -3,6 +3,7 @@ use winit::{
|
|
|
|
|
event_loop::{EventLoop, ControlFlow},
|
|
|
|
|
window::{Window, WindowBuilder},
|
|
|
|
|
};
|
|
|
|
|
use wgpu::util::DeviceExt;
|
|
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
|
|
@ -16,9 +17,8 @@ unsafe impl bytemuck::Zeroable for Vertex {}
|
|
|
|
|
|
|
|
|
|
impl Vertex {
|
|
|
|
|
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
|
|
|
|
use std::mem;
|
|
|
|
|
wgpu::VertexBufferDescriptor {
|
|
|
|
|
stride: mem::size_of::<Vertex>() as wgpu::BufferAddress,
|
|
|
|
|
stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
|
|
|
|
|
step_mode: wgpu::InputStepMode::Vertex,
|
|
|
|
|
attributes: &[
|
|
|
|
|
wgpu::VertexAttributeDescriptor {
|
|
|
|
@ -27,7 +27,7 @@ impl Vertex {
|
|
|
|
|
format: wgpu::VertexFormat::Float3,
|
|
|
|
|
},
|
|
|
|
|
wgpu::VertexAttributeDescriptor {
|
|
|
|
|
offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
|
|
|
|
|
offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
|
|
|
|
|
shader_location: 1,
|
|
|
|
|
format: wgpu::VertexFormat::Float3,
|
|
|
|
|
},
|
|
|
|
@ -75,22 +75,25 @@ impl State {
|
|
|
|
|
async fn new(window: &Window) -> Self {
|
|
|
|
|
let size = window.inner_size();
|
|
|
|
|
|
|
|
|
|
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, // Vulkan + Metal + DX12 + Browser WebGPU
|
|
|
|
|
).await.unwrap();
|
|
|
|
|
|
|
|
|
|
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor {
|
|
|
|
|
extensions: wgpu::Extensions {
|
|
|
|
|
anisotropic_filtering: false,
|
|
|
|
|
let (device, queue) = adapter.request_device(
|
|
|
|
|
&wgpu::DeviceDescriptor {
|
|
|
|
|
features: wgpu::Features::empty(),
|
|
|
|
|
limits: wgpu::Limits::default(),
|
|
|
|
|
shader_validation: true,
|
|
|
|
|
},
|
|
|
|
|
limits: Default::default(),
|
|
|
|
|
}).await;
|
|
|
|
|
None, // Trace path
|
|
|
|
|
).await.unwrap();
|
|
|
|
|
|
|
|
|
|
let sc_desc = wgpu::SwapChainDescriptor {
|
|
|
|
|
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
|
|
|
@ -101,65 +104,72 @@ impl State {
|
|
|
|
|
};
|
|
|
|
|
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
|
|
|
|
|
|
|
|
|
|
let vs_src = include_str!("shader.vert");
|
|
|
|
|
let fs_src = include_str!("shader.frag");
|
|
|
|
|
let mut compiler = shaderc::Compiler::new().unwrap();
|
|
|
|
|
let vs_spirv = compiler.compile_into_spirv(vs_src, shaderc::ShaderKind::Vertex, "shader.vert", "main", None).unwrap();
|
|
|
|
|
let fs_spirv = compiler.compile_into_spirv(fs_src, shaderc::ShaderKind::Fragment, "shader.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 render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
|
|
|
|
bind_group_layouts: &[],
|
|
|
|
|
});
|
|
|
|
|
let vs_module = device.create_shader_module(wgpu::include_spirv!("shader.vert.spv"));
|
|
|
|
|
let fs_module = device.create_shader_module(wgpu::include_spirv!("shader.frag.spv"));
|
|
|
|
|
|
|
|
|
|
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
|
|
|
|
layout: &render_pipeline_layout,
|
|
|
|
|
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
|
|
|
|
module: &vs_module,
|
|
|
|
|
entry_point: "main",
|
|
|
|
|
},
|
|
|
|
|
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
|
|
|
|
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,
|
|
|
|
|
}),
|
|
|
|
|
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
|
|
|
|
color_states: &[
|
|
|
|
|
wgpu::ColorStateDescriptor {
|
|
|
|
|
format: sc_desc.format,
|
|
|
|
|
color_blend: wgpu::BlendDescriptor::REPLACE,
|
|
|
|
|
alpha_blend: wgpu::BlendDescriptor::REPLACE,
|
|
|
|
|
write_mask: wgpu::ColorWrite::ALL,
|
|
|
|
|
let render_pipeline_layout = device.create_pipeline_layout(
|
|
|
|
|
&wgpu::PipelineLayoutDescriptor {
|
|
|
|
|
label: Some("Render Pipeline Layout"),
|
|
|
|
|
bind_group_layouts: &[],
|
|
|
|
|
push_constant_ranges: &[],
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let render_pipeline = device.create_render_pipeline(
|
|
|
|
|
&wgpu::RenderPipelineDescriptor {
|
|
|
|
|
label: Some("Render Pipeline"),
|
|
|
|
|
layout: Some(&render_pipeline_layout),
|
|
|
|
|
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
|
|
|
|
module: &vs_module,
|
|
|
|
|
entry_point: "main",
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
depth_stencil_state: None,
|
|
|
|
|
vertex_state: wgpu::VertexStateDescriptor {
|
|
|
|
|
index_format: wgpu::IndexFormat::Uint16,
|
|
|
|
|
vertex_buffers: &[
|
|
|
|
|
Vertex::desc(),
|
|
|
|
|
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
|
|
|
|
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,
|
|
|
|
|
clamp_depth: false,
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
|
|
|
|
color_states: &[
|
|
|
|
|
wgpu::ColorStateDescriptor {
|
|
|
|
|
format: sc_desc.format,
|
|
|
|
|
color_blend: wgpu::BlendDescriptor::REPLACE,
|
|
|
|
|
alpha_blend: wgpu::BlendDescriptor::REPLACE,
|
|
|
|
|
write_mask: wgpu::ColorWrite::ALL,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
sample_count: 1,
|
|
|
|
|
sample_mask: !0,
|
|
|
|
|
alpha_to_coverage_enabled: false,
|
|
|
|
|
});
|
|
|
|
|
depth_stencil_state: None,
|
|
|
|
|
vertex_state: wgpu::VertexStateDescriptor {
|
|
|
|
|
index_format: wgpu::IndexFormat::Uint16,
|
|
|
|
|
vertex_buffers: &[Vertex::desc()],
|
|
|
|
|
},
|
|
|
|
|
sample_count: 1,
|
|
|
|
|
sample_mask: !0,
|
|
|
|
|
alpha_to_coverage_enabled: false,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let vertex_buffer = device.create_buffer_with_data(
|
|
|
|
|
bytemuck::cast_slice(VERTICES),
|
|
|
|
|
wgpu::BufferUsage::VERTEX,
|
|
|
|
|
let vertex_buffer = device.create_buffer_init(
|
|
|
|
|
&wgpu::util::BufferInitDescriptor {
|
|
|
|
|
label: Some("Vertex Buffer"),
|
|
|
|
|
contents: bytemuck::cast_slice(VERTICES),
|
|
|
|
|
usage: wgpu::BufferUsage::VERTEX,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
let index_buffer = device.create_buffer_with_data(
|
|
|
|
|
bytemuck::cast_slice(INDICES),
|
|
|
|
|
wgpu::BufferUsage::INDEX,
|
|
|
|
|
let index_buffer = device.create_buffer_init(
|
|
|
|
|
&wgpu::util::BufferInitDescriptor {
|
|
|
|
|
label: Some("Index Buffer"),
|
|
|
|
|
contents: bytemuck::cast_slice(INDICES),
|
|
|
|
|
usage: wgpu::BufferUsage::INDEX,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
let num_indices = INDICES.len() as u32;
|
|
|
|
|
|
|
|
|
@ -187,13 +197,19 @@ impl State {
|
|
|
|
|
}).collect::<Vec<_>>();
|
|
|
|
|
let num_challenge_indices = challenge_indices.len() as u32;
|
|
|
|
|
|
|
|
|
|
let challenge_vertex_buffer = device.create_buffer_with_data(
|
|
|
|
|
bytemuck::cast_slice(&challenge_verts),
|
|
|
|
|
wgpu::BufferUsage::VERTEX,
|
|
|
|
|
let challenge_vertex_buffer = device.create_buffer_init(
|
|
|
|
|
&wgpu::util::BufferInitDescriptor {
|
|
|
|
|
label: Some("Challenge Vertex Buffer"),
|
|
|
|
|
contents: bytemuck::cast_slice(&challenge_verts),
|
|
|
|
|
usage: wgpu::BufferUsage::VERTEX,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
let challenge_index_buffer = device.create_buffer_with_data(
|
|
|
|
|
bytemuck::cast_slice(&challenge_indices),
|
|
|
|
|
wgpu::BufferUsage::INDEX,
|
|
|
|
|
let challenge_index_buffer = device.create_buffer_init(
|
|
|
|
|
&wgpu::util::BufferInitDescriptor {
|
|
|
|
|
label: Some("Challenge Index Buffer"),
|
|
|
|
|
contents: bytemuck::cast_slice(&challenge_indices),
|
|
|
|
|
usage: wgpu::BufferUsage::INDEX,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let use_complex = false;
|
|
|
|
@ -246,8 +262,9 @@ impl State {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn render(&mut self) {
|
|
|
|
|
let frame = self.swap_chain.get_next_texture()
|
|
|
|
|
.expect("Timeout getting texture");
|
|
|
|
|
let frame = self.swap_chain.get_current_frame()
|
|
|
|
|
.expect("Timeout getting texture")
|
|
|
|
|
.output;
|
|
|
|
|
|
|
|
|
|
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
|
|
|
|
label: Some("Render Encoder"),
|
|
|
|
@ -259,14 +276,17 @@ impl State {
|
|
|
|
|
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,
|
|
|
|
|
},
|
|
|
|
|
ops: wgpu::Operations {
|
|
|
|
|
load: wgpu::LoadOp::Clear(
|
|
|
|
|
wgpu::Color {
|
|
|
|
|
r: 0.1,
|
|
|
|
|
g: 0.2,
|
|
|
|
|
b: 0.3,
|
|
|
|
|
a: 1.0,
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
store: true,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
depth_stencil_attachment: None,
|
|
|
|
@ -287,15 +307,13 @@ impl State {
|
|
|
|
|
self.num_indices,
|
|
|
|
|
)
|
|
|
|
|
};
|
|
|
|
|
render_pass.set_vertex_buffer(0, data.0, 0, 0);
|
|
|
|
|
render_pass.set_index_buffer(data.1, 0, 0);
|
|
|
|
|
render_pass.set_vertex_buffer(0, data.0.slice(..));
|
|
|
|
|
render_pass.set_index_buffer(data.1.slice(..));
|
|
|
|
|
|
|
|
|
|
render_pass.draw_indexed(0..data.2, 0, 0..1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.queue.submit(&[
|
|
|
|
|
encoder.finish()
|
|
|
|
|
]);
|
|
|
|
|
self.queue.submit(Some(encoder.finish()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|