11//! Editor-environment specific DMI (texture) handling.
22
3+ use lodepng:: { self , ColorType , Decoder , RGBA } ;
4+ use sdl3:: gpu:: {
5+ Device , Texture , TextureCreateInfo , TextureRegion , TextureTransferInfo , TextureUsage ,
6+ TransferBufferUsage ,
7+ } ;
38use std:: collections:: hash_map:: HashMap ;
4- use std:: io;
9+ use std:: io:: { self , Write } ;
510use std:: path:: { Path , PathBuf } ;
611use std:: sync:: { Arc , RwLock } ;
712
8- use lodepng:: { self , ColorType , Decoder , RGBA } ;
9- use sdl3:: pixels:: { PixelFormat , PixelFormatEnum } ;
10- use sdl3:: render:: Texture ;
11- use sdl3:: surface:: Surface ;
12-
13- use crate :: support:: TextureCreator ;
14-
1513type Rect = ( u32 , u32 , u32 , u32 ) ;
1614
1715pub use dreammaker:: dmi:: * ;
@@ -25,8 +23,8 @@ pub struct IconCache {
2523}
2624
2725#[ derive( Default ) ]
28- pub struct TextureCache < ' r > {
29- textures : Vec < Option < Texture < ' r > > > ,
26+ pub struct TextureCache {
27+ textures : Vec < Option < Texture < ' static > > > ,
3028}
3129
3230#[ derive( Default ) ]
@@ -86,17 +84,12 @@ impl IconCache {
8684 }*/
8785}
8886
89- impl < ' r > TextureCache < ' r > {
90- pub fn retrieve (
91- & mut self ,
92- factory : & ' r TextureCreator ,
93- icons : & IconCache ,
94- id : usize ,
95- ) -> & Texture {
87+ impl TextureCache {
88+ pub fn retrieve ( & mut self , device : & Device , icons : & IconCache , id : usize ) -> & Texture {
9689 if id >= self . textures . len ( ) {
9790 self . textures . resize_with ( id + 1 , Default :: default) ;
9891 }
99- self . textures [ id] . get_or_insert_with ( || load_texture ( factory , & icons. get_icon ( id) . bitmap ) )
92+ self . textures [ id] . get_or_insert_with ( || load_texture ( device , & icons. get_icon ( id) . bitmap ) )
10093 }
10194
10295 pub fn clear ( & mut self ) {
@@ -153,10 +146,7 @@ impl IconFile {
153146 }
154147}
155148
156- pub fn texture_from_bytes < ' r > (
157- factory : & ' r TextureCreator ,
158- bytes : & [ u8 ] ,
159- ) -> io:: Result < Texture < ' r > > {
149+ pub fn texture_from_bytes < ' r > ( device : & Device , bytes : & [ u8 ] ) -> io:: Result < Texture < ' r > > {
160150 let mut decoder = Decoder :: new ( ) ;
161151 decoder. info_raw_mut ( ) . colortype = ColorType :: RGBA ;
162152 decoder. info_raw_mut ( ) . set_bitdepth ( 8 ) ;
@@ -166,33 +156,59 @@ pub fn texture_from_bytes<'r>(
166156 Ok ( _) => return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidData , "not RGBA" ) ) ,
167157 Err ( e) => return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidData , e) ) ,
168158 } ;
169- Ok ( load_texture ( factory , & bitmap) )
159+ Ok ( load_texture ( device , & bitmap) )
170160}
171161
172- pub fn load_texture < ' r > (
173- factory : & ' r TextureCreator ,
174- bitmap : & lodepng:: Bitmap < RGBA > ,
175- ) -> Texture < ' r > {
176- let width = bitmap. width ;
177- let height = bitmap. height ;
178-
179- let mut surface = Surface :: new (
180- width as u32 ,
181- height as u32 ,
182- PixelFormat :: from ( PixelFormatEnum :: RGBA8888 ) ,
183- )
184- . expect ( "Surface::new" ) ;
185- surface. with_lock_mut ( |dest| {
186- let mut dest = dest. iter_mut ( ) ;
187- for pixel in & bitmap. buffer {
188- * dest. next ( ) . unwrap ( ) = pixel. r ;
189- * dest. next ( ) . unwrap ( ) = pixel. g ;
190- * dest. next ( ) . unwrap ( ) = pixel. b ;
191- * dest. next ( ) . unwrap ( ) = pixel. a ;
192- }
193- } ) ;
194-
195- factory
196- . create_texture_from_surface ( surface)
197- . expect ( "create_texture_from_surface" )
162+ pub fn load_texture < ' r > ( device : & Device , bitmap : & lodepng:: Bitmap < RGBA > ) -> Texture < ' static > {
163+ let width = bitmap. width as u32 ;
164+ let height = bitmap. height as u32 ;
165+
166+ let texture = device
167+ . create_texture (
168+ TextureCreateInfo :: new ( )
169+ . with_type ( sdl3:: gpu:: TextureType :: _2D)
170+ . with_format ( sdl3:: gpu:: TextureFormat :: R8g8b8a8Unorm )
171+ . with_usage ( TextureUsage :: SAMPLER )
172+ . with_width ( width)
173+ . with_height ( height)
174+ . with_layer_count_or_depth ( 1 )
175+ . with_num_levels ( 1 ) ,
176+ )
177+ . expect ( "create_texture" ) ;
178+
179+ let transfer_buffer = device
180+ . create_transfer_buffer ( )
181+ . with_usage ( TransferBufferUsage :: UPLOAD )
182+ . with_size ( width * height * 4 )
183+ . build ( )
184+ . expect ( "create_transfer_buffer" ) ;
185+
186+ let mut mem = transfer_buffer. map :: < u8 > ( device, true ) ;
187+ let mut dest = mem. mem_mut ( ) ;
188+ for pixel in & bitmap. buffer {
189+ dest. write_all ( & [ pixel. a , pixel. b , pixel. g , pixel. r ] ) ;
190+ }
191+ mem. unmap ( ) ;
192+
193+ let source = TextureTransferInfo :: new ( )
194+ . with_transfer_buffer ( & transfer_buffer)
195+ . with_offset ( 0 ) ;
196+ let destination = TextureRegion :: new ( )
197+ . with_texture ( & texture)
198+ . with_width ( width)
199+ . with_height ( height)
200+ . with_depth ( 1 ) ;
201+
202+ let command_buffer = device
203+ . acquire_command_buffer ( )
204+ . expect ( "acquire_command_buffer" ) ;
205+ let copy_pass = device
206+ . begin_copy_pass ( & command_buffer)
207+ . expect ( "begin_copy_pass" ) ;
208+
209+ copy_pass. upload_to_gpu_texture ( source, destination, false ) ;
210+ device. end_copy_pass ( copy_pass) ;
211+ command_buffer. submit ( ) . expect ( "CommandBuffer::submit" ) ;
212+
213+ texture
198214}
0 commit comments