1use glfw::*;
2use glow::HasContext;
3use impellers::*;
4
5#[allow(unused)]
6pub struct SdlGlImpellerFrameWork {
7 pub ttx: TypographyContext,
8 pub style: ParagraphStyle,
9 pub itx: impellers::Context,
10 pub glow_ctx: glow::Context,
11 pub receiver: GlfwReceiver<(f64, WindowEvent)>,
12 pub window: PWindow,
13 pub gtx: Glfw,
14 pub events: Vec<WindowEvent>,
15}
16impl Default for SdlGlImpellerFrameWork {
17 fn default() -> Self {
18 Self::new()
19 }
20}
21#[allow(unused)]
22pub const DOG_BYTES: &[u8] = include_bytes!("dog.jpg");
23
24type UserCallback = Box<dyn FnMut(&mut SdlGlImpellerFrameWork) -> Option<DisplayList>>;
25impl SdlGlImpellerFrameWork {
26 pub fn new() -> Self {
27 let mut gtx = init(fail_on_errors).expect("failed to init glfw");
29 gtx.window_hint(WindowHint::ContextVersionMajor(4));
30 gtx.window_hint(WindowHint::OpenGlProfile(OpenGlProfileHint::Core));
31 gtx.window_hint(WindowHint::SRgbCapable(true));
32 gtx.window_hint(WindowHint::StencilBits(Some(8)));
33 gtx.window_hint(WindowHint::ScaleToMonitor(true));
34
35 let (mut window, ev_receiver) = gtx
36 .create_window(800, 600, "glfw opengl impeller", WindowMode::Windowed)
37 .unwrap();
38 window.make_current();
39 window.set_all_polling(true);
40
41 let itx = unsafe { impellers::Context::new_opengl_es(|s| window.get_proc_address(s) as _) }
43 .unwrap();
44 let glow_ctx =
45 unsafe { glow::Context::from_loader_function(|s| window.get_proc_address(s) as _) };
46 unsafe {
47 let (width, height) = window.get_framebuffer_size();
48 glow_ctx.viewport(0, 0, width, height);
49 }
50 let ttx = TypographyContext::default();
51 let mut style = ParagraphStyle::default();
52 style.set_font_size(24.0);
53 style.set_font_family("Roboto");
54 style.set_font_weight(FontWeight::Bold);
55 let mut paint = Paint::default();
56 paint.set_color(Color::LIGHT_SKY_BLUE);
57 style.set_foreground(&paint);
58 Self {
59 ttx,
60 style,
61 glow_ctx,
62 itx,
63 window,
64 receiver: ev_receiver,
65 gtx,
66 events: vec![],
67 }
68 }
69 pub fn enter_event_loop(
76 mut self,
77 dl: Option<DisplayList>,
78 mut user_callback: Option<UserCallback>,
79 ) {
80 let mut previous_instant = std::time::Instant::now();
81 let mut current_frame = 0;
82 let mut fps = 0;
83 let mut vsync = true;
84 while !self.window.should_close() {
86 {
87 if previous_instant.elapsed().as_secs_f64() >= 1.0 {
89 fps = current_frame;
90 current_frame = 0;
91 previous_instant = std::time::Instant::now();
92 }
93 current_frame += 1;
94 }
95 self.events.clear();
96 self.gtx.poll_events();
98 for (_, event) in flush_messages(&self.receiver) {
99 match &event {
100 WindowEvent::Close => {
101 self.window.set_should_close(true);
102 }
103 WindowEvent::FramebufferSize(w, h) => {
104 unsafe {
105 self.glow_ctx.viewport(0, 0, *w, *h);
106 }
107 println!("window resized to {}x{}", w, h);
108 }
109 WindowEvent::Key(Key::Space, _, Action::Release, _) => {
110 vsync = !vsync;
111 println!("setting vsync to {vsync}");
112
113 self.gtx.set_swap_interval(if vsync {
114 SwapInterval::Sync(1)
115 } else {
116 SwapInterval::None
117 });
118 }
119 _ => {}
120 }
121 self.events.push(event);
122 }
123
124 let (width, height) = self.window.get_framebuffer_size();
125 let mut surface = unsafe {
127 self.itx.wrap_fbo(
128 0,
129 PixelFormat::RGBA8888,
130 ISize::new(width.into(), height.into()),
131 )
132 }
133 .expect("failed to wrap window's framebuffer");
134 let mut dl_builder = DisplayListBuilder::new(Some(&Rect::from_size(
135 [width as f32, height as f32].into(),
136 )));
137
138 if let Some(dl) = dl.as_ref() {
139 dl_builder.draw_display_list(dl, 1.0);
140 }
141 if let Some(cb) = user_callback.as_mut() {
143 if let Some(display_list) = cb(&mut self) {
144 dl_builder.draw_display_list(&display_list, 1.0);
145 }
146 }
147 {
148 let mut para_builder = ParagraphBuilder::new(&self.ttx).unwrap();
149 para_builder.push_style(&self.style);
150 para_builder.add_text(&format!("avg fps: {fps}"));
151 let para = para_builder.build(1000.0).unwrap();
152 dl_builder.draw_paragraph(¶, Point::origin());
153 }
154 surface
155 .draw_display_list(&dl_builder.build().unwrap())
156 .unwrap();
157
158 self.window.swap_buffers();
160 }
161 }
162
163 }
165
166#[allow(unused)]
167pub fn main() {
168 unimplemented!("this is a common module for other examples to use")
169}