sprite: use bevy_transform types in sprite sheet entities

This commit is contained in:
Carter Anderson 2020-06-22 12:35:33 -07:00
parent f1786ec20a
commit e921ae0199
7 changed files with 52 additions and 71 deletions

View File

@ -64,10 +64,10 @@ pub struct SpriteSheetEntity {
pub draw: Draw, pub draw: Draw,
pub render_pipelines: RenderPipelines, pub render_pipelines: RenderPipelines,
pub mesh: Handle<Mesh>, // TODO: maybe abstract this out pub mesh: Handle<Mesh>, // TODO: maybe abstract this out
// pub transform: Transform, pub transform: Transform,
// pub translation: Translation, pub translation: Translation,
// pub rotation: Rotation, pub rotation: Rotation,
// pub scale: Scale, pub scale: Scale,
} }
impl Default for SpriteSheetEntity { impl Default for SpriteSheetEntity {
@ -77,11 +77,16 @@ impl Default for SpriteSheetEntity {
SPRITE_SHEET_PIPELINE_HANDLE, SPRITE_SHEET_PIPELINE_HANDLE,
PipelineSpecialization { PipelineSpecialization {
dynamic_bindings: vec![ dynamic_bindings: vec![
// TextureAtlasSprite // Transform
DynamicBinding { DynamicBinding {
bind_group: 2, bind_group: 2,
binding: 0, binding: 0,
}, },
// TextureAtlasSprite
DynamicBinding {
bind_group: 2,
binding: 1,
},
], ],
..Default::default() ..Default::default()
}, },
@ -90,10 +95,10 @@ impl Default for SpriteSheetEntity {
sprite: Default::default(), sprite: Default::default(),
texture_atlas: Default::default(), texture_atlas: Default::default(),
draw: Default::default(), draw: Default::default(),
// transform: Default::default(), transform: Default::default(),
// translation: Default::default(), translation: Default::default(),
// rotation: Default::default(), rotation: Default::default(),
// scale: Default::default(), scale: Default::default(),
} }
} }
} }

View File

@ -33,17 +33,19 @@ layout(set = 1, binding = 1) buffer TextureAtlas_textures {
}; };
layout(set = 2, binding = 0) uniform TextureAtlasSprite { layout(set = 2, binding = 0) uniform Transform {
vec3 TextureAtlasSprite_position; mat4 SpriteTransform;
};
layout(set = 2, binding = 1) uniform TextureAtlasSprite {
vec4 TextureAtlasSprite_color; vec4 TextureAtlasSprite_color;
float TextureAtlasSprite_scale;
uint TextureAtlasSprite_index; uint TextureAtlasSprite_index;
}; };
void main() { void main() {
Rect sprite_rect = Textures[TextureAtlasSprite_index]; Rect sprite_rect = Textures[TextureAtlasSprite_index];
vec2 sprite_dimensions = sprite_rect.end - sprite_rect.begin; 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 uvs[4] = vec2[](
vec2(sprite_rect.begin.x, sprite_rect.end.y), vec2(sprite_rect.begin.x, sprite_rect.end.y),
sprite_rect.begin, sprite_rect.begin,
@ -52,5 +54,5 @@ void main() {
); );
v_Uv = uvs[gl_VertexIndex] / AtlasSize; v_Uv = uvs[gl_VertexIndex] / AtlasSize;
v_Color = TextureAtlasSprite_color; v_Color = TextureAtlasSprite_color;
gl_Position = ViewProj * vec4(vertex_position, 1.0); gl_Position = ViewProj * SpriteTransform * vec4(vertex_position, 1.0);
} }

View File

