Change default Image FilterMode to Linear (#4465)
				
					
				
			# Objective - Closes #4464 ## Solution - Specify default mag and min filter types for `Image` instead of using `wgpu`'s defaults. --- ## Changelog ### Changed - Default `Image` filtering changed from `Nearest` to `Linear`. Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
		
							parent
							
								
									728d9696d7
								
							
						
					
					
						commit
						772d15238c
					
				@ -25,7 +25,7 @@ use bevy_render::{
 | 
				
			|||||||
    primitives::{Aabb, Frustum},
 | 
					    primitives::{Aabb, Frustum},
 | 
				
			||||||
    render_resource::{AddressMode, Face, FilterMode, PrimitiveTopology, SamplerDescriptor},
 | 
					    render_resource::{AddressMode, Face, FilterMode, PrimitiveTopology, SamplerDescriptor},
 | 
				
			||||||
    renderer::RenderDevice,
 | 
					    renderer::RenderDevice,
 | 
				
			||||||
    texture::{CompressedImageFormats, Image, ImageType, TextureError},
 | 
					    texture::{CompressedImageFormats, Image, ImageSampler, ImageType, TextureError},
 | 
				
			||||||
    view::VisibleEntities,
 | 
					    view::VisibleEntities,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bevy_scene::Scene;
 | 
					use bevy_scene::Scene;
 | 
				
			||||||
@ -619,7 +619,7 @@ async fn load_texture<'a>(
 | 
				
			|||||||
            )?
 | 
					            )?
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    texture.sampler_descriptor = texture_sampler(&gltf_texture);
 | 
					    texture.sampler_descriptor = ImageSampler::Descriptor(texture_sampler(&gltf_texture));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok((texture, texture_label(&gltf_texture)))
 | 
					    Ok((texture, texture_label(&gltf_texture)))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ use bevy_app::Plugin;
 | 
				
			|||||||
use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped};
 | 
					use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped};
 | 
				
			||||||
