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 render_pipelines: RenderPipelines,
pub mesh: Handle<Mesh>, // 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(),
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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