@ -6,7 +6,7 @@ use bevy_render::{
texture::Texture, texture::Texture,
Color, Color,
}; };
use glam::{Vec2, Vec3}; use glam::Vec2;
use std::collections::HashMap; use std::collections::HashMap;
#[derive(RenderResources)] #[derive(RenderResources)]
@ -25,9 +25,7 @@ pub struct TextureAtlas {
#[derive(Bytes, RenderResources, RenderResource)] #[derive(Bytes, RenderResources, RenderResource)]
#[render_resources(from_self)] #[render_resources(from_self)]
pub struct TextureAtlasSprite { pub struct TextureAtlasSprite {
pub position: Vec3,
pub color: Color, pub color: Color,
pub scale: f32,
pub index: u32, pub index: u32,
} }
@ -36,8 +34,15 @@ impl Default for TextureAtlasSprite {
Self { Self {
index: 0, index: 0,
color: Color::WHITE, 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() .as_ref()
.and_then(|texture_handles| texture_handles.get(&texture).cloned()) .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);
}
}

View File

@ -12,7 +12,7 @@ use bevy_render::{
Color, Color,
}; };
use bevy_sprite::{TextureAtlas, TextureAtlasSprite}; use bevy_sprite::{TextureAtlas, TextureAtlasSprite};
use glam::Vec3; use glam::{Mat4, Vec3};
use std::collections::HashSet; use std::collections::HashSet;
pub struct TextStyle { pub struct TextStyle {
@ -130,24 +130,31 @@ impl<'a> Drawable for DrawableText<'a> {
let bounds = outlined.px_bounds(); let bounds = outlined.px_bounds();
let offset = scaled_font.descent() + glyph_height; let offset = scaled_font.descent() + glyph_height;
let sprite_buffer = TextureAtlasSprite { let transform = Mat4::from_translation(
index: glyph_atlas_info.char_index, caret
color: self.style.color,
position: caret
+ Vec3::new( + Vec3::new(
0.0 + glyph_width / 2.0 + bounds.min.x, 0.0 + glyph_width / 2.0 + bounds.min.x,
glyph_height / 2.0 - bounds.min.y - offset, glyph_height / 2.0 - bounds.min.y - offset,
0.0, 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 let sprite_buffer = context
.shared_buffers .shared_buffers
.get_buffer(&sprite_buffer, BufferUsage::UNIFORM) .get_buffer(&sprite, BufferUsage::UNIFORM)
.unwrap(); .unwrap();
let sprite_bind_group = 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)?; context.create_bind_group_resource(2, &sprite_bind_group)?;
draw.set_bind_group(2, &sprite_bind_group); draw.set_bind_group(2, &sprite_bind_group);
draw.draw_indexed(indices.clone(), 0, 0..1); draw.draw_indexed(indices.clone(), 0, 0..1);

View File

@ -5,6 +5,7 @@ use std::fmt;
#[derive(Debug, PartialEq, Clone, Copy, Properties)] #[derive(Debug, PartialEq, Clone, Copy, Properties)]
pub struct Transform { pub struct Transform {
pub value: Mat4, pub value: Mat4,
#[property(ignore)]
pub sync: bool, // NOTE: this is hopefully a temporary measure to allow setting the transform directly. 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, // ideally setting the transform automatically propagates back to position / translation / rotation,
// but right now they are always considered the source of truth // but right now they are always considered the source of truth

View File

@ -41,10 +41,7 @@ fn setup(
.add_entity(OrthographicCameraEntity::default()) .add_entity(OrthographicCameraEntity::default())
.add_entity(SpriteSheetEntity { .add_entity(SpriteSheetEntity {
texture_atlas: texture_atlas_handle, texture_atlas: texture_atlas_handle,
sprite: TextureAtlasSprite { scale: Scale(6.0),
scale: 6.0,
..Default::default()
},
..Default::default() ..Default::default()
}) })
.add(Timer::from_seconds(0.1)); .add(Timer::from_seconds(0.1));

View File

@ -69,12 +69,9 @@ fn load_atlas(
.build() .build()
// draw a sprite from the atlas // draw a sprite from the atlas
.add_entity(SpriteSheetEntity { .add_entity(SpriteSheetEntity {
sprite: TextureAtlasSprite { scale: Scale(4.0),
index: vendor_index as u32, translation: Translation(Vec3::new(150.0, 0.0, 0.0)),
scale: 4.0, sprite: TextureAtlasSprite::new(vendor_index as u32),
position: Vec3::new(150.0, 0.0, 0.0),
..Default::default()
},
texture_atlas: atlas_handle, texture_atlas: atlas_handle,
..Default::default() ..Default::default()
}) })