sprite: use bevy_transform types in sprite entities

This commit is contained in:
Carter Anderson 2020-06-22 12:14:40 -07:00
parent 9e12031a6b
commit f1786ec20a
8 changed files with 75 additions and 47 deletions

View file

@ -9,6 +9,7 @@ pub fn derive_render_resource(input: TokenStream) -> TokenStream {
let bevy_render_path: Path = get_path(&modules.bevy_render); let bevy_render_path: Path = get_path(&modules.bevy_render);
let bevy_asset_path: Path = get_path(&modules.bevy_asset); let bevy_asset_path: Path = get_path(&modules.bevy_asset);
let bevy_core_path: Path = get_path(&modules.bevy_core);
let struct_name = &ast.ident; let struct_name = &ast.ident;
TokenStream::from(quote! { TokenStream::from(quote! {
@ -17,9 +18,11 @@ pub fn derive_render_resource(input: TokenStream) -> TokenStream {
Some(#bevy_render_path::render_resource::RenderResourceType::Buffer) Some(#bevy_render_path::render_resource::RenderResourceType::Buffer)
} }
fn write_buffer_bytes(&self, buffer: &mut [u8]) { fn write_buffer_bytes(&self, buffer: &mut [u8]) {
use #bevy_core_path::bytes::Bytes;
self.write_bytes(buffer); self.write_bytes(buffer);
} }
fn buffer_byte_len(&self) -> Option<usize> { fn buffer_byte_len(&self) -> Option<usize> {
use #bevy_core_path::bytes::Bytes;
Some(self.byte_len()) Some(self.byte_len())
} }
fn texture(&self) -> Option<#bevy_asset_path::Handle<#bevy_render_path::texture::Texture>> { fn texture(&self) -> Option<#bevy_asset_path::Handle<#bevy_render_path::texture::Texture>> {

View file

@ -1,30 +1,58 @@
use crate::{ use crate::{
render::SPRITE_PIPELINE_HANDLE, sprite::Sprite, ColorMaterial, Quad, TextureAtlas, render::SPRITE_PIPELINE_HANDLE, sprite::Sprite, ColorMaterial, TextureAtlas,
TextureAtlasSprite, QUAD_HANDLE, SPRITE_SHEET_PIPELINE_HANDLE, TextureAtlasSprite, QUAD_HANDLE, SPRITE_SHEET_PIPELINE_HANDLE,
}; };
use bevy_app::EntityArchetype; use bevy_app::EntityArchetype;
use bevy_asset::Handle; use bevy_asset::Handle;
use bevy_render::{draw::Draw, mesh::Mesh, pipeline::{PipelineSpecialization, RenderPipelines, RenderPipeline, DynamicBinding}}; use bevy_render::{
draw::Draw,
mesh::Mesh,
pipeline::{DynamicBinding, PipelineSpecialization, RenderPipeline, RenderPipelines},
};
use bevy_transform::prelude::{Rotation, Scale, Transform, Translation};
#[derive(EntityArchetype)] #[derive(EntityArchetype)]
pub struct SpriteEntity { pub struct SpriteEntity {
pub sprite: Sprite, pub sprite: Sprite,
pub quad: Quad,
pub mesh: Handle<Mesh>, // TODO: maybe abstract this out pub mesh: Handle<Mesh>, // TODO: maybe abstract this out
pub material: Handle<ColorMaterial>, pub material: Handle<ColorMaterial>,
pub draw: Draw, pub draw: Draw,
pub render_pipelines: RenderPipelines, pub render_pipelines: RenderPipelines,
pub transform: Transform,
pub translation: Translation,
pub rotation: Rotation,
pub scale: Scale,
} }
impl Default for SpriteEntity { impl Default for SpriteEntity {
fn default() -> Self { fn default() -> Self {
Self { Self {
mesh: QUAD_HANDLE, mesh: QUAD_HANDLE,
render_pipelines: RenderPipelines::from_handles(&[SPRITE_PIPELINE_HANDLE]), render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::specialized(
SPRITE_PIPELINE_HANDLE,
PipelineSpecialization {
dynamic_bindings: vec![
// Transform
DynamicBinding {
bind_group: 2,
binding: 0,
},
// Sprite
DynamicBinding {
bind_group: 2,
binding: 1,
},
],
..Default::default()
},
)]),
sprite: Default::default(), sprite: Default::default(),
quad: Default::default(),
material: Default::default(), material: Default::default(),
draw: Default::default(), draw: Default::default(),
transform: Default::default(),
translation: Default::default(),
rotation: Default::default(),
scale: Default::default(),
} }
} }
} }

View file

@ -1,4 +1,4 @@
use crate::{ColorMaterial, Quad, TextureAtlas, TextureAtlasSprite}; use crate::{ColorMaterial, Quad, TextureAtlas, TextureAtlasSprite, Sprite};
use bevy_asset::{Assets, Handle}; use bevy_asset::{Assets, Handle};
use bevy_render::{ use bevy_render::{
base_render_graph, base_render_graph,
@ -111,6 +111,7 @@ pub fn build_sprite_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor
pub mod node { pub mod node {
pub const COLOR_MATERIAL: &'static str = "color_material"; pub const COLOR_MATERIAL: &'static str = "color_material";
pub const QUAD: &'static str = "quad"; pub const QUAD: &'static str = "quad";
pub const SPRITE: &'static str = "sprite";
pub const SPRITE_SHEET: &'static str = "sprite_sheet"; pub const SPRITE_SHEET: &'static str = "sprite_sheet";
pub const SPRITE_SHEET_SPRITE: &'static str = "sprite_sheet_sprite"; pub const SPRITE_SHEET_SPRITE: &'static str = "sprite_sheet_sprite";
} }
@ -131,6 +132,9 @@ impl SpriteRenderGraphBuilder for RenderGraph {
self.add_system_node(node::QUAD, RenderResourcesNode::<Quad>::new(false)); self.add_system_node(node::QUAD, RenderResourcesNode::<Quad>::new(false));
self.add_node_edge(node::QUAD, base_render_graph::node::MAIN_PASS) self.add_node_edge(node::QUAD, base_render_graph::node::MAIN_PASS)
.unwrap(); .unwrap();
self.add_system_node(node::SPRITE, RenderResourcesNode::<Sprite>::new(true));
self.add_node_edge(node::SPRITE, base_render_graph::node::MAIN_PASS)
.unwrap();
self.add_system_node( self.add_system_node(
node::SPRITE_SHEET, node::SPRITE_SHEET,

View file

@ -4,13 +4,13 @@ layout(location = 0) in vec2 v_Uv;
layout(location = 0) out vec4 o_Target; layout(location = 0) out vec4 o_Target;
layout(set = 2, binding = 0) uniform ColorMaterial_color { layout(set = 1, binding = 0) uniform ColorMaterial_color {
vec4 Color; vec4 Color;
}; };
# ifdef COLORMATERIAL_TEXTURE # ifdef COLORMATERIAL_TEXTURE
layout(set = 3, binding = 0) uniform texture2D ColorMaterial_texture; layout(set = 1, binding = 1) uniform texture2D ColorMaterial_texture;
layout(set = 3, binding = 1) uniform sampler ColorMaterial_texture_sampler; layout(set = 1, binding = 2) uniform sampler ColorMaterial_texture_sampler;
# endif # endif
void main() { void main() {

View file

@ -10,15 +10,15 @@ layout(set = 0, binding = 0) uniform Camera2d {
mat4 ViewProj; mat4 ViewProj;
}; };
layout(set = 1, binding = 0) uniform Quad { layout(set = 2, binding = 0) uniform Transform {
vec2 Quad_Position; mat4 Model;
vec2 Quad_Size; };
float Quad_ZIndex; layout(set = 2, binding = 1) uniform Sprite {
vec2 Sprite_size;
}; };
void main() { void main() {
v_Uv = Vertex_Uv; v_Uv = Vertex_Uv;
vec3 position = Vertex_Position * vec3(Quad_Size, 0.0); vec3 position = Vertex_Position * vec3(Sprite_size, 1.0);
position = position + vec3(Quad_Position, Quad_ZIndex); gl_Position = ViewProj * Model * vec4(position, 1.0);
gl_Position = ViewProj * vec4(position, 1.0);
} }

View file

@ -1,34 +1,35 @@
use crate::{ColorMaterial, Quad}; use crate::ColorMaterial;
use bevy_asset::{Assets, Handle}; use bevy_asset::{Assets, Handle};
use bevy_render::texture::Texture; use bevy_core::bytes::Byteable;
use bevy_render::{
render_resource::{RenderResource, RenderResources},
texture::Texture,
};
pub use legion::prelude::*; pub use legion::prelude::*;
use glam::Vec2;
#[repr(C)]
#[derive(Default, RenderResources, RenderResource)]
#[render_resources(from_self)]
pub struct Sprite { pub struct Sprite {
pub scale: f32, size: Vec2,
} }
impl Default for Sprite { // SAFE: sprite is repr(C) and only consists of byteables
fn default() -> Self { unsafe impl Byteable for Sprite {}
Sprite { scale: 1.0 }
}
}
// TODO: port to system fn
pub fn sprite_system() -> Box<dyn Schedulable> { pub fn sprite_system() -> Box<dyn Schedulable> {
SystemBuilder::new("sprite_system") SystemBuilder::new("sprite_system")
.read_resource::<Assets<ColorMaterial>>() .read_resource::<Assets<ColorMaterial>>()
.read_resource::<Assets<Texture>>() .read_resource::<Assets<Texture>>()
.with_query( .with_query(<(Write<Sprite>, Read<Handle<ColorMaterial>>)>::query())
<(Read<Sprite>, Read<Handle<ColorMaterial>>, Write<Quad>)>::query().filter(
changed::<Sprite>() | changed::<Quad>() | changed::<Handle<ColorMaterial>>(),
),
)
.build(|_, world, (materials, textures), query| { .build(|_, world, (materials, textures), query| {
for (sprite, handle, mut rect) in query.iter_mut(world) { for (mut sprite, handle) in query.iter_mut(world) {
let material = materials.get(&handle).unwrap(); let material = materials.get(&handle).unwrap();
if let Some(texture_handle) = material.texture { if let Some(texture_handle) = material.texture {
if let Some(texture) = textures.get(&texture_handle) { if let Some(texture) = textures.get(&texture_handle) {
let aspect = texture.aspect(); sprite.size = texture.size;
*rect.size.x_mut() = texture.size.x() * sprite.scale;
*rect.size.y_mut() = rect.size.x() * aspect;
} }
} }
} }

View file

@ -81,11 +81,7 @@ fn load_atlas(
// draw the atlas itself // draw the atlas itself
.add_entity(SpriteEntity { .add_entity(SpriteEntity {
material: materials.add(texture_atlas_texture.into()), material: materials.add(texture_atlas_texture.into()),
quad: Quad { translation: Vec3::new(-300.0, 0., 0.0).into(),
position: Vec2::new(-300.0, 0.),
..Default::default()
},
sprite: Sprite { scale: 1.0 },
..Default::default() ..Default::default()
}); });

View file

@ -42,11 +42,7 @@ fn atlas_render_system(
let texture_atlas = texture_atlases.get(&font_atlas.texture_atlas).unwrap(); let texture_atlas = texture_atlases.get(&font_atlas.texture_atlas).unwrap();
command_buffer.build().add_entity(SpriteEntity { command_buffer.build().add_entity(SpriteEntity {
material: materials.add(texture_atlas.texture.into()), material: materials.add(texture_atlas.texture.into()),
quad: Quad { translation: Vec3::new(-300.0, 0., 0.0).into(),
position: Vec2::new(-300.0, 0.),
..Default::default()
},
sprite: Sprite { scale: 1.0 },
..Default::default() ..Default::default()
}); });
break; break;