Skip to content
Snippets Groups Projects
Commit 33b239af authored by Matthew's avatar Matthew
Browse files

Added texture atlas support

parent 0572f601
No related branches found
No related tags found
No related merge requests found
assets/texture_atlas.png

10.1 KiB

...@@ -16,6 +16,7 @@ use kayak_font::KayakFont; ...@@ -16,6 +16,7 @@ use kayak_font::KayakFont;
pub mod font; pub mod font;
pub mod image; pub mod image;
mod nine_patch; mod nine_patch;
mod texture_atlas;
mod quad; mod quad;
pub struct BevyKayakUIExtractPlugin; pub struct BevyKayakUIExtractPlugin;
...@@ -79,6 +80,11 @@ pub fn extract( ...@@ -79,6 +80,11 @@ pub fn extract(
nine_patch::extract_nine_patch(&render_primitive, &image_manager, &images, dpi); nine_patch::extract_nine_patch(&render_primitive, &image_manager, &images, dpi);
extracted_quads.extend(nine_patch_quads); extracted_quads.extend(nine_patch_quads);
} }
RenderPrimitive::TextureAtlas { .. } => {
let texture_atlas_quads =
texture_atlas::extract_texture_atlas(&render_primitive, &image_manager, &images, dpi);
extracted_quads.extend(texture_atlas_quads);
}
RenderPrimitive::Clip { layout } => { RenderPrimitive::Clip { layout } => {
extracted_quads.push(ExtractQuadBundle { extracted_quads.push(ExtractQuadBundle {
extracted_quad: ExtractedQuad { extracted_quad: ExtractedQuad {
......
use crate::ImageManager;
use bevy::{
math::Vec2,
prelude::{Assets, Res},
render::{color::Color, texture::Image},
sprite::Rect,
};
use bevy_kayak_renderer::{
render::unified::pipeline::{ExtractQuadBundle, ExtractedQuad, UIQuadType},
Corner,
};
use kayak_core::render_primitive::RenderPrimitive;
pub fn extract_texture_atlas(
render_primitive: &RenderPrimitive,
image_manager: &Res<ImageManager>,
images: &Res<Assets<Image>>,
dpi: f32,
) -> Vec<ExtractQuadBundle> {
let mut extracted_quads = Vec::new();
let (size, position, layout, handle) = match render_primitive {
RenderPrimitive::TextureAtlas {
size,
position,
layout,
handle,
} => (size, position, layout, handle),
_ => panic!(""),
};
let image_handle = image_manager
.get_handle(handle)
.and_then(|a| Some(a.clone_weak()));
let image = images.get(image_handle.as_ref().unwrap());
if image.is_none() {
return vec![];
}
let image_size = image
.and_then(|i| {
Some(Vec2::new(
i.texture_descriptor.size.width as f32,
i.texture_descriptor.size.height as f32,
))
})
.unwrap()
* dpi;
let quad = ExtractQuadBundle {
extracted_quad: ExtractedQuad {
rect: Rect {
min: Vec2::new(layout.posx, layout.posy),
max: Vec2::new(layout.posx + layout.width, layout.posy + layout.height),
},
uv_min: Some(Vec2::new(
position.0 / image_size.x,
1.0 - ((position.1 + size.1) / image_size.y)
)),
uv_max: Some(Vec2::new(
(position.0 + size.0) / image_size.x,
1.0 - (position.1 / image_size.y),
)),
color: Color::WHITE,
vertex_index: 0,
char_id: 0,
z_index: layout.z_index,
font_handle: None,
quad_type: UIQuadType::Image,
type_index: 0,
border_radius: Corner::default(),
image: image_handle,
},
};
extracted_quads.push(quad);
extracted_quads
}
mod extract;
pub use extract::extract_texture_atlas;
...@@ -13,6 +13,11 @@ pub enum RenderCommand { ...@@ -13,6 +13,11 @@ pub enum RenderCommand {
Image { Image {
handle: u16, handle: u16,
}, },
TextureAtlas {
position: (f32, f32),
size: (f32, f32),
handle: u16,
},
NinePatch { NinePatch {
border: Edge<f32>, border: Edge<f32>,
handle: u16, handle: u16,
......
...@@ -32,6 +32,12 @@ pub enum RenderPrimitive { ...@@ -32,6 +32,12 @@ pub enum RenderPrimitive {
layout: Rect, layout: Rect,
handle: u16, handle: u16,
}, },
TextureAtlas {
size: (f32, f32),
position: (f32, f32),
layout: Rect,
handle: u16,
},
NinePatch { NinePatch {
border: Edge<f32>, border: Edge<f32>,
layout: Rect, layout: Rect,
...@@ -47,6 +53,7 @@ impl RenderPrimitive { ...@@ -47,6 +53,7 @@ impl RenderPrimitive {
RenderPrimitive::Text { layout, .. } => *layout = new_layout, RenderPrimitive::Text { layout, .. } => *layout = new_layout,
RenderPrimitive::Image { layout, .. } => *layout = new_layout, RenderPrimitive::Image { layout, .. } => *layout = new_layout,
RenderPrimitive::NinePatch { layout, .. } => *layout = new_layout, RenderPrimitive::NinePatch { layout, .. } => *layout = new_layout,
RenderPrimitive::TextureAtlas { layout, .. } => *layout = new_layout,
_ => (), _ => (),
} }
} }
...@@ -98,6 +105,12 @@ impl From<&Style> for RenderPrimitive { ...@@ -98,6 +105,12 @@ impl From<&Style> for RenderPrimitive {
layout: Rect::default(), layout: Rect::default(),
handle, handle,
}, },
RenderCommand::TextureAtlas { handle, size, position, } => Self::TextureAtlas {
handle,
layout: Rect::default(),
size,
position,
},
RenderCommand::NinePatch { handle, border } => Self::NinePatch { RenderCommand::NinePatch { handle, border } => Self::NinePatch {
border, border,
layout: Rect::default(), layout: Rect::default(),
......
...@@ -8,6 +8,7 @@ mod if_element; ...@@ -8,6 +8,7 @@ mod if_element;
mod image; mod image;
mod inspector; mod inspector;
mod nine_patch; mod nine_patch;
mod texture_atlas;
mod scroll; mod scroll;
mod text; mod text;
mod text_box; mod text_box;
...@@ -24,6 +25,7 @@ pub use if_element::*; ...@@ -24,6 +25,7 @@ pub use if_element::*;
pub use image::*; pub use image::*;
pub use inspector::*; pub use inspector::*;
pub use nine_patch::*; pub use nine_patch::*;
pub use texture_atlas::*;
pub use scroll::*; pub use scroll::*;
pub use text::*; pub use text::*;
pub use text_box::*; pub use text_box::*;
......
use kayak_core::OnLayout;
use crate::core::{
render_command::RenderCommand,
rsx,
styles::{Style, StyleProp},
widget, Children, OnEvent, WidgetProps,
};
/// Props used by the [`NinePatch`] widget
#[derive(WidgetProps, Default, Debug, PartialEq, Clone)]
pub struct TextureAtlasProps {
/// The handle to image
pub handle: u16,
/// The position of the tile (in pixels)
pub position: (f32, f32),
/// The size of the tile (in pixels)
pub tile_size: (f32, f32),
#[prop_field(Styles)]
pub styles: Option<Style>,
#[prop_field(Children)]
pub children: Option<Children>,
#[prop_field(OnEvent)]
pub on_event: Option<OnEvent>,
#[prop_field(OnLayout)]
pub on_layout: Option<OnLayout>,
#[prop_field(Focusable)]
pub focusable: Option<bool>,
}
#[widget]
/// A widget that renders a nine-patch image background
///
/// A nine-patch is a special type of image that's broken into nine parts:
///
/// * Edges - Top, Bottom, Left, Right
/// * Corners - Top-Left, Top-Right, Bottom-Left, Bottom-Right
/// * Center
///
/// Using these parts of an image, we can construct a scalable background and border
/// all from a single image. This is done by:
///
/// * Stretching the edges (vertically for left/right and horizontally for top/bottom)
/// * Preserving the corners
/// * Scaling the center to fill the remaining space
///
///
/// # Props
///
/// __Type:__ [`NinePatchProps`]
///
/// | Common Prop | Accepted |
/// | :---------: | :------: |
/// | `children` | ✅ |
/// | `styles` | ✅ |
/// | `on_event` | ✅ |
/// | `on_layout` | ✅ |
/// | `focusable` | ✅ |
///
pub fn TextureAtlas(props: TextureAtlasProps) {
props.styles = Some(Style {
render_command: StyleProp::Value(RenderCommand::TextureAtlas {
position: props.position,
size: props.tile_size,
handle: props.handle,
}),
..props.styles.clone().unwrap_or_default()
});
rsx! {
<>
{children}
</>
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment