@@ -339,130 +339,128 @@ pub fn prepare_sprites(
339339 sprite_meta. vertices . clear ( ) ;
340340 sprite_meta. colored_vertices . clear ( ) ;
341341
342- // We divide the sprites according to their color
343- let [ mut white_sprites, mut colored_sprites] = extracted_sprites. sprites . drain ( ..) . fold (
344- [ vec ! [ ] , vec ! [ ] ] ,
345- |[ mut colored, mut white] , sprite| {
346- if sprite. color == Color :: WHITE {
347- white. push ( sprite) ;
348- } else {
349- colored. push ( sprite)
350- }
351- [ colored, white]
352- } ,
353- ) ;
354-
355342 // Sort sprites by z for correct transparency and then by handle to improve batching
356- let sort = |vec : & mut Vec < ExtractedSprite > | {
357- vec. sort_unstable_by ( |a, b| {
358- match a
359- . transform
360- . translation
361- . z
362- . partial_cmp ( & b. transform . translation . z )
343+ extracted_sprites. sprites . sort_unstable_by ( |a, b| {
344+ match a
345+ . transform
346+ . translation
347+ . z
348+ . partial_cmp ( & b. transform . translation . z )
349+ {
350+ Some ( Ordering :: Equal ) | None => a. image_handle_id . cmp ( & b. image_handle_id ) ,
351+ Some ( other) => other,
352+ }
353+ } ) ;
354+
355+ // Impossible starting values that will be replaced on the first iteration
356+ let mut current_batch_handle = HandleId :: Id ( Uuid :: nil ( ) , u64:: MAX ) ;
357+ let mut current_image_size = Vec2 :: ZERO ;
358+ let mut current_batch_colored = false ;
359+ let mut z_order = 0.0 ;
360+
361+ // Vertex buffer indices
362+ let [ mut white_start, mut white_end] = [ 0 , 0 ] ;
363+ let [ mut colored_start, mut colored_end] = [ 0 , 0 ] ;
364+
365+ for extracted_sprite in extracted_sprites. sprites . drain ( ..) {
366+ let colored = extracted_sprite. color != Color :: WHITE ;
367+ if extracted_sprite. image_handle_id != current_batch_handle
368+ || colored != current_batch_colored
369+ {
370+ if let Some ( gpu_image) = gpu_images. get ( & Handle :: weak ( extracted_sprite. image_handle_id ) )
363371 {
364- Some ( Ordering :: Equal ) | None => a. image_handle_id . cmp ( & b. image_handle_id ) ,
365- Some ( other) => other,
366- }
367- } ) ;
368- } ;
369- sort ( & mut white_sprites) ;
370- sort ( & mut colored_sprites) ;
371-
372- for ( colored, sprites) in [ ( false , white_sprites) , ( true , colored_sprites) ] {
373- // Impossible starting values that will be replaced on the first iteration
374- let mut current_batch_handle = HandleId :: Id ( Uuid :: nil ( ) , u64:: MAX ) ;
375- let mut current_image_size = Vec2 :: ZERO ;
376- let mut z_order = 0.0 ;
377-
378- // Vertex buffer indices
379- let mut index_start = 0 ;
380- let mut index_end = 0 ;
381-
382- for extracted_sprite in sprites {
383- if extracted_sprite. image_handle_id != current_batch_handle {
384- if let Some ( gpu_image) =
385- gpu_images. get ( & Handle :: weak ( extracted_sprite. image_handle_id ) )
386- {
387- current_image_size = gpu_image. size ;
388- current_batch_handle = extracted_sprite. image_handle_id ;
389- if index_start != index_end {
390- commands. spawn ( ) . insert ( SpriteBatch {
391- range : index_start..index_end,
392- image_handle_id : current_batch_handle,
393- colored,
394- z_order,
395- } ) ;
396- index_start = index_end;
397- }
398- } else {
399- // We skip loading images
400- continue ;
372+ current_image_size = gpu_image. size ;
373+ current_batch_handle = extracted_sprite. image_handle_id ;
374+ current_batch_colored = colored;
375+ let [ start, end] = match colored {
376+ true => [ & mut colored_start, & mut colored_end] ,
377+ false => [ & mut white_start, & mut white_end] ,
378+ } ;
379+ if * start != * end {
380+ commands. spawn ( ) . insert ( SpriteBatch {
381+ range : * start..* end,
382+ image_handle_id : current_batch_handle,
383+ colored : current_batch_colored,
384+ z_order,
385+ } ) ;
386+ * start = * end;
401387 }
388+ } else {
389+ // We skip loading images
390+ continue ;
402391 }
403- // Calculate vertex data for this item
404- let mut uvs = QUAD_UVS ;
405- if extracted_sprite. flip_x {
406- uvs = [ uvs[ 1 ] , uvs[ 0 ] , uvs[ 3 ] , uvs[ 2 ] ] ;
407- }
408- if extracted_sprite. flip_y {
409- uvs = [ uvs[ 3 ] , uvs[ 2 ] , uvs[ 1 ] , uvs[ 0 ] ] ;
410- }
411-
412- // By default, the size of the quad is the size of the texture
413- let mut quad_size = current_image_size;
392+ }
393+ // Calculate vertex data for this item
394+ let mut uvs = QUAD_UVS ;
395+ if extracted_sprite. flip_x {
396+ uvs = [ uvs[ 1 ] , uvs[ 0 ] , uvs[ 3 ] , uvs[ 2 ] ] ;
397+ }
398+ if extracted_sprite. flip_y {
399+ uvs = [ uvs[ 3 ] , uvs[ 2 ] , uvs[ 1 ] , uvs[ 0 ] ] ;
400+ }
414401
415- // If a rect is specified, adjust UVs and the size of the quad
416- if let Some ( rect) = extracted_sprite. rect {
417- let rect_size = rect. size ( ) ;
418- for uv in & mut uvs {
419- * uv = ( rect. min + * uv * rect_size) / current_image_size;
420- }
421- quad_size = rect_size;
422- }
402+ // By default, the size of the quad is the size of the texture
403+ let mut quad_size = current_image_size;
423404
424- // Override the size if a custom one is specified
425- if let Some ( custom_size) = extracted_sprite. custom_size {
426- quad_size = custom_size;
405+ // If a rect is specified, adjust UVs and the size of the quad
406+ if let Some ( rect) = extracted_sprite. rect {
407+ let rect_size = rect. size ( ) ;
408+ for uv in & mut uvs {
409+ * uv = ( rect. min + * uv * rect_size) / current_image_size;
427410 }
411+ quad_size = rect_size;
412+ }
428413
429- // Apply size and global transform
430- let positions = QUAD_VERTEX_POSITIONS . map ( |quad_pos| {
431- extracted_sprite
432- . transform
433- . mul_vec3 ( ( ( quad_pos - extracted_sprite. anchor ) * quad_size) . extend ( 0. ) )
434- . into ( )
435- } ) ;
414+ // Override the size if a custom one is specified
415+ if let Some ( custom_size) = extracted_sprite. custom_size {
416+ quad_size = custom_size;
417+ }
436418
437- if colored {
438- for i in QUAD_INDICES {
439- sprite_meta. colored_vertices . push ( ColoredSpriteVertex {
440- position : positions[ i] ,
441- uv : uvs[ i] . into ( ) ,
442- color : extracted_sprite. color . as_linear_rgba_f32 ( ) ,
443- } ) ;
444- }
445- } else {
446- for i in QUAD_INDICES {
447- sprite_meta. vertices . push ( SpriteVertex {
448- position : positions[ i] ,
449- uv : uvs[ i] . into ( ) ,
450- } ) ;
451- }
419+ // Apply size and global transform
420+ let positions = QUAD_VERTEX_POSITIONS . map ( |quad_pos| {
421+ extracted_sprite
422+ . transform
423+ . mul_vec3 ( ( ( quad_pos - extracted_sprite. anchor ) * quad_size) . extend ( 0. ) )
424+ . into ( )
425+ } ) ;
426+ if colored {
427+ for i in QUAD_INDICES {
428+ sprite_meta. colored_vertices . push ( ColoredSpriteVertex {
429+ position : positions[ i] ,
430+ uv : uvs[ i] . into ( ) ,
431+ color : extracted_sprite. color . as_linear_rgba_f32 ( ) ,
432+ } ) ;
452433 }
453- index_end += QUAD_INDICES . len ( ) as u32 ;
454- z_order = extracted_sprite. transform . translation . z ;
455- }
456- // if start != end, there is one last batch to process
457- if index_start != index_end {
458- commands. spawn ( ) . insert ( SpriteBatch {
459- range : index_start..index_end,
460- image_handle_id : current_batch_handle,
461- colored,
462- z_order,
463- } ) ;
434+ colored_end += QUAD_INDICES . len ( ) as u32 ;
435+ } else {
436+ for i in QUAD_INDICES {
437+ sprite_meta. vertices . push ( SpriteVertex {
438+ position : positions[ i] ,
439+ uv : uvs[ i] . into ( ) ,
440+ } ) ;
441+ }
442+ white_end += QUAD_INDICES . len ( ) as u32 ;
464443 }
444+ z_order = extracted_sprite. transform . translation . z ;
465445 }
446+ // if start != end, there is one last batch to process
447+ if white_start != white_end {
448+ commands. spawn ( ) . insert ( SpriteBatch {
449+ range : white_start..white_end,
450+ image_handle_id : current_batch_handle,
451+ colored : false ,
452+ z_order,
453+ } ) ;
454+ }
455+ if colored_start != colored_end {
456+ commands. spawn ( ) . insert ( SpriteBatch {
457+ range : colored_start..colored_end,
458+ image_handle_id : current_batch_handle,
459+ colored : true ,
460+ z_order,
461+ } ) ;
462+ }
463+
466464 sprite_meta
467465 . vertices
468466 . write_buffer ( & render_device, & render_queue) ;
0 commit comments