2023-01-29 22:04:01 -03:30
use glyphon ::{
Attrs , Buffer , Color , Family , FontSystem , Metrics , Resolution , SwashCache , TextArea , TextAtlas ,
TextBounds , TextRenderer ,
} ;
2022-05-09 10:19:10 -02:30
use wgpu ::{
2022-10-18 13:02:31 -02:30
Backends , CommandEncoderDescriptor , CompositeAlphaMode , DeviceDescriptor , Features , Instance ,
Limits , LoadOp , Operations , PresentMode , RenderPassColorAttachment , RenderPassDescriptor ,
2022-10-26 00:21:14 -02:30
RequestAdapterOptions , SurfaceConfiguration , TextureFormat , TextureUsages ,
TextureViewDescriptor ,
2022-05-09 10:19:10 -02:30
} ;
use winit ::{
2022-10-28 00:44:15 -02:30
dpi ::LogicalSize ,
2022-05-09 10:19:10 -02:30
event ::{ Event , WindowEvent } ,
event_loop ::{ ControlFlow , EventLoop } ,
2022-10-28 00:44:15 -02:30
window ::WindowBuilder ,
2022-05-09 10:19:10 -02:30
} ;
fn main ( ) {
pollster ::block_on ( run ( ) ) ;
}
2022-10-25 01:11:57 -02:30
static mut FONT_SYSTEM : Option < FontSystem > = None ;
2022-05-09 10:19:10 -02:30
async fn run ( ) {
2022-10-28 00:44:15 -02:30
// Set up window
let ( width , height ) = ( 800 , 600 ) ;
let event_loop = EventLoop ::new ( ) ;
let window = 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
2022-05-09 22:40:00 -02:30
let instance = Instance ::new ( Backends ::all ( ) ) ;
2022-05-09 10:19:10 -02:30
let adapter = instance
2022-05-09 22:40:00 -02:30
. request_adapter ( & RequestAdapterOptions ::default ( ) )
2022-05-09 10:19:10 -02:30
. await
. unwrap ( ) ;
let ( device , queue ) = adapter
. request_device (
2022-05-09 22:40:00 -02:30
& DeviceDescriptor {
2022-05-09 10:19:10 -02:30
label : None ,
2022-05-09 22:40:00 -02:30
features : Features ::empty ( ) ,
limits : Limits ::downlevel_defaults ( ) ,
2022-05-09 10:19:10 -02:30
} ,
None ,
)
. await
. unwrap ( ) ;
let surface = unsafe { instance . create_surface ( & window ) } ;
2022-10-26 00:21:14 -02:30
// TODO: handle srgb
let swapchain_format = TextureFormat ::Bgra8Unorm ;
2022-05-09 22:40:00 -02:30
let mut config = SurfaceConfiguration {
usage : TextureUsages ::RENDER_ATTACHMENT ,
2022-05-09 10:19:10 -02:30
format : swapchain_format ,
width : size . width ,
height : size . height ,
2022-11-28 02:23:10 -03:30
present_mode : PresentMode ::Fifo ,
2022-10-18 13:02:31 -02:30
alpha_mode : CompositeAlphaMode ::Opaque ,
2022-05-09 10:19:10 -02:30
} ;
surface . configure ( & device , & config ) ;
2022-10-28 00:44:15 -02:30
// Set up text renderer
2022-10-28 01:14:07 -02:30
let mut text_renderer = TextRenderer ::new ( & device , & queue ) ;
2022-10-25 22:38:12 -02:30
unsafe {
FONT_SYSTEM = Some ( FontSystem ::new ( ) ) ;
}
2022-10-28 01:14:07 -02:30
let mut cache = SwashCache ::new ( unsafe { FONT_SYSTEM . as_ref ( ) . unwrap ( ) } ) ;
2022-06-03 00:38:59 -02:30
let mut atlas = TextAtlas ::new ( & device , & queue , swapchain_format ) ;
2022-11-03 21:05:21 -02:30
let mut buffer = Buffer ::new (
2022-10-25 22:38:12 -02:30
unsafe { FONT_SYSTEM . as_ref ( ) . unwrap ( ) } ,
2023-01-26 00:44:29 -03:30
Metrics ::new ( 30 , 42 ) ,
2022-11-28 03:56:00 -03:30
) ;
2023-01-26 00:44:29 -03:30
let physical_width = ( width as f64 * scale_factor ) as i32 ;
let physical_height = ( height as f64 * scale_factor ) as i32 ;
buffer . set_size ( physical_width , physical_height ) ;
buffer . set_text ( " Hello world! 👋 \n This is rendered with 🦅 glyphon 🦁 \n The text below should be partially clipped. \n a 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 ) ) ;
2022-11-03 21:05:21 -02:30
buffer . shape_until_scroll ( ) ;
2022-05-09 10:19:10 -02:30
event_loop . run ( move | event , _ , control_flow | {
let _ = ( & instance , & adapter ) ;
* control_flow = ControlFlow ::Poll ;
match event {
Event ::WindowEvent {
event : WindowEvent ::Resized ( size ) ,
..
} = > {
config . width = size . width ;
config . height = size . height ;
surface . configure ( & device , & config ) ;
window . request_redraw ( ) ;
}
Event ::RedrawRequested ( _ ) = > {
text_renderer
. prepare (
& device ,
& queue ,
2022-06-03 00:38:59 -02:30
& mut atlas ,
2022-05-09 10:19:10 -02:30
Resolution {
width : config . width ,
height : config . height ,
} ,
2023-01-26 00:07:05 -03:30
& [ TextArea {
buffer : & buffer ,
2023-01-26 00:44:29 -03:30
left : 10 ,
top : 10 ,
2023-01-26 00:07:05 -03:30
bounds : TextBounds {
2023-01-26 00:44:29 -03:30
left : 0 ,
top : 0 ,
right : 600 ,
bottom : 160 ,
2023-01-26 00:07:05 -03:30
} ,
} ] ,
2022-10-28 01:24:45 -02:30
Color ::rgb ( 255 , 255 , 255 ) ,
2022-10-28 01:14:07 -02:30
& mut cache ,
2022-05-09 10:19:10 -02:30
)
. 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 ,
2022-07-13 09:34:49 -02:30
color_attachments : & [ Some ( RenderPassColorAttachment {
2022-05-09 10:19:10 -02:30
view : & view ,
resolve_target : None ,
ops : Operations {
2022-05-09 22:40:00 -02:30
load : LoadOp ::Clear ( wgpu ::Color ::BLACK ) ,
2022-05-09 10:19:10 -02:30
store : true ,
} ,
2022-07-13 09:34:49 -02:30
} ) ] ,
2022-05-09 10:19:10 -02:30
depth_stencil_attachment : None ,
} ) ;
2022-06-03 00:38:59 -02:30
text_renderer . render ( & atlas , & mut pass ) . unwrap ( ) ;
2022-05-09 10:19:10 -02:30
}
queue . submit ( Some ( encoder . finish ( ) ) ) ;
frame . present ( ) ;
}
Event ::WindowEvent {
event : WindowEvent ::CloseRequested ,
..
} = > * control_flow = ControlFlow ::Exit ,
Event ::MainEventsCleared = > {
window . request_redraw ( ) ;
}
_ = > { }
}
} ) ;
}