@@ -13,9 +13,11 @@ use crate::{
1313 texture:: BevyDefault ,
1414} ;
1515use bevy_asset:: HandleUntyped ;
16+ use bevy_derive:: { Deref , DerefMut } ;
1617use bevy_ecs:: system:: { lifetimeless:: SRes , SystemParamItem } ;
1718use bevy_math:: Vec2 ;
1819use bevy_reflect:: TypeUuid ;
20+ use std:: hash:: Hash ;
1921use thiserror:: Error ;
2022use wgpu:: {
2123 Extent3d , ImageCopyTexture , ImageDataLayout , Origin3d , TextureDimension , TextureFormat ,
@@ -106,9 +108,49 @@ pub struct Image {
106108 pub data : Vec < u8 > ,
107109 // TODO: this nesting makes accessing Image metadata verbose. Either flatten out descriptor or add accessors
108110 pub texture_descriptor : wgpu:: TextureDescriptor < ' static > ,
109- pub sampler_descriptor : wgpu :: SamplerDescriptor < ' static > ,
111+ pub sampler_descriptor : ImageSampler ,
110112}
111113
114+ /// Used in `Image`, this determines what image sampler to use when rendering. The default setting,
115+ /// [`ImageSampler::Default`], will result in reading the sampler set in the [`DefaultImageSampler`]
116+ /// resource - the global default sampler - at runtime. Setting this to [`ImageSampler::Descriptor`]
117+ /// will override the global default descriptor for this [`Image`].
118+ #[ derive( Debug , Clone ) ]
119+ pub enum ImageSampler {
120+ Default ,
121+ Descriptor ( wgpu:: SamplerDescriptor < ' static > ) ,
122+ }
123+ impl Default for ImageSampler {
124+ fn default ( ) -> Self {
125+ Self :: Default
126+ }
127+ }
128+
129+ impl ImageSampler {
130+ /// Returns a sampler descriptor with `Linear` min and mag filters
131+ pub fn linear_descriptor ( ) -> wgpu:: SamplerDescriptor < ' static > {
132+ wgpu:: SamplerDescriptor {
133+ mag_filter : wgpu:: FilterMode :: Linear ,
134+ min_filter : wgpu:: FilterMode :: Linear ,
135+ ..Default :: default ( )
136+ }
137+ }
138+
139+ /// Returns a sampler descriptor with `Nearest` min and mag filters
140+ pub fn nearest_descriptor ( ) -> wgpu:: SamplerDescriptor < ' static > {
141+ wgpu:: SamplerDescriptor {
142+ mag_filter : wgpu:: FilterMode :: Nearest ,
143+ min_filter : wgpu:: FilterMode :: Nearest ,
144+ ..Default :: default ( )
145+ }
146+ }
147+ }
148+
149+ /// Resource used as the global default image sampler for [`Image`]s with their `sampler_descriptor`
150+ /// set to [`ImageSampler::Default`].
151+ #[ derive( Debug , Clone , Deref , DerefMut ) ]
152+ pub struct DefaultImageSampler ( pub ( crate ) Sampler ) ;
153+
112154impl Default for Image {
113155 fn default ( ) -> Self {
114156 let format = wgpu:: TextureFormat :: bevy_default ( ) ;
@@ -128,7 +170,7 @@ impl Default for Image {
128170 sample_count : 1 ,
129171 usage : wgpu:: TextureUsages :: TEXTURE_BINDING | wgpu:: TextureUsages :: COPY_DST ,
130172 } ,
131- sampler_descriptor : wgpu :: SamplerDescriptor :: default ( ) ,
173+ sampler_descriptor : ImageSampler :: Default ,
132174 }
133175 }
134176}
@@ -540,7 +582,11 @@ pub struct GpuImage {
540582impl RenderAsset for Image {
541583 type ExtractedAsset = Image ;
542584 type PreparedAsset = GpuImage ;
543- type Param = ( SRes < RenderDevice > , SRes < RenderQueue > ) ;
585+ type Param = (
586+ SRes < RenderDevice > ,
587+ SRes < RenderQueue > ,
588+ SRes < DefaultImageSampler > ,
589+ ) ;
544590
545591 /// Clones the Image.
546592 fn extract_asset ( & self ) -> Self :: ExtractedAsset {
@@ -550,7 +596,7 @@ impl RenderAsset for Image {
550596 /// Converts the extracted image into a [`GpuImage`].
551597 fn prepare_asset (
552598 image : Self :: ExtractedAsset ,
553- ( render_device, render_queue) : & mut SystemParamItem < Self :: Param > ,
599+ ( render_device, render_queue, default_sampler ) : & mut SystemParamItem < Self :: Param > ,
554600 ) -> Result < Self :: PreparedAsset , PrepareAssetError < Self :: ExtractedAsset > > {
555601 let texture = if image. texture_descriptor . mip_level_count > 1 || image. is_compressed ( ) {
556602 render_device. create_texture_with_data (
@@ -593,7 +639,11 @@ impl RenderAsset for Image {
593639 image. texture_descriptor . size . width as f32 ,
594640 image. texture_descriptor . size . height as f32 ,
595641 ) ;
596- let sampler = render_device. create_sampler ( & image. sampler_descriptor ) ;
642+ let sampler = match image. sampler_descriptor {
643+ ImageSampler :: Default => ( * * * default_sampler) . clone ( ) ,
644+ ImageSampler :: Descriptor ( descriptor) => render_device. create_sampler ( & descriptor) ,
645+ } ;
646+
597647 Ok ( GpuImage {
598648 texture,
599649 texture_view,
0 commit comments