diff --git a/crates/bevy_derive/src/render_resource.rs b/crates/bevy_derive/src/render_resource.rs index 6141c6a223..63c06f9cad 100644 --- a/crates/bevy_derive/src/render_resource.rs +++ b/crates/bevy_derive/src/render_resource.rs @@ -9,6 +9,7 @@ pub fn derive_render_resource(input: TokenStream) -> TokenStream { let bevy_render_path: Path = get_path(&modules.bevy_render); 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; TokenStream::from(quote! { @@ -17,9 +18,11 @@ pub fn derive_render_resource(input: TokenStream) -> TokenStream { Some(#bevy_render_path::render_resource::RenderResourceType::Buffer) } fn write_buffer_bytes(&self, buffer: &mut [u8]) { + use #bevy_core_path::bytes::Bytes; self.write_bytes(buffer); } fn buffer_byte_len(&self) -> Option { + use #bevy_core_path::bytes::Bytes; Some(self.byte_len()) } fn texture(&self) -> Option<#bevy_asset_path::Handle<#bevy_render_path::texture::Texture>> { diff --git a/crates/bevy_sprite/src/entity.rs b/crates/bevy_sprite/src/entity.rs index 457b0550e6..58d73d5f59 100644 --- a/crates/bevy_sprite/src/entity.rs +++ b/crates/bevy_sprite/src/entity.rs @@ -1,30 +1,58 @@ 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, }; use bevy_app::EntityArchetype; 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)] pub struct SpriteEntity { pub sprite: Sprite, - pub quad: Quad, pub mesh: Handle, // TODO: maybe abstract this out pub material: Handle, pub draw: Draw, pub render_pipelines: RenderPipelines, + pub transform: Transform, + pub translation: Translation, + pub rotation: Rotation, + pub scale: Scale, } impl Default for SpriteEntity { fn default() -> Self { Self { 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(), - quad: Default::default(), material: Default::default(), draw: Default::default(), + transform: Default::default(), + translation: Default::default(), + rotation: Default::default(), + scale: Default::default(), } } } @@ -36,10 +64,10 @@ pub struct SpriteSheetEntity { pub draw: Draw, pub render_pipelines: RenderPipelines, pub mesh: Handle, // TODO: maybe abstract this out - // pub transform: Transform, - // pub translation: Translation, - // pub rotation: Rotation, - // pub scale: Scale, + // pub transform: Transform, + // pub translation: Translation, + // pub rotation: Rotation, + // pub scale: Scale, } impl Default for SpriteSheetEntity { diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index b88240c1c7..e5c21c7a6f 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -1,4 +1,4 @@ -use crate::{ColorMaterial, Quad, TextureAtlas, TextureAtlasSprite}; +use crate::{ColorMaterial, Quad, TextureAtlas, TextureAtlasSprite, Sprite}; use bevy_asset::{Assets, Handle}; use bevy_render::{ base_render_graph, @@ -111,6 +111,7 @@ pub fn build_sprite_pipeline(shaders: &mut Assets) -> PipelineDescriptor pub mod node { pub const COLOR_MATERIAL: &'static str = "color_material"; pub const QUAD: &'static str = "quad"; + pub const SPRITE: &'static str = "sprite"; pub const SPRITE_SHEET: &'static str = "sprite_sheet"; 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::::new(false)); self.add_node_edge(node::QUAD, base_render_graph::node::MAIN_PASS) .unwrap(); + self.add_system_node(node::SPRITE, RenderResourcesNode::::new(true)); + self.add_node_edge(node::SPRITE, base_render_graph::node::MAIN_PASS) + .unwrap(); self.add_system_node( node::SPRITE_SHEET, diff --git a/crates/bevy_sprite/src/render/sprite.frag b/crates/bevy_sprite/src/render/sprite.frag index 1146ac2825..9683598e2e 100644 --- a/crates/bevy_sprite/src/render/sprite.frag +++ b/crates/bevy_sprite/src/render/sprite.frag @@ -4,13 +4,13 @@ layout(location = 0) in vec2 v_Uv; 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; }; # ifdef COLORMATERIAL_TEXTURE -layout(set = 3, binding = 0) uniform texture2D ColorMaterial_texture; -layout(set = 3, binding = 1) uniform sampler ColorMaterial_texture_sampler; +layout(set = 1, binding = 1) uniform texture2D ColorMaterial_texture; +layout(set = 1, binding = 2) uniform sampler ColorMaterial_texture_sampler; # endif void main() { diff --git a/crates/bevy_sprite/src/render/sprite.vert b/crates/bevy_sprite/src/render/sprite.vert index 767fefd810..3cab495b10 100644 --- a/crates/bevy_sprite/src/render/sprite.vert +++ b/crates/bevy_sprite/src/render/sprite.vert @@ -10,15 +10,15 @@ layout(set = 0, binding = 0) uniform Camera2d { mat4 ViewProj; }; -layout(set = 1, binding = 0) uniform Quad { - vec2 Quad_Position; - vec2 Quad_Size; - float Quad_ZIndex; +layout(set = 2, binding = 0) uniform Transform { + mat4 Model; +}; +layout(set = 2, binding = 1) uniform Sprite { + vec2 Sprite_size; }; void main() { v_Uv = Vertex_Uv; - vec3 position = Vertex_Position * vec3(Quad_Size, 0.0); - position = position + vec3(Quad_Position, Quad_ZIndex); - gl_Position = ViewProj * vec4(position, 1.0); + vec3 position = Vertex_Position * vec3(Sprite_size, 1.0); + gl_Position = ViewProj * Model * vec4(position, 1.0); } \ No newline at end of file diff --git a/crates/bevy_sprite/src/sprite.rs b/crates/bevy_sprite/src/sprite.rs index 2b4d642828..2021244a32 100644 --- a/crates/bevy_sprite/src/sprite.rs +++ b/crates/bevy_sprite/src/sprite.rs @@ -1,34 +1,35 @@ -use crate::{ColorMaterial, Quad}; +use crate::ColorMaterial; 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::*; +use glam::Vec2; + +#[repr(C)] +#[derive(Default, RenderResources, RenderResource)] +#[render_resources(from_self)] pub struct Sprite { - pub scale: f32, + size: Vec2, } -impl Default for Sprite { - fn default() -> Self { - Sprite { scale: 1.0 } - } -} +// SAFE: sprite is repr(C) and only consists of byteables +unsafe impl Byteable for Sprite {} +// TODO: port to system fn pub fn sprite_system() -> Box { SystemBuilder::new("sprite_system") .read_resource::>() .read_resource::>() - .with_query( - <(Read, Read>, Write)>::query().filter( - changed::() | changed::() | changed::>(), - ), - ) + .with_query(<(Write, Read>)>::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(); if let Some(texture_handle) = material.texture { if let Some(texture) = textures.get(&texture_handle) { - let aspect = texture.aspect(); - *rect.size.x_mut() = texture.size.x() * sprite.scale; - *rect.size.y_mut() = rect.size.x() * aspect; + sprite.size = texture.size; } } } diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index c59dc22bd2..c21f853168 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -81,11 +81,7 @@ fn load_atlas( // draw the atlas itself .add_entity(SpriteEntity { material: materials.add(texture_atlas_texture.into()), - quad: Quad { - position: Vec2::new(-300.0, 0.), - ..Default::default() - }, - sprite: Sprite { scale: 1.0 }, + translation: Vec3::new(-300.0, 0., 0.0).into(), ..Default::default() }); diff --git a/examples/ui/font_atlas_debug.rs b/examples/ui/font_atlas_debug.rs index 363c9ebb3e..5cc2c2159b 100644 --- a/examples/ui/font_atlas_debug.rs +++ b/examples/ui/font_atlas_debug.rs @@ -42,11 +42,7 @@ fn atlas_render_system( let texture_atlas = texture_atlases.get(&font_atlas.texture_atlas).unwrap(); command_buffer.build().add_entity(SpriteEntity { material: materials.add(texture_atlas.texture.into()), - quad: Quad { - position: Vec2::new(-300.0, 0.), - ..Default::default() - }, - sprite: Sprite { scale: 1.0 }, + translation: Vec3::new(-300.0, 0., 0.0).into(), ..Default::default() }); break;