8
8
9
9
#![ cfg_attr( not( debug_assertions) , windows_subsystem = "windows" ) ] // hide console window on Windows in release
10
10
11
- use eframe:: { egui, epi } ;
11
+ use eframe:: egui;
12
12
13
13
use parking_lot:: Mutex ;
14
14
use std:: sync:: Arc ;
15
15
16
- #[ derive( Default ) ]
16
+ fn main ( ) {
17
+ let options = eframe:: NativeOptions :: default ( ) ;
18
+ eframe:: run_native ( "Custom 3D painting in eframe" , options, |cc| {
19
+ Box :: new ( MyApp :: new ( cc) )
20
+ } ) ;
21
+ }
22
+
17
23
struct MyApp {
18
- rotating_triangle : Arc < Mutex < Option < RotatingTriangle > > > ,
24
+ /// Behind an `Arc<Mutex<…>>` so we can pass it to [`egui::PaintCallback`] and paint later.
25
+ rotating_triangle : Arc < Mutex < RotatingTriangle > > ,
19
26
angle : f32 ,
20
27
}
21
28
22
- impl epi:: App for MyApp {
23
- fn name ( & self ) -> & str {
24
- "Custom 3D painting inside an egui window"
29
+ impl MyApp {
30
+ fn new ( cc : & eframe:: CreationContext < ' _ > ) -> Self {
31
+ Self {
32
+ rotating_triangle : Arc :: new ( Mutex :: new ( RotatingTriangle :: new ( & cc. gl ) ) ) ,
33
+ angle : 0.0 ,
34
+ }
25
35
}
36
+ }
26
37
27
- fn update ( & mut self , ctx : & egui:: Context , _frame : & epi:: Frame ) {
38
+ impl eframe:: App for MyApp {
39
+ fn update ( & mut self , ctx : & egui:: Context , _frame : & eframe:: Frame ) {
28
40
egui:: CentralPanel :: default ( ) . show ( ctx, |ui| {
29
- ui. heading ( "Here is some 3D stuff:" ) ;
41
+ ui. horizontal ( |ui| {
42
+ ui. spacing_mut ( ) . item_spacing . x = 0.0 ;
43
+ ui. label ( "The triangle is being painted using " ) ;
44
+ ui. hyperlink_to ( "glow" , "https://github.com/grovesNL/glow" ) ;
45
+ ui. label ( " (OpenGL)." ) ;
46
+ } ) ;
30
47
31
48
egui:: ScrollArea :: both ( ) . show ( ui, |ui| {
32
49
egui:: Frame :: dark_canvas ( ui. style ( ) ) . show ( ui, |ui| {
@@ -35,14 +52,10 @@ impl epi::App for MyApp {
35
52
ui. label ( "Drag to rotate!" ) ;
36
53
} ) ;
37
54
} ) ;
55
+ }
38
56
39
- let mut frame = egui:: Frame :: window ( & * ctx. style ( ) ) ;
40
- frame. fill = frame. fill . linear_multiply ( 0.5 ) ; // transparent
41
- egui:: Window :: new ( "3D stuff in a window" )
42
- . frame ( frame)
43
- . show ( ctx, |ui| {
44
- self . custom_painting ( ui) ;
45
- } ) ;
57
+ fn on_exit ( & mut self , gl : & glow:: Context ) {
58
+ self . rotating_triangle . lock ( ) . destroy ( gl)
46
59
}
47
60
}
48
61
@@ -53,17 +66,15 @@ impl MyApp {
53
66
54
67
self . angle += response. drag_delta ( ) . x * 0.01 ;
55
68
69
+ // Clone locals so we can move them into the paint callback:
56
70
let angle = self . angle ;
57
71
let rotating_triangle = self . rotating_triangle . clone ( ) ;
58
72
59
- let callback = egui:: epaint :: PaintCallback {
73
+ let callback = egui:: PaintCallback {
60
74
rect,
61
75
callback : std:: sync:: Arc :: new ( move |render_ctx| {
62
76
if let Some ( painter) = render_ctx. downcast_ref :: < egui_glow:: Painter > ( ) {
63
- let mut rotating_triangle = rotating_triangle. lock ( ) ;
64
- let rotating_triangle = rotating_triangle
65
- . get_or_insert_with ( || RotatingTriangle :: new ( painter. gl ( ) ) ) ;
66
- rotating_triangle. paint ( painter. gl ( ) , angle) ;
77
+ rotating_triangle. lock ( ) . paint ( painter. gl ( ) , angle) ;
67
78
} else {
68
79
eprintln ! ( "Can't do custom painting because we are not using a glow context" ) ;
69
80
}
@@ -163,9 +174,7 @@ impl RotatingTriangle {
163
174
}
164
175
}
165
176
166
- // TODO: figure out how to call this in a nice way
167
- #[ allow( unused) ]
168
- fn destroy ( self , gl : & glow:: Context ) {
177
+ fn destroy ( & self , gl : & glow:: Context ) {
169
178
use glow:: HasContext as _;
170
179
unsafe {
171
180
gl. delete_program ( self . program ) ;
@@ -186,8 +195,3 @@ impl RotatingTriangle {
186
195
}
187
196
}
188
197
}
189
-
190
- fn main ( ) {
191
- let options = eframe:: NativeOptions :: default ( ) ;
192
- eframe:: run_native ( Box :: new ( MyApp :: default ( ) ) , options) ;
193
- }
0 commit comments