Update main.rs

This commit is contained in:
Pointu 2020-04-24 12:09:50 +08:00 committed by GitHub
parent a1059d5ccc
commit 13cbe0ca68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -158,6 +158,11 @@ impl Instance {
}
struct State {
surface: wgpu::Surface,
device: wgpu::Device,
queue: wgpu::Queue,
sc_desc: wgpu::SwapChainDescriptor,
swap_chain: wgpu::SwapChain,
render_pipeline: wgpu::RenderPipeline,
obj_model: model::Model,
camera: Camera,
@ -169,13 +174,41 @@ struct State {
instance_buffer: wgpu::Buffer,
depth_texture: wgpu::Texture,
depth_texture_view: wgpu::TextureView,
size: winit::dpi::PhysicalSize<u32>,
}
impl State {
fn new(
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
) -> (Self, Option<Vec<wgpu::CommandBuffer>>) {
async fn new(window: &Window) -> Self {
let size = window.inner_size();
let surface = wgpu::Surface::create(window);
let adapter = wgpu::Adapter::request(
&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,
},
limits: Default::default(),
}).await;
let sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb,
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Fifo,
};
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
@ -300,7 +333,7 @@ impl State {
"code/beginner/tutorial9-models/src/res/cube.obj",
)
.unwrap();
queue.submit(&cmds);
let vs_src = include_str!("shader.vert");
let fs_src = include_str!("shader.frag");
let vs_spirv = glsl_to_spirv::compile(vs_src, glsl_to_spirv::ShaderType::Vertex).unwrap();
@ -360,7 +393,12 @@ impl State {
},
});
let state = Self {
Self {
surface,
device,
queue,
sc_desc,
swap_chain,
render_pipeline,
obj_model,
camera,
@ -372,34 +410,31 @@ impl State {
instance_buffer,
depth_texture,
depth_texture_view,
};
(state, Some(cmds))
size,
}
}
fn resize(
&mut self,
sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
) -> Option<wgpu::CommandBuffer> {
self.depth_texture = texture::Texture::create_depth_texture(device, sc_desc).texture;
async fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
self.depth_texture = texture::Texture::create_depth_texture(&self.device, &self.sc_desc).texture;
self.depth_texture_view = self.depth_texture.create_default_view();
self.camera.aspect = sc_desc.width as f32 / sc_desc.height as f32;
None
self.camera.aspect = self.sc_desc.width as f32 / self.sc_desc.height as f32;
self.size = new_size;
self.sc_desc.width = new_size.width;
self.sc_desc.height = new_size.height;
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
}
fn input(&mut self, event: &WindowEvent) -> bool {
self.camera_controller.process_events(event)
}
fn update(&mut self, device: &wgpu::Device) -> Option<wgpu::CommandBuffer> {
async fn update(&mut self) {
self.camera_controller.update_camera(&mut self.camera);
self.uniforms.update_view_proj(&self.camera);
let mut encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
let staging_buffer = device.create_buffer_with_data(
let staging_buffer = self.device.create_buffer_with_data(
bytemuck::cast_slice(&[self.uniforms]),
wgpu::BufferUsage::COPY_SRC,
);
@ -412,16 +447,14 @@ impl State {
std::mem::size_of::<Uniforms>() as wgpu::BufferAddress,
);
Some(encoder.finish())
self.queue.submit(&[encoder.finish()]);
}
fn render(
&mut self,
frame: &wgpu::SwapChainOutput,
device: &wgpu::Device,
) -> wgpu::CommandBuffer {
async fn render(&mut self) {
let frame = self.swap_chain.get_next_texture()
.expect("Timeout getting texture");
let mut encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
{
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
@ -456,105 +489,10 @@ impl State {
);
}
encoder.finish()
self.queue.submit(&[encoder.finish()]);
}
}
async fn run_async(event_loop: EventLoop<()>, window: Window) {
let size = window.inner_size();
let surface = wgpu::Surface::create(&window);
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();
let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
let mut sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: if cfg!(target_arch = "wasm32") {
wgpu::TextureFormat::Bgra8Unorm
} else {
wgpu::TextureFormat::Bgra8UnormSrgb
},
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Mailbox,
};
let mut swap_chain = device.create_swap_chain(&surface, &sc_desc);
let (mut state, init_cmds_buf) = State::new(&sc_desc, &device);
if let Some(cmds_buf) = init_cmds_buf {
queue.submit(&cmds_buf);
}
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
Event::MainEventsCleared => window.request_redraw(),
Event::WindowEvent {
ref event,
window_id,
} if window_id == window.id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
WindowEvent::KeyboardInput { input, .. } => match input {
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
} => {
*control_flow = ControlFlow::Exit;
}
_ => {}
},
WindowEvent::Resized(physical_size) => {
sc_desc.width = physical_size.width;
sc_desc.height = physical_size.height;
swap_chain = device.create_swap_chain(&surface, &sc_desc);
let cmd_buf = state.resize(&sc_desc, &device);
if let Some(cmd_buf) = cmd_buf {
queue.submit(&[cmd_buf]);
}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
sc_desc.width = new_inner_size.width;
sc_desc.height = new_inner_size.height;
swap_chain = device.create_swap_chain(&surface, &sc_desc);
let cmd_buf = state.resize(&sc_desc, &device);
if let Some(cmd_buf) = cmd_buf {
queue.submit(&[cmd_buf]);
}
}
_ => {}
}
}
}
Event::RedrawRequested(_) => {
if let Some(cmd_buf) = state.update(&device) {
queue.submit(&[cmd_buf]);
}
let frame = swap_chain
.get_next_texture()
.expect("Timeout when acquiring next swap chain texture");
let command_buf = state.render(&frame, &device);
queue.submit(&[command_buf]);
}
_ => {}
}
});
}
fn main() {
let event_loop = EventLoop::new();
let title = "tutorial9-models";
@ -562,7 +500,46 @@ fn main() {
.with_title(title)
.build(&event_loop)
.unwrap();
futures::executor::block_on(run_async(event_loop, window));
use futures::executor::block_on;
let mut state = block_on(State::new(&window));
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
Event::MainEventsCleared => window.request_redraw(),
Event::WindowEvent {
ref event,
window_id,
} if window_id == window.id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
WindowEvent::KeyboardInput { input, .. } => match input {
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
} => {
*control_flow = ControlFlow::Exit;
}
_ => {}
},
WindowEvent::Resized(physical_size) => {
block_on(state.resize(*physical_size));
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
block_on(state.resize(**new_inner_size));
}
_ => {}
}
}
}
Event::RedrawRequested(_) => {
block_on(state.update());
block_on(state.render());
}
_ => {}
}
});
}
#[inline]
pub fn matrix4f_cast_slice(a: &[Vec<cgmath::Matrix4<f32>>]) -> &[u8] {