use bevy_ecs::{
 | 
					use bevy_ecs::{
 | 
				
			||||||
    prelude::*,
 | 
					    prelude::*,
 | 
				
			||||||
    system::{lifetimeless::*, SystemParamItem},
 | 
					    system::{lifetimeless::*, SystemParamItem, SystemState},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bevy_math::{Mat4, Vec2};
 | 
					use bevy_math::{Mat4, Vec2};
 | 
				
			||||||
use bevy_reflect::TypeUuid;
 | 
					use bevy_reflect::TypeUuid;
 | 
				
			||||||
@ -21,7 +21,9 @@ use bevy_render::{
 | 
				
			|||||||
    render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
 | 
					    render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
 | 
				
			||||||
    render_resource::*,
 | 
					    render_resource::*,
 | 
				
			||||||
    renderer::{RenderDevice, RenderQueue},
 | 
					    renderer::{RenderDevice, RenderQueue},
 | 
				
			||||||
    texture::{BevyDefault, GpuImage, Image, TextureFormatPixelInfo},
 | 
					    texture::{
 | 
				
			||||||
 | 
					        BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    view::{ComputedVisibility, ViewUniform, ViewUniformOffset, ViewUniforms},
 | 
					    view::{ComputedVisibility, ViewUniform, ViewUniformOffset, ViewUniforms},
 | 
				
			||||||
    RenderApp, RenderStage,
 | 
					    RenderApp, RenderStage,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -275,7 +277,12 @@ pub struct MeshPipeline {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl FromWorld for MeshPipeline {
 | 
					impl FromWorld for MeshPipeline {
 | 
				
			||||||
    fn from_world(world: &mut World) -> Self {
 | 
					    fn from_world(world: &mut World) -> Self {
 | 
				
			||||||
        let render_device = world.resource::<RenderDevice>();
 | 
					        let mut system_state: SystemState<(
 | 
				
			||||||
 | 
					            Res<RenderDevice>,
 | 
				
			||||||
 | 
					            Res<DefaultImageSampler>,
 | 
				
			||||||
 | 
					            Res<RenderQueue>,
 | 
				
			||||||
 | 
					        )> = SystemState::new(world);
 | 
				
			||||||
 | 
					        let (render_device, default_sampler, render_queue) = system_state.get_mut(world);
 | 
				
			||||||
        let clustered_forward_buffer_binding_type = render_device
 | 
					        let clustered_forward_buffer_binding_type = render_device
 | 
				
			||||||
            .get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT);
 | 
					            .get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -435,10 +442,12 @@ impl FromWorld for MeshPipeline {
 | 
				
			|||||||
                TextureFormat::bevy_default(),
 | 
					                TextureFormat::bevy_default(),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            let texture = render_device.create_texture(&image.texture_descriptor);
 | 
					            let texture = render_device.create_texture(&image.texture_descriptor);
 | 
				
			||||||
            let sampler = render_device.create_sampler(&image.sampler_descriptor);
 | 
					            let sampler = match image.sampler_descriptor {
 | 
				
			||||||
 | 
					                ImageSampler::Default => (**default_sampler).clone(),
 | 
				
			||||||
 | 
					                ImageSampler::Descriptor(descriptor) => render_device.create_sampler(&descriptor),
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let format_size = image.texture_descriptor.format.pixel_size();
 | 
					            let format_size = image.texture_descriptor.format.pixel_size();
 | 
				
			||||||
            let render_queue = world.resource_mut::<RenderQueue>();
 | 
					 | 
				
			||||||
            render_queue.write_texture(
 | 
					            render_queue.write_texture(
 | 
				
			||||||
                ImageCopyTexture {
 | 
					                ImageCopyTexture {
 | 
				
			||||||
                    texture: &texture,
 | 
					                    texture: &texture,
 | 
				
			||||||
 | 
				
			|||||||
@ -180,7 +180,8 @@ impl Plugin for RenderPlugin {
 | 
				
			|||||||
                .insert_resource(queue)
 | 
					                .insert_resource(queue)
 | 
				
			||||||
                .insert_resource(adapter_info)
 | 
					                .insert_resource(adapter_info)
 | 
				
			||||||
                .insert_resource(pipeline_cache)
 | 
					                .insert_resource(pipeline_cache)
 | 
				
			||||||
                .insert_resource(asset_server);
 | 
					                .insert_resource(asset_server)
 | 
				
			||||||
 | 
					                .init_resource::<RenderGraph>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            app.add_sub_app(RenderApp, render_app, move |app_world, render_app| {
 | 
					            app.add_sub_app(RenderApp, render_app, move |app_world, render_app| {
 | 
				
			||||||
                #[cfg(feature = "trace")]
 | 
					                #[cfg(feature = "trace")]
 | 
				
			||||||
 | 
				
			|||||||
@ -13,9 +13,11 @@ use crate::{
 | 
				
			|||||||
    texture::BevyDefault,
 | 
					    texture::BevyDefault,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bevy_asset::HandleUntyped;
 | 
					use bevy_asset::HandleUntyped;
 | 
				
			||||||
 | 
					use bevy_derive::{Deref, DerefMut};
 | 
				
			||||||
use bevy_ecs::system::{lifetimeless::SRes, SystemParamItem};
 | 
					use bevy_ecs::system::{lifetimeless::SRes, SystemParamItem};
 | 
				
			||||||
use bevy_math::Vec2;
 | 
					use bevy_math::Vec2;
 | 
				
			||||||
use bevy_reflect::TypeUuid;
 | 
					use bevy_reflect::TypeUuid;
 | 
				
			||||||
 | 
					use std::hash::Hash;
 | 
				
			||||||
use thiserror::Error;
 | 
					use thiserror::Error;
 | 
				
			||||||
use wgpu::{
 | 
					use wgpu::{
 | 
				
			||||||
    Extent3d, ImageCopyTexture, ImageDataLayout, Origin3d, TextureDimension, TextureFormat,
 | 
					    Extent3d, ImageCopyTexture, ImageDataLayout, Origin3d, TextureDimension, TextureFormat,
 | 
				
			||||||
@ -106,9 +108,49 @@ pub struct Image {
 | 
				
			|||||||
    pub data: Vec<u8>,
 | 
					    pub data: Vec<u8>,
 | 
				
			||||||
    // TODO: this nesting makes accessing Image metadata verbose. Either flatten out descriptor or add accessors
 | 
					    // TODO: this nesting makes accessing Image metadata verbose. Either flatten out descriptor or add accessors
 | 
				
			||||||
    pub texture_descriptor: wgpu::TextureDescriptor<'static>,
 | 
					    pub texture_descriptor: wgpu::TextureDescriptor<'static>,
 | 
				
			||||||
    pub sampler_descriptor: wgpu::SamplerDescriptor<'static>,
 | 
					    pub sampler_descriptor: ImageSampler,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Used in `Image`, this determines what image sampler to use when rendering. The default setting,
 | 
				
			||||||
 | 
					/// [`ImageSampler::Default`], will result in reading the sampler set in the [`DefaultImageSampler`]
 | 
				
			||||||
 | 
					/// resource - the global default sampler - at runtime. Setting this to [`ImageSampler::Descriptor`]
 | 
				
			||||||
 | 
					/// will override the global default descriptor for this [`Image`].
 | 
				
			||||||
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
 | 
					pub enum ImageSampler {
 | 
				
			||||||
 | 
					    Default,
 | 
				
			||||||
 | 
					    Descriptor(wgpu::SamplerDescriptor<'static>),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					impl Default for ImageSampler {
 | 
				
			||||||
 | 
					    fn default() -> Self {
 | 
				
			||||||
 | 
					        Self::Default
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ImageSampler {
 | 
				
			||||||
 | 
					    /// Returns a sampler descriptor with `Linear` min and mag filters
 | 
				
			||||||
 | 
					    pub fn linear_descriptor() -> wgpu::SamplerDescriptor<'static> {
 | 
				
			||||||
 | 
					        wgpu::SamplerDescriptor {
 | 
				
			||||||
 | 
					            mag_filter: wgpu::FilterMode::Linear,
 | 
				
			||||||
 | 
					            min_filter: wgpu::FilterMode::Linear,
 | 
				
			||||||
 | 
					            ..Default::default()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Returns a sampler descriptor with `Nearest` min and mag filters
 | 
				
			||||||
 | 
					    pub fn nearest_descriptor() -> wgpu::SamplerDescriptor<'static> {
 | 
				
			||||||
 | 
					        wgpu::SamplerDescriptor {
 | 
				
			||||||
 | 
					            mag_filter: wgpu::FilterMode::Nearest,
 | 
				
			||||||
 | 
					            min_filter: wgpu::FilterMode::Nearest,
 | 
				
			||||||
 | 
					            ..Default::default()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Resource used as the global default image sampler for [`Image`]s with their `sampler_descriptor`
 | 
				
			||||||
 | 
					/// set to [`ImageSampler::Default`].
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Deref, DerefMut)]
 | 
				
			||||||
 | 
					pub struct DefaultImageSampler(pub(crate) Sampler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Default for Image {
 | 
					impl Default for Image {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        let format = wgpu::TextureFormat::bevy_default();
 | 
					        let format = wgpu::TextureFormat::bevy_default();
 | 
				
			||||||
@ -128,7 +170,7 @@ impl Default for Image {
 | 
				
			|||||||
                sample_count: 1,
 | 
					                sample_count: 1,
 | 
				
			||||||
                usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
 | 
					                usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            sampler_descriptor: wgpu::SamplerDescriptor::default(),
 | 
					            sampler_descriptor: ImageSampler::Default,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -540,7 +582,11 @@ pub struct GpuImage {
 | 
				
			|||||||
impl RenderAsset for Image {
 | 
					impl RenderAsset for Image {
 | 
				
			||||||
    type ExtractedAsset = Image;
 | 
					    type ExtractedAsset = Image;
 | 
				
			||||||
    type PreparedAsset = GpuImage;
 | 
					    type PreparedAsset = GpuImage;
 | 
				
			||||||
    type Param = (SRes<RenderDevice>, SRes<RenderQueue>);
 | 
					    type Param = (
 | 
				
			||||||
 | 
					        SRes<RenderDevice>,
 | 
				
			||||||
 | 
					        SRes<RenderQueue>,
 | 
				
			||||||
 | 
					        SRes<DefaultImageSampler>,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Clones the Image.
 | 
					    /// Clones the Image.
 | 
				
			||||||
    fn extract_asset(&self) -> Self::ExtractedAsset {
 | 
					    fn extract_asset(&self) -> Self::ExtractedAsset {
 | 
				
			||||||
@ -550,7 +596,7 @@ impl RenderAsset for Image {
 | 
				
			|||||||
    /// Converts the extracted image into a [`GpuImage`].
 | 
					    /// Converts the extracted image into a [`GpuImage`].
 | 
				
			||||||
    fn prepare_asset(
 | 
					    fn prepare_asset(
 | 
				
			||||||
        image: Self::ExtractedAsset,
 | 
					        image: Self::ExtractedAsset,
 | 
				
			||||||
        (render_device, render_queue): &mut SystemParamItem<Self::Param>,
 | 
					        (render_device, render_queue, default_sampler): &mut SystemParamItem<Self::Param>,
 | 
				
			||||||
    ) -> Result<Self::PreparedAsset, PrepareAssetError<Self::ExtractedAsset>> {
 | 
					    ) -> Result<Self::PreparedAsset, PrepareAssetError<Self::ExtractedAsset>> {
 | 
				
			||||||
        let texture = if image.texture_descriptor.mip_level_count > 1 || image.is_compressed() {
 | 
					        let texture = if image.texture_descriptor.mip_level_count > 1 || image.is_compressed() {
 | 
				
			||||||
            render_device.create_texture_with_data(
 | 
					            render_device.create_texture_with_data(
 | 
				
			||||||
@ -593,7 +639,11 @@ impl RenderAsset for Image {
 | 
				
			|||||||
            image.texture_descriptor.size.width as f32,
 | 
					            image.texture_descriptor.size.width as f32,
 | 
				
			||||||
            image.texture_descriptor.size.height as f32,
 | 
					            image.texture_descriptor.size.height as f32,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        let sampler = render_device.create_sampler(&image.sampler_descriptor);
 | 
					        let sampler = match image.sampler_descriptor {
 | 
				
			||||||
 | 
					            ImageSampler::Default => (***default_sampler).clone(),
 | 
				
			||||||
 | 
					            ImageSampler::Descriptor(descriptor) => render_device.create_sampler(&descriptor),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(GpuImage {
 | 
					        Ok(GpuImage {
 | 
				
			||||||
            texture,
 | 
					            texture,
 | 
				
			||||||
            texture_view,
 | 
					            texture_view,
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,7 @@ pub use texture_cache::*;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    render_asset::{PrepareAssetLabel, RenderAssetPlugin},
 | 
					    render_asset::{PrepareAssetLabel, RenderAssetPlugin},
 | 
				
			||||||
 | 
					    renderer::RenderDevice,
 | 
				
			||||||
    RenderApp, RenderStage,
 | 
					    RenderApp, RenderStage,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bevy_app::{App, Plugin};
 | 
					use bevy_app::{App, Plugin};
 | 
				
			||||||
@ -63,14 +64,52 @@ impl Plugin for ImagePlugin {
 | 
				
			|||||||
            .resource_mut::<Assets<Image>>()
 | 
					            .resource_mut::<Assets<Image>>()
 | 
				
			||||||
            .set_untracked(DEFAULT_IMAGE_HANDLE, Image::default());
 | 
					            .set_untracked(DEFAULT_IMAGE_HANDLE, Image::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let default_sampler = app
 | 
				
			||||||
 | 
					            .world
 | 
				
			||||||
 | 
					            .get_resource_or_insert_with(ImageSettings::default)
 | 
				
			||||||
 | 
					            .default_sampler
 | 
				
			||||||
 | 
					            .clone();
 | 
				
			||||||
        if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
 | 
					        if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
 | 
				
			||||||
 | 
					            let default_sampler = {
 | 
				
			||||||
 | 
					                let device = render_app.world.resource::<RenderDevice>();
 | 
				
			||||||
 | 
					                device.create_sampler(&default_sampler)
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
            render_app
 | 
					            render_app
 | 
				
			||||||
 | 
					                .insert_resource(DefaultImageSampler(default_sampler))
 | 
				
			||||||
                .init_resource::<TextureCache>()
 | 
					                .init_resource::<TextureCache>()
 | 
				
			||||||
                .add_system_to_stage(RenderStage::Cleanup, update_texture_cache_system);
 | 
					                .add_system_to_stage(RenderStage::Cleanup, update_texture_cache_system);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// [`ImagePlugin`] settings.
 | 
				
			||||||
 | 
					pub struct ImageSettings {
 | 
				
			||||||
 | 
					    /// The default image sampler to use when [`ImageSampler`] is set to `Default`.
 | 
				
			||||||
 | 
					    pub default_sampler: wgpu::SamplerDescriptor<'static>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Default for ImageSettings {
 | 
				
			||||||
 | 
					    fn default() -> Self {
 | 
				
			||||||
 | 
					        ImageSettings::default_linear()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ImageSettings {
 | 
				
			||||||
 | 
					    /// Creates image settings with default linear sampling.
 | 
				
			||||||
 | 
					    pub fn default_linear() -> ImageSettings {
 | 
				
			||||||
 | 
					        ImageSettings {
 | 
				
			||||||
 | 
					            default_sampler: ImageSampler::linear_descriptor(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Creates image settings with default nearest sampling.
 | 
				
			||||||
 | 
					    pub fn default_nearest() -> ImageSettings {
 | 
				
			||||||
 | 
					        ImageSettings {
 | 
				
			||||||
 | 
					            default_sampler: ImageSampler::nearest_descriptor(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait BevyDefault {
 | 
					pub trait BevyDefault {
 | 
				
			||||||
    fn bevy_default() -> Self;
 | 
					    fn bevy_default() -> Self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@ use bevy_app::Plugin;
 | 
				
			|||||||
use bevy_asset::{load_internal_asset, Handle, HandleUntyped};
 | 
					use bevy_asset::{load_internal_asset, Handle, HandleUntyped};
 | 
				
			||||||
use bevy_ecs::{
 | 
					use bevy_ecs::{
 | 
				
			||||||
    prelude::*,
 | 
					    prelude::*,
 | 
				
			||||||
    system::{lifetimeless::*, SystemParamItem},
 | 
					    system::{lifetimeless::*, SystemParamItem, SystemState},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bevy_math::{Mat4, Vec2};
 | 
					use bevy_math::{Mat4, Vec2};
 | 
				
			||||||
use bevy_reflect::{Reflect, TypeUuid};
 | 
					use bevy_reflect::{Reflect, TypeUuid};
 | 
				
			||||||
@ -13,7 +13,9 @@ use bevy_render::{
 | 
				
			|||||||
    render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
 | 
					    render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
 | 
				
			||||||
    render_resource::*,
 | 
					    render_resource::*,
 | 
				
			||||||
    renderer::{RenderDevice, RenderQueue},
 | 
					    renderer::{RenderDevice, RenderQueue},
 | 
				
			||||||
    texture::{BevyDefault, GpuImage, Image, TextureFormatPixelInfo},
 | 
					    texture::{
 | 
				
			||||||
 | 
					        BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    view::{ComputedVisibility, ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms},
 | 
					    view::{ComputedVisibility, ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms},
 | 
				
			||||||
    RenderApp, RenderStage,
 | 
					    RenderApp, RenderStage,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -140,7 +142,9 @@ pub struct Mesh2dPipeline {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl FromWorld for Mesh2dPipeline {
 | 
					impl FromWorld for Mesh2dPipeline {
 | 
				
			||||||
    fn from_world(world: &mut World) -> Self {
 | 
					    fn from_world(world: &mut World) -> Self {
 | 
				
			||||||
        let render_device = world.resource::<RenderDevice>();
 | 
					        let mut system_state: SystemState<(Res<RenderDevice>, Res<DefaultImageSampler>)> =
 | 
				
			||||||
 | 
					            SystemState::new(world);
 | 
				
			||||||
 | 
					        let (render_device, default_sampler) = system_state.get_mut(world);
 | 
				
			||||||
        let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
 | 
					        let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
 | 
				
			||||||
            entries: &[
 | 
					            entries: &[
 | 
				
			||||||
                // View
 | 
					                // View
 | 
				
			||||||
@ -180,7 +184,10 @@ impl FromWorld for Mesh2dPipeline {
 | 
				
			|||||||
                TextureFormat::bevy_default(),
 | 
					                TextureFormat::bevy_default(),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            let texture = render_device.create_texture(&image.texture_descriptor);
 | 
					            let texture = render_device.create_texture(&image.texture_descriptor);
 | 
				
			||||||
            let sampler = render_device.create_sampler(&image.sampler_descriptor);
 | 
					            let sampler = match image.sampler_descriptor {
 | 
				
			||||||
 | 
					                ImageSampler::Default => (**default_sampler).clone(),
 | 
				
			||||||
 | 
					                ImageSampler::Descriptor(descriptor) => render_device.create_sampler(&descriptor),
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let format_size = image.texture_descriptor.format.pixel_size();
 | 
					            let format_size = image.texture_descriptor.format.pixel_size();
 | 
				
			||||||
            let render_queue = world.resource_mut::<RenderQueue>();
 | 
					            let render_queue = world.resource_mut::<RenderQueue>();
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,11 @@
 | 
				
			|||||||
//! Renders an animated sprite by loading all animation frames from a single image (a sprite sheet)
 | 
					//! Renders an animated sprite by loading all animation frames from a single image (a sprite sheet)
 | 
				
			||||||
//! into a texture atlas, and changing the displayed image periodically.
 | 
					//! into a texture atlas, and changing the displayed image periodically.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use bevy::prelude::*;
 | 
					use bevy::{prelude::*, render::texture::ImageSettings};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
    App::new()
 | 
					    App::new()
 | 
				
			||||||
 | 
					        .insert_resource(ImageSettings::default_nearest()) // prevents blurry sprites
 | 
				
			||||||
        .add_plugins(DefaultPlugins)
 | 
					        .add_plugins(DefaultPlugins)
 | 
				
			||||||
        .add_startup_system(setup)
 | 
					        .add_startup_system(setup)
 | 
				
			||||||
        .add_system(animate_sprite)
 | 
					        .add_system(animate_sprite)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,12 @@
 | 
				
			|||||||
//! In this example we generate a new texture atlas (sprite sheet) from a folder containing
 | 
					//! In this example we generate a new texture atlas (sprite sheet) from a folder containing
 | 
				
			||||||
//! individual sprites.
 | 
					//! individual sprites.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use bevy::{asset::LoadState, prelude::*};
 | 
					use bevy::{asset::LoadState, prelude::*, render::texture::ImageSettings};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
    App::new()
 | 
					    App::new()
 | 
				
			||||||
        .init_resource::<RpgSpriteHandles>()
 | 
					        .init_resource::<RpgSpriteHandles>()
 | 
				
			||||||
 | 
					        .insert_resource(ImageSettings::default_nearest()) // prevents blurry sprites
 | 
				
			||||||
        .add_plugins(DefaultPlugins)
 | 
					        .add_plugins(DefaultPlugins)
 | 
				
			||||||
        .add_state(AppState::Setup)
 | 
					        .add_state(AppState::Setup)
 | 
				
			||||||
        .add_system_set(SystemSet::on_enter(AppState::Setup).with_system(load_textures))
 | 
					        .add_system_set(SystemSet::on_enter(AppState::Setup).with_system(load_textures))
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user