update example to use winit 0.30 (#105)
* update example to use winit 0.30 * omit unneeded field in example
This commit is contained in:
parent
9def853042
commit
719d69a1ee
2 changed files with 211 additions and 151 deletions
|
@ -15,6 +15,6 @@ lru = { version = "0.12.1", default-features = false }
|
||||||
rustc-hash = "2.0"
|
rustc-hash = "2.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
winit = { version = "0.29.10", features = ["rwh_05"] }
|
winit = "0.30.3"
|
||||||
wgpu = { version = "22", default-features = true }
|
wgpu = "22"
|
||||||
pollster = "0.3.0"
|
pollster = "0.3.0"
|
||||||
|
|
|
@ -9,158 +9,218 @@ use wgpu::{
|
||||||
RenderPassDescriptor, RequestAdapterOptions, SurfaceConfiguration, TextureFormat,
|
RenderPassDescriptor, RequestAdapterOptions, SurfaceConfiguration, TextureFormat,
|
||||||
TextureUsages, TextureViewDescriptor,
|
TextureUsages, TextureViewDescriptor,
|
||||||
};
|
};
|
||||||
use winit::{
|
use winit::{dpi::LogicalSize, event::WindowEvent, event_loop::EventLoop, window::Window};
|
||||||
dpi::LogicalSize,
|
|
||||||
event::{Event, WindowEvent},
|
|
||||||
event_loop::EventLoop,
|
|
||||||
window::WindowBuilder,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
pollster::block_on(run());
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run() {
|
|
||||||
// Set up window
|
|
||||||
let (width, height) = (800, 600);
|
|
||||||
let event_loop = EventLoop::new().unwrap();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
let window = Arc::new(
|
|
||||||
WindowBuilder::new()
|
|
||||||
.with_inner_size(LogicalSize::new(width as f64, height as f64))
|
|
||||||
.with_title("glyphon hello world")
|
|
||||||
.build(&event_loop)
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
let size = window.inner_size();
|
|
||||||
let scale_factor = window.scale_factor();
|
|
||||||
|
|
||||||
// Set up surface
|
|
||||||
let instance = Instance::new(InstanceDescriptor::default());
|
|
||||||
let adapter = instance
|
|
||||||
.request_adapter(&RequestAdapterOptions::default())
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let (device, queue) = adapter
|
|
||||||
.request_device(&DeviceDescriptor::default(), None)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let surface = instance
|
|
||||||
.create_surface(window.clone())
|
|
||||||
.expect("Create surface");
|
|
||||||
let swapchain_format = TextureFormat::Bgra8UnormSrgb;
|
|
||||||
let mut config = SurfaceConfiguration {
|
|
||||||
usage: TextureUsages::RENDER_ATTACHMENT,
|
|
||||||
format: swapchain_format,
|
|
||||||
width: size.width,
|
|
||||||
height: size.height,
|
|
||||||
present_mode: PresentMode::Fifo,
|
|
||||||
alpha_mode: CompositeAlphaMode::Opaque,
|
|
||||||
view_formats: vec![],
|
|
||||||
desired_maximum_frame_latency: 2,
|
|
||||||
};
|
|
||||||
surface.configure(&device, &config);
|
|
||||||
|
|
||||||
// Set up text renderer
|
|
||||||
let mut font_system = FontSystem::new();
|
|
||||||
let mut swash_cache = SwashCache::new();
|
|
||||||
let cache = Cache::new(&device);
|
|
||||||
let mut viewport = Viewport::new(&device, &cache);
|
|
||||||
let mut atlas = TextAtlas::new(&device, &queue, &cache, swapchain_format);
|
|
||||||
let mut text_renderer =
|
|
||||||
TextRenderer::new(&mut atlas, &device, MultisampleState::default(), None);
|
|
||||||
let mut buffer = Buffer::new(&mut font_system, Metrics::new(30.0, 42.0));
|
|
||||||
|
|
||||||
let physical_width = (width as f64 * scale_factor) as f32;
|
|
||||||
let physical_height = (height as f64 * scale_factor) as f32;
|
|
||||||
|
|
||||||
buffer.set_size(
|
|
||||||
&mut font_system,
|
|
||||||
Some(physical_width),
|
|
||||||
Some(physical_height),
|
|
||||||
);
|
|
||||||
buffer.set_text(&mut font_system, "Hello world! 👋\nThis is rendered with 🦅 glyphon 🦁\nThe text below should be partially clipped.\na b c d e f g h i j k l m n o p q r s t u v w x y z", Attrs::new().family(Family::SansSerif), Shaping::Advanced);
|
|
||||||
buffer.shape_until_scroll(&mut font_system, false);
|
|
||||||
|
|
||||||
event_loop
|
event_loop
|
||||||
.run(move |event, target| {
|
.run_app(&mut Application { window_state: None })
|
||||||
if let Event::WindowEvent {
|
|
||||||
window_id: _,
|
|
||||||
event,
|
|
||||||
} = event
|
|
||||||
{
|
|
||||||
match event {
|
|
||||||
WindowEvent::Resized(size) => {
|
|
||||||
config.width = size.width;
|
|
||||||
config.height = size.height;
|
|
||||||
surface.configure(&device, &config);
|
|
||||||
window.request_redraw();
|
|
||||||
}
|
|
||||||
WindowEvent::RedrawRequested => {
|
|
||||||
viewport.update(
|
|
||||||
&queue,
|
|
||||||
Resolution {
|
|
||||||
width: config.width,
|
|
||||||
height: config.height,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
text_renderer
|
|
||||||
.prepare(
|
|
||||||
&device,
|
|
||||||
&queue,
|
|
||||||
&mut font_system,
|
|
||||||
&mut atlas,
|
|
||||||
&viewport,
|
|
||||||
[TextArea {
|
|
||||||
buffer: &buffer,
|
|
||||||
left: 10.0,
|
|
||||||
top: 10.0,
|
|
||||||
scale: 1.0,
|
|
||||||
bounds: TextBounds {
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
right: 600,
|
|
||||||
bottom: 160,
|
|
||||||
},
|
|
||||||
default_color: Color::rgb(255, 255, 255),
|
|
||||||
}],
|
|
||||||
&mut swash_cache,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let frame = surface.get_current_texture().unwrap();
|
|
||||||
let view = frame.texture.create_view(&TextureViewDescriptor::default());
|
|
||||||
let mut encoder = device
|
|
||||||
.create_command_encoder(&CommandEncoderDescriptor { label: None });
|
|
||||||
{
|
|
||||||
let mut pass = encoder.begin_render_pass(&RenderPassDescriptor {
|
|
||||||
label: None,
|
|
||||||
color_attachments: &[Some(RenderPassColorAttachment {
|
|
||||||
view: &view,
|
|
||||||
resolve_target: None,
|
|
||||||
ops: Operations {
|
|
||||||
load: LoadOp::Clear(wgpu::Color::BLACK),
|
|
||||||
store: wgpu::StoreOp::Store,
|
|
||||||
},
|
|
||||||
})],
|
|
||||||
depth_stencil_attachment: None,
|
|
||||||
timestamp_writes: None,
|
|
||||||
occlusion_query_set: None,
|
|
||||||
});
|
|
||||||
|
|
||||||
text_renderer.render(&atlas, &viewport, &mut pass).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
queue.submit(Some(encoder.finish()));
|
|
||||||
frame.present();
|
|
||||||
|
|
||||||
atlas.trim();
|
|
||||||
}
|
|
||||||
WindowEvent::CloseRequested => target.exit(),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct WindowState {
|
||||||
|
device: wgpu::Device,
|
||||||
|
queue: wgpu::Queue,
|
||||||
|
surface: wgpu::Surface<'static>,
|
||||||
|
surface_config: SurfaceConfiguration,
|
||||||
|
|
||||||
|
font_system: FontSystem,
|
||||||
|
swash_cache: SwashCache,
|
||||||
|
viewport: glyphon::Viewport,
|
||||||
|
atlas: glyphon::TextAtlas,
|
||||||
|
text_renderer: glyphon::TextRenderer,
|
||||||
|
text_buffer: glyphon::Buffer,
|
||||||
|
|
||||||
|
// Make sure that the winit window is last in the struct so that
|
||||||
|
// it is dropped after the wgpu surface is dropped, otherwise the
|
||||||
|
// program may crash when closed. This is probably a bug in wgpu.
|
||||||
|
window: Arc<Window>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowState {
|
||||||
|
async fn new(window: Arc<Window>) -> Self {
|
||||||
|
let physical_size = window.inner_size();
|
||||||
|
let scale_factor = window.scale_factor();
|
||||||
|
|
||||||
|
// Set up surface
|
||||||
|
let instance = Instance::new(InstanceDescriptor::default());
|
||||||
|
let adapter = instance
|
||||||
|
.request_adapter(&RequestAdapterOptions::default())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let (device, queue) = adapter
|
||||||
|
.request_device(&DeviceDescriptor::default(), None)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let surface = instance
|
||||||
|
.create_surface(window.clone())
|
||||||
|
.expect("Create surface");
|
||||||
|
let swapchain_format = TextureFormat::Bgra8UnormSrgb;
|
||||||
|
let surface_config = SurfaceConfiguration {
|
||||||
|
usage: TextureUsages::RENDER_ATTACHMENT,
|
||||||
|
format: swapchain_format,
|
||||||
|
width: physical_size.width,
|
||||||
|
height: physical_size.height,
|
||||||
|
present_mode: PresentMode::Fifo,
|
||||||
|
alpha_mode: CompositeAlphaMode::Opaque,
|
||||||
|
view_formats: vec![],
|
||||||
|
desired_maximum_frame_latency: 2,
|
||||||
|
};
|
||||||
|
surface.configure(&device, &surface_config);
|
||||||
|
|
||||||
|
// Set up text renderer
|
||||||
|
let mut font_system = FontSystem::new();
|
||||||
|
let swash_cache = SwashCache::new();
|
||||||
|
let cache = Cache::new(&device);
|
||||||
|
let viewport = Viewport::new(&device, &cache);
|
||||||
|
let mut atlas = TextAtlas::new(&device, &queue, &cache, swapchain_format);
|
||||||
|
let text_renderer =
|
||||||
|
TextRenderer::new(&mut atlas, &device, MultisampleState::default(), None);
|
||||||
|
let mut text_buffer = Buffer::new(&mut font_system, Metrics::new(30.0, 42.0));
|
||||||
|
|
||||||
|
let physical_width = (physical_size.width as f64 * scale_factor) as f32;
|
||||||
|
let physical_height = (physical_size.height as f64 * scale_factor) as f32;
|
||||||
|
|
||||||
|
text_buffer.set_size(
|
||||||
|
&mut font_system,
|
||||||
|
Some(physical_width),
|
||||||
|
Some(physical_height),
|
||||||
|
);
|
||||||
|
text_buffer.set_text(&mut font_system, "Hello world! 👋\nThis is rendered with 🦅 glyphon 🦁\nThe text below should be partially clipped.\na b c d e f g h i j k l m n o p q r s t u v w x y z", Attrs::new().family(Family::SansSerif), Shaping::Advanced);
|
||||||
|
text_buffer.shape_until_scroll(&mut font_system, false);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
device,
|
||||||
|
queue,
|
||||||
|
surface,
|
||||||
|
surface_config,
|
||||||
|
font_system,
|
||||||
|
swash_cache,
|
||||||
|
viewport,
|
||||||
|
atlas,
|
||||||
|
text_renderer,
|
||||||
|
text_buffer,
|
||||||
|
window,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Application {
|
||||||
|
window_state: Option<WindowState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl winit::application::ApplicationHandler for Application {
|
||||||
|
fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
|
||||||
|
if self.window_state.is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up window
|
||||||
|
let (width, height) = (800, 600);
|
||||||
|
let window_attributes = Window::default_attributes()
|
||||||
|
.with_inner_size(LogicalSize::new(width as f64, height as f64))
|
||||||
|
.with_title("glyphon hello world");
|
||||||
|
let window = Arc::new(event_loop.create_window(window_attributes).unwrap());
|
||||||
|
|
||||||
|
self.window_state = Some(pollster::block_on(WindowState::new(window)));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn window_event(
|
||||||
|
&mut self,
|
||||||
|
event_loop: &winit::event_loop::ActiveEventLoop,
|
||||||
|
_window_id: winit::window::WindowId,
|
||||||
|
event: WindowEvent,
|
||||||
|
) {
|
||||||
|
let Some(state) = &mut self.window_state else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let WindowState {
|
||||||
|
window,
|
||||||
|
device,
|
||||||
|
queue,
|
||||||
|
surface,
|
||||||
|
surface_config,
|
||||||
|
font_system,
|
||||||
|
swash_cache,
|
||||||
|
viewport,
|
||||||
|
atlas,
|
||||||
|
text_renderer,
|
||||||
|
text_buffer,
|
||||||
|
..
|
||||||
|
} = state;
|
||||||
|
|
||||||
|
match event {
|
||||||
|
WindowEvent::Resized(size) => {
|
||||||
|
surface_config.width = size.width;
|
||||||
|
surface_config.height = size.height;
|
||||||
|
surface.configure(&device, &surface_config);
|
||||||
|
window.request_redraw();
|
||||||
|
}
|
||||||
|
WindowEvent::RedrawRequested => {
|
||||||
|
viewport.update(
|
||||||
|
&queue,
|
||||||
|
Resolution {
|
||||||
|
width: surface_config.width,
|
||||||
|
height: surface_config.height,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
text_renderer
|
||||||
|
.prepare(
|
||||||
|
device,
|
||||||
|
queue,
|
||||||
|
font_system,
|
||||||
|
atlas,
|
||||||
|
viewport,
|
||||||
|
[TextArea {
|
||||||
|
buffer: text_buffer,
|
||||||
|
left: 10.0,
|
||||||
|
top: 10.0,
|
||||||
|
scale: 1.0,
|
||||||
|
bounds: TextBounds {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
right: 600,
|
||||||
|
bottom: 160,
|
||||||
|
},
|
||||||
|
default_color: Color::rgb(255, 255, 255),
|
||||||
|
}],
|
||||||
|
swash_cache,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let frame = surface.get_current_texture().unwrap();
|
||||||
|
let view = frame.texture.create_view(&TextureViewDescriptor::default());
|
||||||
|
let mut encoder =
|
||||||
|
device.create_command_encoder(&CommandEncoderDescriptor { label: None });
|
||||||
|
{
|
||||||
|
let mut pass = encoder.begin_render_pass(&RenderPassDescriptor {
|
||||||
|
label: None,
|
||||||
|
color_attachments: &[Some(RenderPassColorAttachment {
|
||||||
|
view: &view,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: Operations {
|
||||||
|
load: LoadOp::Clear(wgpu::Color::BLACK),
|
||||||
|
store: wgpu::StoreOp::Store,
|
||||||
|
},
|
||||||
|
})],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
timestamp_writes: None,
|
||||||
|
occlusion_query_set: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
text_renderer.render(&atlas, &viewport, &mut pass).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.submit(Some(encoder.finish()));
|
||||||
|
frame.present();
|
||||||
|
|
||||||
|
atlas.trim();
|
||||||
|
}
|
||||||
|
WindowEvent::CloseRequested => event_loop.exit(),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue