This commit is contained in:
Carter Anderson 2020-05-04 01:22:25 -07:00
parent 1056b79abf
commit dcc34473e5
9 changed files with 113 additions and 5 deletions

View file

@ -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"

View file

@ -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 {

View file

@ -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()
},
}
}
}

View file

@ -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();

View 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
View 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()
});
}

View file

@ -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

View file

@ -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();

View file

@ -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::{