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 {
43 impellers::Context::new_opengl_es(|s| {
44 window
45 .get_proc_address(s)
46 .map(|f| f as _)
47 .unwrap_or(std::ptr::null_mut())
48 })
49 }
50 .unwrap();
51 let glow_ctx = unsafe {
52 glow::Context::from_loader_function(|s| {
53 window
54 .get_proc_address(s)
55 .map(|f| f as _)
56 .unwrap_or(std::ptr::null_mut())
57 })
58 };
59 unsafe {
60 let (width, height) = window.get_framebuffer_size();
61 glow_ctx.viewport(0, 0, width, height);
62 }
63 let ttx = TypographyContext::default();
64 let mut style = ParagraphStyle::default();
65 style.set_font_size(24.0);
66 style.set_font_family("Roboto");
67 style.set_font_weight(FontWeight::Bold);
68 let mut paint = Paint::default();
69 paint.set_color(Color::LIGHT_SKY_BLUE);
70 style.set_foreground(&paint);
71 Self {
72 ttx,
73 style,
74 glow_ctx,
75 itx,
76 window,
77 receiver: ev_receiver,
78 gtx,
79 events: vec![],
80 }
81 }
82 pub fn enter_event_loop(
89 mut self,
90 dl: Option<DisplayList>,
91 mut user_callback: Option<UserCallback>,
92 ) {
93 let mut previous_instant = std::time::Instant::now();
94 let mut current_frame = 0;
95 let mut fps = 0;
96 let mut vsync = true;
97 while !self.window.should_close() {
99 {
100 if previous_instant.elapsed().as_secs_f64() >= 1.0 {
102 fps = current_frame;
103 current_frame = 0;
104 previous_instant = std::time::Instant::now();
105 }
106 current_frame += 1;
107 }
108 self.events.clear();
109 self.gtx.poll_events();
111 for (_, event) in flush_messages(&self.receiver) {
112 match &event {
113 WindowEvent::Close => {
114 self.window.set_should_close(true);
115 }
116 WindowEvent::FramebufferSize(w, h) => {
117 unsafe {
118 self.glow_ctx.viewport(0, 0, *w, *h);
119 }
120 println!("window resized to {}x{}", w, h);
121 }
122 WindowEvent::Key(Key::Space, _, Action::Release, _) => {
123 vsync = !vsync;
124 println!("setting vsync to {vsync}");
125
126 self.gtx.set_swap_interval(if vsync {
127 SwapInterval::Sync(1)
128 } else {
129 SwapInterval::None
130 });
131 }
132 _ => {}
133 }
134 self.events.push(event);
135 }
136
137 let (width, height) = self.window.get_framebuffer_size();
138 let mut surface = unsafe {
140 self.itx.wrap_fbo(
141 0,
142 PixelFormat::RGBA8888,
143 ISize::new(width.into(), height.into()),
144 )
145 }
146 .expect("failed to wrap window's framebuffer");
147 let mut dl_builder = DisplayListBuilder::new(Some(&Rect::from_size(
148 [width as f32, height as f32].into(),
149 )));
150
151 if let Some(dl) = dl.as_ref() {
152 dl_builder.draw_display_list(dl, 1.0);
153 }
154 if let Some(cb) = user_callback.as_mut() {
156 if let Some(display_list) = cb(&mut self) {
157 dl_builder.draw_display_list(&display_list, 1.0);
158 }
159 }
160 {
161 let mut para_builder = ParagraphBuilder::new(&self.ttx).unwrap();
162 para_builder.push_style(&self.style);
163 para_builder.add_text(&format!("avg fps: {fps}"));
164 let para = para_builder.build(1000.0).unwrap();
165 dl_builder.draw_paragraph(¶, Point::origin());
166 }
167 surface
168 .draw_display_list(&dl_builder.build().unwrap())
169 .unwrap();
170
171 self.window.swap_buffers();
173 }
174 }
175
176 }
178
179#[allow(unused)]
180pub fn main() {
181 unimplemented!("this is a common module for other examples to use")
182}