mirror of
https://github.com/sotrh/learn-wgpu.git
synced 2024-11-04 06:00:47 +00:00
Update main.rs
This commit is contained in:
parent
a1059d5ccc
commit
13cbe0ca68
@ -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] {
|
||||
|
Loading…
Reference in New Issue
Block a user