From e921ae019922030d4edf4a5ec141b1442c125e8c Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Mon, 22 Jun 2020 12:35:33 -0700 Subject: [PATCH] sprite: use bevy_transform types in sprite sheet entities --- crates/bevy_sprite/src/entity.rs | 23 +++++---- .../bevy_sprite/src/render/sprite_sheet.vert | 12 +++-- crates/bevy_sprite/src/texture_atlas.rs | 50 ++++--------------- crates/bevy_text/src/draw.rs | 23 ++++++--- .../src/components/transform.rs | 1 + examples/2d/sprite_sheet.rs | 5 +- examples/2d/texture_atlas.rs | 9 ++-- 7 files changed, 52 insertions(+), 71 deletions(-) diff --git a/crates/bevy_sprite/src/entity.rs b/crates/bevy_sprite/src/entity.rs index 58d73d5f59..0d505d24de 100644 --- a/crates/bevy_sprite/src/entity.rs +++ b/crates/bevy_sprite/src/entity.rs @@ -64,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 { @@ -77,11 +77,16 @@ impl Default for SpriteSheetEntity { SPRITE_SHEET_PIPELINE_HANDLE, PipelineSpecialization { dynamic_bindings: vec![ - // TextureAtlasSprite + // Transform DynamicBinding { bind_group: 2, binding: 0, }, + // TextureAtlasSprite + DynamicBinding { + bind_group: 2, + binding: 1, + }, ], ..Default::default() }, @@ -90,10 +95,10 @@ impl Default for SpriteSheetEntity { sprite: Default::default(), texture_atlas: Default::default(), draw: Default::default(), - // transform: Default::default(), - // translation: Default::default(), - // rotation: Default::default(), - // scale: Default::default(), + transform: Default::default(), + translation: Default::default(), + rotation: Default::default(), + scale: Default::default(), } } } diff --git a/crates/bevy_sprite/src/render/sprite_sheet.vert b/crates/bevy_sprite/src/render/sprite_sheet.vert index f3ec814894..909367c433 100644 --- a/crates/bevy_sprite/src/render/sprite_sheet.vert +++ b/crates/bevy_sprite/src/render/sprite_sheet.vert @@ -33,17 +33,19 @@ layout(set = 1, binding = 1) buffer TextureAtlas_textures { }; -layout(set = 2, binding = 0) uniform TextureAtlasSprite { - vec3 TextureAtlasSprite_position; +layout(set = 2, binding = 0) uniform Transform { + mat4 SpriteTransform; +}; + +layout(set = 2, binding = 1) uniform TextureAtlasSprite { vec4 TextureAtlasSprite_color; - float TextureAtlasSprite_scale; uint TextureAtlasSprite_index; }; void main() { Rect sprite_rect = Textures[TextureAtlasSprite_index]; vec2 sprite_dimensions = sprite_rect.end - sprite_rect.begin; - vec3 vertex_position = vec3(Vertex_Position.xy * sprite_dimensions * TextureAtlasSprite_scale, 0.0) + TextureAtlasSprite_position.xyz; + vec3 vertex_position = vec3(Vertex_Position.xy * sprite_dimensions, 0.0); vec2 uvs[4] = vec2[]( vec2(sprite_rect.begin.x, sprite_rect.end.y), sprite_rect.begin, @@ -52,5 +54,5 @@ void main() { ); v_Uv = uvs[gl_VertexIndex] / AtlasSize; v_Color = TextureAtlasSprite_color; - gl_Position = ViewProj * vec4(vertex_position, 1.0); + gl_Position = ViewProj * SpriteTransform * vec4(vertex_position, 1.0); } \ No newline at end of file diff --git a/crates/bevy_sprite/src/texture_atlas.rs b/crates/bevy_sprite/src/texture_atlas.rs index eda63357b7..80247db37a 100644 --- a/crates/bevy_sprite/src/texture_atlas.rs +++ b/crates/bevy_sprite/src/texture_atlas.rs @@ -6,7 +6,7 @@ use bevy_render::{ texture::Texture, Color, }; -use glam::{Vec2, Vec3}; +use glam::Vec2; use std::collections::HashMap; #[derive(RenderResources)] @@ -25,9 +25,7 @@ pub struct TextureAtlas { #[derive(Bytes, RenderResources, RenderResource)] #[render_resources(from_self)] pub struct TextureAtlasSprite { - pub position: Vec3, pub color: Color, - pub scale: f32, pub index: u32, } @@ -36,8 +34,15 @@ impl Default for TextureAtlasSprite { Self { index: 0, color: Color::WHITE, - scale: 1.0, - position: Default::default(), + } + } +} + +impl TextureAtlasSprite { + pub fn new(index: u32) -> TextureAtlasSprite { + Self { + index, + ..Default::default() } } } @@ -93,37 +98,4 @@ impl TextureAtlas { .as_ref() .and_then(|texture_handles| texture_handles.get(&texture).cloned()) } -} - -#[cfg(test)] -mod tests { - use crate::TextureAtlasSprite; - use bevy_core::bytes::{Bytes, FromBytes}; - use bevy_render::Color; - use glam::Vec3; - - #[test] - fn test_atlas_byte_conversion() { - let x = TextureAtlasSprite { - color: Color::RED, - index: 2, - position: Vec3::new(1., 2., 3.), - scale: 4.0, - }; - - assert_eq!(x.byte_len(), 40); - let mut bytes = vec![0; x.byte_len()]; - - x.write_bytes(&mut bytes); - - let position = Vec3::from_bytes(&bytes[0..16]); - let color = Color::from_bytes(&bytes[16..32]); - let scale = f32::from_bytes(&bytes[32..36]); - let index = u32::from_bytes(&bytes[36..40]); - - assert_eq!(position, x.position); - assert_eq!(color, x.color); - assert_eq!(scale, x.scale); - assert_eq!(index, x.index); - } -} +} \ No newline at end of file diff --git a/crates/bevy_text/src/draw.rs b/crates/bevy_text/src/draw.rs index 5ad6dc589d..06015a816e 100644 --- a/crates/bevy_text/src/draw.rs +++ b/crates/bevy_text/src/draw.rs @@ -12,7 +12,7 @@ use bevy_render::{ Color, }; use bevy_sprite::{TextureAtlas, TextureAtlasSprite}; -use glam::Vec3; +use glam::{Mat4, Vec3}; use std::collections::HashSet; pub struct TextStyle { @@ -130,24 +130,31 @@ impl<'a> Drawable for DrawableText<'a> { let bounds = outlined.px_bounds(); let offset = scaled_font.descent() + glyph_height; - let sprite_buffer = TextureAtlasSprite { - index: glyph_atlas_info.char_index, - color: self.style.color, - position: caret + let transform = Mat4::from_translation( + caret + Vec3::new( 0.0 + glyph_width / 2.0 + bounds.min.x, glyph_height / 2.0 - bounds.min.y - offset, 0.0, ), - scale: 1.0, + ); + let sprite = TextureAtlasSprite { + index: glyph_atlas_info.char_index, + color: self.style.color, }; + let transform_buffer = context + .shared_buffers + .get_buffer(&transform, BufferUsage::UNIFORM) + .unwrap(); let sprite_buffer = context .shared_buffers - .get_buffer(&sprite_buffer, BufferUsage::UNIFORM) + .get_buffer(&sprite, BufferUsage::UNIFORM) .unwrap(); let sprite_bind_group = - BindGroup::build().add_binding(0, sprite_buffer).finish(); + BindGroup::build() + .add_binding(0, transform_buffer) + .add_binding(1, sprite_buffer).finish(); context.create_bind_group_resource(2, &sprite_bind_group)?; draw.set_bind_group(2, &sprite_bind_group); draw.draw_indexed(indices.clone(), 0, 0..1); diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index d17a94e407..53894161ba 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -5,6 +5,7 @@ use std::fmt; #[derive(Debug, PartialEq, Clone, Copy, Properties)] pub struct Transform { pub value: Mat4, + #[property(ignore)] pub sync: bool, // NOTE: this is hopefully a temporary measure to allow setting the transform directly. // ideally setting the transform automatically propagates back to position / translation / rotation, // but right now they are always considered the source of truth diff --git a/examples/2d/sprite_sheet.rs b/examples/2d/sprite_sheet.rs index 884ad9506c..9d42103f89 100644 --- a/examples/2d/sprite_sheet.rs +++ b/examples/2d/sprite_sheet.rs @@ -41,10 +41,7 @@ fn setup( .add_entity(OrthographicCameraEntity::default()) .add_entity(SpriteSheetEntity { texture_atlas: texture_atlas_handle, - sprite: TextureAtlasSprite { - scale: 6.0, - ..Default::default() - }, + scale: Scale(6.0), ..Default::default() }) .add(Timer::from_seconds(0.1)); diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index c21f853168..5163dfd0ff 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -69,12 +69,9 @@ fn load_atlas( .build() // draw a sprite from the atlas .add_entity(SpriteSheetEntity { - sprite: TextureAtlasSprite { - index: vendor_index as u32, - scale: 4.0, - position: Vec3::new(150.0, 0.0, 0.0), - ..Default::default() - }, + scale: Scale(4.0), + translation: Translation(Vec3::new(150.0, 0.0, 0.0)), + sprite: TextureAtlasSprite::new(vendor_index as u32), texture_atlas: atlas_handle, ..Default::default() })