sprites
This commit is contained in:
		
							parent
							
								
									1056b79abf
								
							
						
					
					
						commit
						dcc34473e5
					
				@ -65,6 +65,10 @@ opt-level = 3
 | 
			
		||||
name = "hello_world"
 | 
			
		||||
path = "examples/hello_world.rs"
 | 
			
		||||
 | 
			
		||||
[[example]]
 | 
			
		||||
name = "sprite"
 | 
			
		||||
path = "examples/2d/sprite.rs"
 | 
			
		||||
 | 
			
		||||
[[example]]
 | 
			
		||||
name = "load_model"
 | 
			
		||||
path = "examples/3d/load_model.rs"
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,12 @@ pub struct Texture {
 | 
			
		||||
    pub height: usize,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Texture {
 | 
			
		||||
    pub fn aspect(&self) -> f32 {
 | 
			
		||||
        self.height as f32 / self.width as f32
 | 
			
		||||
    } 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Asset<TextureType> for Texture {
 | 
			
		||||
    fn load(descriptor: TextureType) -> Self {
 | 
			
		||||
        let (data, width, height) = match descriptor {
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
use super::Node;
 | 
			
		||||
use crate::{render::UI_PIPELINE_HANDLE, ColorMaterial, Rect, QUAD_HANDLE};
 | 
			
		||||
use crate::{render::UI_PIPELINE_HANDLE, ColorMaterial, Rect, QUAD_HANDLE, sprite::Sprite};
 | 
			
		||||
use bevy_asset::Handle;
 | 
			
		||||
use bevy_derive::EntityArchetype;
 | 
			
		||||
use bevy_render::{mesh::Mesh, Renderable};
 | 
			
		||||
@ -28,3 +28,28 @@ impl Default for UiEntity {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(EntityArchetype)]
 | 
			
		||||
#[module(meta = false)]
 | 
			
		||||
pub struct SpriteEntity {
 | 
			
		||||
    pub sprite: Sprite,
 | 
			
		||||
    pub rect: Rect,
 | 
			
		||||
    pub mesh: Handle<Mesh>,              // TODO: maybe abstract this out
 | 
			
		||||
    pub material: Handle<ColorMaterial>,
 | 
			
		||||
    pub renderable: Renderable,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for SpriteEntity {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        SpriteEntity {
 | 
			
		||||
            sprite: Default::default(),
 | 
			
		||||
            rect: Default::default(),
 | 
			
		||||
            mesh: QUAD_HANDLE,
 | 
			
		||||
            material: Default::default(),
 | 
			
		||||
            renderable: Renderable {
 | 
			
		||||
                pipelines: vec![UI_PIPELINE_HANDLE],
 | 
			
		||||
                ..Default::default()
 | 
			
		||||
            },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -4,6 +4,7 @@ pub mod entity;
 | 
			
		||||
mod margins;
 | 
			
		||||
mod node;
 | 
			
		||||
mod rect;
 | 
			
		||||
mod sprite;
 | 
			
		||||
mod render;
 | 
			
		||||
mod ui_update_system;
 | 
			
		||||
 | 
			
		||||
@ -14,6 +15,7 @@ pub use node::*;
 | 
			
		||||
pub use rect::*;
 | 
			
		||||
pub use render::*;
 | 
			
		||||
pub use ui_update_system::*;
 | 
			
		||||
pub use sprite::*;
 | 
			
		||||
 | 
			
		||||
use bevy_app::{stage, AppBuilder, AppPlugin};
 | 
			
		||||
use bevy_asset::{AssetStorage, Handle};
 | 
			
		||||
@ -24,6 +26,7 @@ use bevy_render::{
 | 
			
		||||
};
 | 
			
		||||
use glam::Vec2;
 | 
			
		||||
use legion::prelude::IntoSystem;
 | 
			
		||||
use sprite::sprite_system;
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
pub struct UiPlugin;
 | 
			
		||||
@ -42,7 +45,8 @@ impl AppPlugin for UiPlugin {
 | 
			
		||||
                stage::POST_UPDATE,
 | 
			
		||||
                asset_handle_shader_def_system::<ColorMaterial>.system(),
 | 
			
		||||
            )
 | 
			
		||||
            .add_system(ui_update_system());
 | 
			
		||||
            .add_system_to_stage(stage::POST_UPDATE, sprite_system())
 | 
			
		||||
            .add_system_to_stage(stage::POST_UPDATE, ui_update_system());
 | 
			
		||||
 | 
			
		||||
        let resources = app.resources();
 | 
			
		||||
        let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								crates/bevy_ui/src/sprite.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								crates/bevy_ui/src/sprite.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
use crate::{ColorMaterial, Rect};
 | 
			
		||||
use bevy_asset::{AssetStorage, Handle};
 | 
			
		||||
use bevy_render::texture::Texture;
 | 
			
		||||
pub use legion::prelude::*;
 | 
			
		||||
pub struct Sprite {
 | 
			
		||||
    pub scale: f32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for Sprite {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Sprite {
 | 
			
		||||
            scale: 1.0
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn sprite_system() -> Box<dyn Schedulable> {
 | 
			
		||||
    SystemBuilder::new("sprite_system")
 | 
			
		||||
        .read_resource::<AssetStorage<ColorMaterial>>()
 | 
			
		||||
        .read_resource::<AssetStorage<Texture>>()
 | 
			
		||||
        .with_query(
 | 
			
		||||
            <(Read<Sprite>, Read<Handle<ColorMaterial>>, Write<Rect>)>::query().filter(
 | 
			
		||||
                changed::<Sprite>() | changed::<Rect>() | changed::<Handle<ColorMaterial>>(),
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
        .build(|_, world, (materials, textures), query| {
 | 
			
		||||
            for (sprite, handle, mut rect) in query.iter_mut(world) {
 | 
			
		||||
                let material = materials.get(&handle).unwrap();
 | 
			
		||||
                if let Some(texture_handle) = material.texture {
 | 
			
		||||
                    let texture = textures.get(&texture_handle).unwrap();
 | 
			
		||||
                    let aspect = texture.aspect();
 | 
			
		||||
                    *rect.size.x_mut() = texture.width as f32 * sprite.scale;
 | 
			
		||||
                    *rect.size.y_mut() = rect.size.x() * aspect;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								examples/2d/sprite.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								examples/2d/sprite.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
use bevy::prelude::*;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    App::build()
 | 
			
		||||
        .add_default_plugins()
 | 
			
		||||
        .add_startup_system(setup)
 | 
			
		||||
        .run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn setup(world: &mut World, resources: &mut Resources) {
 | 
			
		||||
    let mut texture_storage = resources.get_mut::<AssetStorage<Texture>>().unwrap();
 | 
			
		||||
    let texture_path = concat!(
 | 
			
		||||
        env!("CARGO_MANIFEST_DIR"),
 | 
			
		||||
        "/assets/branding/icon.png"
 | 
			
		||||
    );
 | 
			
		||||
    let texture = Texture::load(TextureType::Png(texture_path.to_string()));
 | 
			
		||||
    let texture_handle = texture_storage.add(texture);
 | 
			
		||||
    let mut color_materials = resources.get_mut::<AssetStorage<ColorMaterial>>().unwrap();
 | 
			
		||||
 | 
			
		||||
    world
 | 
			
		||||
        .build()
 | 
			
		||||
        .add_entity(Camera2dEntity::default())
 | 
			
		||||
        .add_entity(SpriteEntity {
 | 
			
		||||
            rect: Rect {
 | 
			
		||||
                position: Vec2::new(300.0, 300.0),
 | 
			
		||||
                z_index: 0.5,
 | 
			
		||||
                ..Default::default()
 | 
			
		||||
            },
 | 
			
		||||
            material: color_materials.add(texture_handle.into()),
 | 
			
		||||
            ..Default::default()
 | 
			
		||||
        });
 | 
			
		||||
}
 | 
			
		||||
@ -16,7 +16,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
 | 
			
		||||
        "/assets/branding/bevy_logo_dark_big.png"
 | 
			
		||||
    );
 | 
			
		||||
    let texture = Texture::load(TextureType::Png(texture_path.to_string()));
 | 
			
		||||
    let aspect = texture.height as f32 / texture.width as f32;
 | 
			
		||||
    let aspect = texture.aspect();
 | 
			
		||||
    let texture_handle = texture_storage.add(texture);
 | 
			
		||||
 | 
			
		||||
    // create a new quad mesh. this is what we will apply the texture to
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
 | 
			
		||||
        "/assets/branding/bevy_logo_dark_big.png"
 | 
			
		||||
    );
 | 
			
		||||
    let texture = Texture::load(TextureType::Png(texture_path.to_string()));
 | 
			
		||||
    let aspect = texture.height as f32 / texture.width as f32;
 | 
			
		||||
    let aspect = texture.aspect();
 | 
			
		||||
    let texture_handle = texture_storage.add(texture);
 | 
			
		||||
 | 
			
		||||
    let mut color_materials = resources.get_mut::<AssetStorage<ColorMaterial>>().unwrap();
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@ pub use crate::render::{
 | 
			
		||||
#[cfg(feature = "transform")]
 | 
			
		||||
pub use crate::transform::prelude::*;
 | 
			
		||||
#[cfg(feature = "ui")]
 | 
			
		||||
pub use crate::ui::{entity::*, Anchors, Margins, Node, ColorMaterial};
 | 
			
		||||
pub use crate::ui::{entity::*, Anchors, Rect, Sprite, Margins, Node, ColorMaterial};
 | 
			
		||||
#[cfg(feature = "window")]
 | 
			
		||||
pub use crate::window::{Window, WindowDescriptor, WindowPlugin, Windows};
 | 
			
		||||
pub use crate::{
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user