@@ -2,6 +2,7 @@ pub mod menu_scene;
22pub mod playing_scene;
33
44use crate :: context:: Context ;
5+ use iced_core:: image:: Renderer as _;
56use midi_file:: midly:: MidiMessage ;
67use neothesia_core:: render:: { QuadRenderer , TextRenderer } ;
78use std:: time:: Duration ;
@@ -14,67 +15,104 @@ pub trait Scene {
1415 fn midi_event ( & mut self , _ctx : & mut Context , _channel : u8 , _message : & MidiMessage ) { }
1516}
1617
17- fn render_nuon (
18- ui : & mut nuon:: Ui ,
19- quad_pipeline : & mut QuadRenderer ,
20- text_renderer : & mut TextRenderer ,
21- renderer : & mut impl iced_core:: image:: Renderer < Handle = iced_core:: image:: Handle > ,
22- ) {
23- for quad in ui. quads . iter ( ) {
24- quad_pipeline. push ( neothesia_core:: render:: QuadInstance {
25- position : quad. rect . origin . into ( ) ,
26- size : quad. rect . size . into ( ) ,
27- color : wgpu_jumpstart:: Color :: new (
28- quad. color . r ,
29- quad. color . g ,
30- quad. color . b ,
31- quad. color . a ,
32- )
33- . into_linear_rgba ( ) ,
34- border_radius : quad. border_radius ,
18+ struct NuonLayer {
19+ quad_renderer : QuadRenderer ,
20+ text_renderer : TextRenderer ,
21+ }
22+
23+ #[ derive( Default ) ]
24+ pub struct NuonRenderer {
25+ layers : Vec < NuonLayer > ,
26+ }
27+
28+ impl NuonRenderer {
29+ fn ensure_layers ( & mut self , ctx : & mut Context , len : usize ) {
30+ self . layers . resize_with ( len, || NuonLayer {
31+ quad_renderer : ctx. quad_renderer_facotry . new_renderer ( ) ,
32+ text_renderer : ctx. text_renderer_factory . new_renderer ( ) ,
3533 } ) ;
3634 }
3735
38- for img in ui. images . iter ( ) {
39- renderer. draw_image (
40- iced_core:: Image {
41- handle : img. image . clone ( ) ,
42- filter_method : iced_core:: image:: FilterMethod :: default ( ) ,
43- rotation : iced_core:: Radians ( 0.0 ) ,
44- opacity : 1.0 ,
45- snap : false ,
46- } ,
47- iced_core:: Rectangle {
48- x : img. rect . origin . x ,
49- y : img. rect . origin . y ,
50- width : img. rect . size . width ,
51- height : img. rect . size . height ,
52- } ,
53- ) ;
36+ pub fn render < ' rpass > ( & ' rpass self , rpass : & mut wgpu_jumpstart:: RenderPass < ' rpass > ) {
37+ for layer in self . layers . iter ( ) {
38+ layer. quad_renderer . render ( rpass) ;
39+ layer. text_renderer . render ( rpass) ;
40+ }
5441 }
42+ }
5543
56- for icon in ui. icons . iter ( ) {
57- text_renderer. queue_icon ( icon. origin . x , icon. origin . y , icon. size , & icon. icon ) ;
58- }
44+ fn render_nuon ( ui : & mut nuon:: Ui , nuon_renderer : & mut NuonRenderer , ctx : & mut Context ) {
45+ nuon_renderer. ensure_layers ( ctx, ui. layers . len ( ) ) ;
5946
60- for text in ui. text . iter ( ) {
61- let buffer = if text. bold {
62- TextRenderer :: gen_buffer_bold ( text. size , & text. text )
63- } else {
64- TextRenderer :: gen_buffer ( text. size , & text. text )
65- } ;
47+ let renderer = & mut ctx. iced_manager . renderer ;
6648
67- match text. text_justify {
68- nuon:: TextJustify :: Left => {
69- text_renderer. queue_buffer_left ( text. rect , buffer) ;
70- }
71- nuon:: TextJustify :: Right => {
72- text_renderer. queue_buffer_right ( text. rect , buffer) ;
73- }
74- nuon:: TextJustify :: Center => {
75- text_renderer. queue_buffer_centered ( text. rect , buffer) ;
49+ for ( layer, out) in ui. layers . iter ( ) . zip ( nuon_renderer. layers . iter_mut ( ) ) {
50+ out. quad_renderer . clear ( ) ;
51+ out. quad_renderer . set_scissor_rect ( layer. scissor_rect ) ;
52+ out. text_renderer . set_scissor_rect ( layer. scissor_rect ) ;
53+
54+ for quad in layer. quads . iter ( ) {
55+ out. quad_renderer
56+ . push ( neothesia_core:: render:: QuadInstance {
57+ position : quad. rect . origin . into ( ) ,
58+ size : quad. rect . size . into ( ) ,
59+ color : wgpu_jumpstart:: Color :: new (
60+ quad. color . r ,
61+ quad. color . g ,
62+ quad. color . b ,
63+ quad. color . a ,
64+ )
65+ . into_linear_rgba ( ) ,
66+ border_radius : quad. border_radius ,
67+ } ) ;
68+ }
69+
70+ for img in layer. images . iter ( ) {
71+ renderer. draw_image (
72+ iced_core:: Image {
73+ handle : img. image . clone ( ) ,
74+ filter_method : iced_core:: image:: FilterMethod :: default ( ) ,
75+ rotation : iced_core:: Radians ( 0.0 ) ,
76+ opacity : 1.0 ,
77+ snap : false ,
78+ } ,
79+ iced_core:: Rectangle {
80+ x : img. rect . origin . x ,
81+ y : img. rect . origin . y ,
82+ width : img. rect . size . width ,
83+ height : img. rect . size . height ,
84+ } ,
85+ ) ;
86+ }
87+
88+ for icon in layer. icons . iter ( ) {
89+ out. text_renderer
90+ . queue_icon ( icon. origin . x , icon. origin . y , icon. size , & icon. icon ) ;
91+ }
92+
93+ for text in layer. text . iter ( ) {
94+ let buffer = if text. bold {
95+ TextRenderer :: gen_buffer_bold ( text. size , & text. text )
96+ } else {
97+ TextRenderer :: gen_buffer ( text. size , & text. text )
98+ } ;
99+
100+ match text. text_justify {
101+ nuon:: TextJustify :: Left => {
102+ out. text_renderer . queue_buffer_left ( text. rect , buffer) ;
103+ }
104+ nuon:: TextJustify :: Right => {
105+ out. text_renderer . queue_buffer_right ( text. rect , buffer) ;
106+ }
107+ nuon:: TextJustify :: Center => {
108+ out. text_renderer . queue_buffer_centered ( text. rect , buffer) ;
109+ }
76110 }
77111 }
112+
113+ out. quad_renderer . prepare ( ) ;
114+ out. text_renderer
115+ . update ( ctx. window_state . logical_size . into ( ) ) ;
78116 }
79117
80118 ui. done ( ) ;
0 commit comments