Basic window surface
This commit is contained in:
parent
d25d006cec
commit
4cd1a3e7cd
|
@ -1039,6 +1039,12 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pollster"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "presser"
|
name = "presser"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -1232,6 +1238,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
|
"pollster",
|
||||||
"wgpu",
|
"wgpu",
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,5 +9,6 @@ edition = "2021"
|
||||||
anyhow = "1.0.80"
|
anyhow = "1.0.80"
|
||||||
env_logger = "0.11.3"
|
env_logger = "0.11.3"
|
||||||
log = "0.4.21"
|
log = "0.4.21"
|
||||||
|
pollster = "0.3.0"
|
||||||
wgpu = "0.19.3"
|
wgpu = "0.19.3"
|
||||||
winit = "0.29.14"
|
winit = "0.29.14"
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use winit::{
|
||||||
|
dpi::PhysicalSize, event::WindowEvent, event_loop::EventLoopWindowTarget, window::Window,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Context<'w> {
|
||||||
|
pub window: &'w Window,
|
||||||
|
pub instance: wgpu::Instance,
|
||||||
|
pub size: PhysicalSize<u32>,
|
||||||
|
pub surface: wgpu::Surface<'w>,
|
||||||
|
pub surface_config: wgpu::SurfaceConfiguration,
|
||||||
|
pub adapter: wgpu::Adapter,
|
||||||
|
pub device: wgpu::Device,
|
||||||
|
pub queue: wgpu::Queue,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'w> Context<'w> {
|
||||||
|
pub async fn new(window: &'w Window, limits: wgpu::Limits) -> Result<Self> {
|
||||||
|
log::info!("Initialising WGPU context...");
|
||||||
|
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||||
|
backends: wgpu::Backends::VULKAN,
|
||||||
|
dx12_shader_compiler: Default::default(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
// To be able to start drawing we need a few things:
|
||||||
|
// - A surface
|
||||||
|
// - A GPU device to draw to the surface
|
||||||
|
// - A draw command queue
|
||||||
|
log::info!("Initialising window surface...");
|
||||||
|
let surface = instance.create_surface(window)?;
|
||||||
|
|
||||||
|
log::info!("Requesting GPU adapter...");
|
||||||
|
let adapter = instance
|
||||||
|
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||||
|
power_preference: wgpu::PowerPreference::HighPerformance,
|
||||||
|
force_fallback_adapter: false,
|
||||||
|
compatible_surface: Some(&surface),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
log::info!("Checking GPU adapter meets requirements");
|
||||||
|
log::info!("Requesting GPU device...");
|
||||||
|
let (device, queue) = adapter
|
||||||
|
.request_device(
|
||||||
|
&wgpu::DeviceDescriptor {
|
||||||
|
label: None,
|
||||||
|
required_features: wgpu::Features::empty(),
|
||||||
|
required_limits: limits,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
log::info!("Configuring window surface...");
|
||||||
|
let size = window.inner_size();
|
||||||
|
let surface_config = surface
|
||||||
|
.get_default_config(&adapter, size.width, size.height)
|
||||||
|
.unwrap();
|
||||||
|
surface.configure(&device, &surface_config);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
window,
|
||||||
|
instance,
|
||||||
|
size,
|
||||||
|
surface,
|
||||||
|
surface_config,
|
||||||
|
adapter,
|
||||||
|
device,
|
||||||
|
queue,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize_surface(&mut self, new_size: PhysicalSize<u32>) {
|
||||||
|
if new_size.width > 0 && new_size.height > 0 {
|
||||||
|
self.size = new_size;
|
||||||
|
self.surface_config.width = new_size.width;
|
||||||
|
self.surface_config.height = new_size.height;
|
||||||
|
self.surface.configure(&self.device, &self.surface_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_window_event(
|
||||||
|
&mut self,
|
||||||
|
event: &WindowEvent,
|
||||||
|
elwt: &EventLoopWindowTarget<()>,
|
||||||
|
) -> bool {
|
||||||
|
let mut handled = true;
|
||||||
|
match event {
|
||||||
|
WindowEvent::CloseRequested => {
|
||||||
|
elwt.exit();
|
||||||
|
}
|
||||||
|
WindowEvent::Resized(physical_size) => {
|
||||||
|
self.resize_surface(*physical_size);
|
||||||
|
}
|
||||||
|
WindowEvent::ScaleFactorChanged { .. } => {
|
||||||
|
self.resize_surface(self.window.inner_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => handled = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
handled
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
mod context;
|
||||||
|
|
||||||
|
pub use self::context::Context;
|
59
src/main.rs
59
src/main.rs
|
@ -1,8 +1,12 @@
|
||||||
|
mod gfx;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use gfx::Context;
|
||||||
|
use wgpu::Limits;
|
||||||
use winit::{
|
use winit::{
|
||||||
dpi::LogicalSize,
|
dpi::LogicalSize,
|
||||||
event::*,
|
event::*,
|
||||||
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
window::{Window, WindowBuilder},
|
window::{Window, WindowBuilder},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,15 +14,23 @@ pub fn main() -> Result<()> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let (event_loop, window) = make_window()?;
|
let (event_loop, window) = make_window()?;
|
||||||
run(event_loop, window)?;
|
let context = pollster::block_on(Context::new(&window, Limits::default()))?;
|
||||||
|
run(event_loop, context)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(event_loop: EventLoop<()>, window: Window) -> Result<()> {
|
pub fn run(event_loop: EventLoop<()>, mut context: Context) -> Result<()> {
|
||||||
event_loop.run(|event, elwt| match event {
|
event_loop.run(|event, elwt| match event {
|
||||||
Event::WindowEvent { window_id, event } if window_id == window.id() => {
|
Event::WindowEvent { window_id, event } if window_id == context.window.id() => {
|
||||||
handle_window_event(event, elwt);
|
if context.handle_window_event(&event, elwt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let WindowEvent::RedrawRequested = event {
|
||||||
|
render(&context);
|
||||||
|
context.window.request_redraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
})?;
|
})?;
|
||||||
|
@ -38,8 +50,39 @@ fn make_window() -> Result<(EventLoop<()>, Window)> {
|
||||||
Ok((event_loop, window))
|
Ok((event_loop, window))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_window_event(event: WindowEvent, elwt: &EventLoopWindowTarget<()>) {
|
fn render(context: &Context) {
|
||||||
if let WindowEvent::CloseRequested = event {
|
let output = context.surface.get_current_texture().unwrap();
|
||||||
elwt.exit();
|
let view = output
|
||||||
|
.texture
|
||||||
|
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
let mut encoder = context
|
||||||
|
.device
|
||||||
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||||
|
label: Some("Render Encoder"),
|
||||||
|
});
|
||||||
|
{
|
||||||
|
let _render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: Some("Render Pass"),
|
||||||
|
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||||
|
view: &view,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Clear(wgpu::Color {
|
||||||
|
r: 0.1,
|
||||||
|
g: 0.2,
|
||||||
|
b: 0.3,
|
||||||
|
a: 1.0,
|
||||||
|
}),
|
||||||
|
store: wgpu::StoreOp::Store,
|
||||||
|
},
|
||||||
|
})],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
occlusion_query_set: None,
|
||||||
|
timestamp_writes: None,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// submit will accept anything that implements IntoIter
|
||||||
|
context.queue.submit(std::iter::once(encoder.finish()));
|
||||||
|
output.present();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue