Skip to content
Snippets Groups Projects
Unverified Commit f64df76a authored by TheRawMeatball's avatar TheRawMeatball
Browse files

Split the renderer

parent 137c421a
No related branches found
No related tags found
No related merge requests found
Showing
with 265 additions and 16 deletions
...@@ -442,11 +442,24 @@ dependencies = [ ...@@ -442,11 +442,24 @@ dependencies = [
"ndk-glue 0.5.0", "ndk-glue 0.5.0",
] ]
[[package]]
name = "bevy_kayak_renderer"
version = "0.0.1"
dependencies = [
"bevy",
"bytemuck",
"kayak_font",
"serde",
"serde_json",
"serde_path_to_error",
]
[[package]] [[package]]
name = "bevy_kayak_ui" name = "bevy_kayak_ui"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bevy", "bevy",
"bevy_kayak_renderer",
"bytemuck", "bytemuck",
"kayak_core", "kayak_core",
"kayak_font", "kayak_font",
......
[package]
name = "bevy_kayak_renderer"
version = "0.0.1"
edition = "2021"
[dependencies]
bytemuck = "1.7.2"
bevy = { version = "0.6.0" }
kayak_font = { path = "../kayak_font" }
serde = "1.0"
serde_json = "1.0"
serde_path_to_error = "0.1"
use bevy::{
prelude::*,
window::{WindowCreated, WindowResized},
};
pub mod camera;
pub mod render;
pub use camera::*;
#[derive(Default)]
pub struct BevyKayakRendererPlugin;
impl Plugin for BevyKayakRendererPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.add_system(update_window_size)
.init_resource::<WindowSize>()
.add_plugin(render::BevyKayakUIRenderPlugin)
.add_plugin(camera::KayakUICameraPlugin);
}
}
/// Tracks the bevy window size.
#[derive(Default, Debug, Clone, Copy, PartialEq)]
pub struct WindowSize(pub f32, pub f32);
fn update_window_size(
mut window_resized_events: EventReader<WindowResized>,
mut window_created_events: EventReader<WindowCreated>,
) {
let mut changed_window_ids = Vec::new();
// handle resize events. latest events are handled first because we only want to resize each
// window once
for event in window_resized_events.iter().rev() {
if changed_window_ids.contains(&event.id) {
continue;
}
changed_window_ids.push(event.id);
}
// handle resize events. latest events are handled first because we only want to resize each
// window once
for event in window_created_events.iter().rev() {
if changed_window_ids.contains(&event.id) {
continue;
}
changed_window_ids.push(event.id);
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct Corner<T> {
pub top_left: T,
pub top_right: T,
pub bottom_left: T,
pub bottom_right: T,
}
use bevy::{
core_pipeline::node::MAIN_PASS_DRIVER,
prelude::{Commands, Plugin, Res},
render::{
camera::ActiveCameras,
render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType},
render_phase::{DrawFunctions, RenderPhase},
RenderApp, RenderStage,
},
};
use crate::{
render::{
ui_pass::MainPassUINode, ui_pass_driver::UIPassDriverNode, unified::UnifiedRenderPlugin,
},
UICameraBundle,
};
use self::ui_pass::TransparentUI;
mod ui_pass;
mod ui_pass_driver;
pub mod unified;
pub mod node {
pub const UI_PASS_DEPENDENCIES: &str = "kayak_ui_pass_dependencies";
pub const UI_PASS_DRIVER: &str = "kayak_ui_pass_driver";
}
pub mod draw_ui_graph {
pub const NAME: &str = "kayak_draw_ui";
pub mod input {
pub const VIEW_ENTITY: &str = "kayak_view_entity";
}
pub mod node {
pub const MAIN_PASS: &str = "kayak_ui_pass";
}
}
pub struct BevyKayakUIRenderPlugin;
impl Plugin for BevyKayakUIRenderPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
let render_app = app.sub_app_mut(RenderApp);
render_app
.init_resource::<DrawFunctions<TransparentUI>>()
.add_system_to_stage(RenderStage::Extract, extract_core_pipeline_camera_phases);
// .add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<TransparentUI>);
let pass_node_ui = MainPassUINode::new(&mut render_app.world);
let mut graph = render_app.world.get_resource_mut::<RenderGraph>().unwrap();
let mut draw_ui_graph = RenderGraph::default();
draw_ui_graph.add_node(draw_ui_graph::node::MAIN_PASS, pass_node_ui);
let input_node_id = draw_ui_graph.set_input(vec![SlotInfo::new(
draw_ui_graph::input::VIEW_ENTITY,
SlotType::Entity,
)]);
draw_ui_graph
.add_slot_edge(
input_node_id,
draw_ui_graph::input::VIEW_ENTITY,
draw_ui_graph::node::MAIN_PASS,
MainPassUINode::IN_VIEW,
)
.unwrap();
graph.add_sub_graph(draw_ui_graph::NAME, draw_ui_graph);
graph.add_node(node::UI_PASS_DEPENDENCIES, EmptyNode);
graph.add_node(node::UI_PASS_DRIVER, UIPassDriverNode);
graph
.add_node_edge(node::UI_PASS_DEPENDENCIES, node::UI_PASS_DRIVER)
.unwrap();
graph
.add_node_edge(MAIN_PASS_DRIVER, node::UI_PASS_DRIVER)
.unwrap();
app.add_plugin(UnifiedRenderPlugin);
}
}
pub fn extract_core_pipeline_camera_phases(
mut commands: Commands,
active_cameras: Res<ActiveCameras>,
) {
if let Some(camera_2d) = active_cameras.get(UICameraBundle::UI_CAMERA) {
if let Some(entity) = camera_2d.entity {
commands
.get_or_spawn(entity)
.insert(RenderPhase::<TransparentUI>::default());
}
}
}
use bevy::{ use bevy::{
math::Vec2,
prelude::{Assets, Commands, HandleUntyped, Plugin, Res}, prelude::{Assets, Commands, HandleUntyped, Plugin, Res},
reflect::TypeUuid, reflect::TypeUuid,
render::{ render::{render_phase::DrawFunctions, render_resource::Shader, RenderApp, RenderStage},
color::Color, render_phase::DrawFunctions, render_resource::Shader, texture::Image,
RenderApp, RenderStage,
},
sprite::Rect,
window::Windows, window::Windows,
}; };
use kayak_core::{render_primitive::RenderPrimitive, styles::Corner, Binding, Bound};
use kayak_font::KayakFont;
use crate::{ use crate::{
render::{ render::{
ui_pass::TransparentUI, ui_pass::TransparentUI,
unified::pipeline::{DrawUI, QuadMeta, UnifiedPipeline}, unified::pipeline::{DrawUI, QuadMeta, UnifiedPipeline},
}, },
BevyContext, FontMapping, ImageManager, WindowSize, WindowSize,
}; };
use self::pipeline::{ExtractQuadBundle, ExtractedQuad, ImageBindGroups, UIQuadType}; use self::pipeline::ImageBindGroups;
pub mod font; pub mod pipeline;
pub mod image;
mod nine_patch;
mod pipeline;
mod quad;
pub const UNIFIED_SHADER_HANDLE: HandleUntyped = pub const UNIFIED_SHADER_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 7604018236855288450); HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 7604018236855288450);
...@@ -39,15 +28,12 @@ impl Plugin for UnifiedRenderPlugin { ...@@ -39,15 +28,12 @@ impl Plugin for UnifiedRenderPlugin {
let unified_shader = Shader::from_wgsl(include_str!("shader.wgsl")); let unified_shader = Shader::from_wgsl(include_str!("shader.wgsl"));
shaders.set_untracked(UNIFIED_SHADER_HANDLE, unified_shader); shaders.set_untracked(UNIFIED_SHADER_HANDLE, unified_shader);
app.add_plugin(font::TextRendererPlugin)
.add_plugin(image::ImageRendererPlugin);
let render_app = app.sub_app_mut(RenderApp); let render_app = app.sub_app_mut(RenderApp);
render_app render_app
.init_resource::<ImageBindGroups>() .init_resource::<ImageBindGroups>()
.init_resource::<UnifiedPipeline>() .init_resource::<UnifiedPipeline>()
.init_resource::<QuadMeta>() .init_resource::<QuadMeta>()
.add_system_to_stage(RenderStage::Extract, extract) .add_system_to_stage(RenderStage::Extract, extract_baseline)
.add_system_to_stage(RenderStage::Prepare, pipeline::prepare_quads) .add_system_to_stage(RenderStage::Prepare, pipeline::prepare_quads)
.add_system_to_stage(RenderStage::Queue, pipeline::queue_quads); .add_system_to_stage(RenderStage::Queue, pipeline::queue_quads);
...@@ -64,83 +50,17 @@ impl Plugin for UnifiedRenderPlugin { ...@@ -64,83 +50,17 @@ impl Plugin for UnifiedRenderPlugin {
pub struct Dpi(f32); pub struct Dpi(f32);
pub fn extract( pub fn extract_baseline(
mut commands: Commands, mut commands: Commands,
context: Option<Res<BevyContext>>,
fonts: Res<Assets<KayakFont>>,
font_mapping: Res<FontMapping>,
image_manager: Res<ImageManager>,
images: Res<Assets<Image>>,
windows: Res<Windows>, windows: Res<Windows>,
window_size: Res<Binding<WindowSize>>, window_size: Res<WindowSize>,
) { ) {
if context.is_none() {
return;
}
let context = context.unwrap();
let render_primitives = if let Ok(context) = context.kayak_context.read() {
context.widget_manager.build_render_primitives()
} else {
vec![]
};
// dbg!(&render_primitives);
let dpi = if let Some(window) = windows.get_primary() { let dpi = if let Some(window) = windows.get_primary() {
window.scale_factor() as f32 window.scale_factor() as f32
} else { } else {
1.0 1.0
}; };
let mut extracted_quads = Vec::new(); commands.insert_resource(*window_size);
for render_primitive in render_primitives {
match render_primitive {
RenderPrimitive::Text { .. } => {
let text_quads = font::extract_texts(&render_primitive, &fonts, &font_mapping, dpi);
extracted_quads.extend(text_quads);
}
RenderPrimitive::Image { .. } => {
let image_quads = image::extract_images(&render_primitive, &image_manager, dpi);
extracted_quads.extend(image_quads);
}
RenderPrimitive::Quad { .. } => {
let quad_quads = quad::extract_quads(&render_primitive, 1.0);
extracted_quads.extend(quad_quads);
}
RenderPrimitive::NinePatch { .. } => {
let nine_patch_quads =
nine_patch::extract_nine_patch(&render_primitive, &image_manager, &images, dpi);
extracted_quads.extend(nine_patch_quads);
}
RenderPrimitive::Clip { layout } => {
extracted_quads.push(ExtractQuadBundle {
extracted_quad: ExtractedQuad {
rect: Rect {
min: Vec2::new(layout.posx, layout.posy) * dpi,
max: Vec2::new(layout.posx + layout.width, layout.posy + layout.height)
* dpi,
},
color: Color::default(),
vertex_index: 0,
char_id: 0,
z_index: layout.z_index,
font_handle: None,
quad_type: UIQuadType::Clip,
type_index: 0,
border_radius: Corner::default(),
image: None,
uv_min: None,
uv_max: None,
},
});
}
_ => {}
}
}
commands.insert_resource(window_size.get());
commands.insert_resource(Dpi(dpi)); commands.insert_resource(Dpi(dpi));
commands.spawn_batch(extracted_quads);
} }
...@@ -38,8 +38,8 @@ use kayak_font::{ ...@@ -38,8 +38,8 @@ use kayak_font::{
}; };
use super::{Dpi, UNIFIED_SHADER_HANDLE}; use super::{Dpi, UNIFIED_SHADER_HANDLE};
use crate::{render::ui_pass::TransparentUI, WindowSize}; use crate::render::ui_pass::TransparentUI;
use kayak_core::styles::Corner; use crate::{Corner, WindowSize};
pub struct UnifiedPipeline { pub struct UnifiedPipeline {
view_layout: BindGroupLayout, view_layout: BindGroupLayout,
...@@ -300,7 +300,7 @@ impl FromWorld for UnifiedPipeline { ...@@ -300,7 +300,7 @@ impl FromWorld for UnifiedPipeline {
#[derive(Debug, Bundle)] #[derive(Debug, Bundle)]
pub struct ExtractQuadBundle { pub struct ExtractQuadBundle {
pub(crate) extracted_quad: ExtractedQuad, pub extracted_quad: ExtractedQuad,
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
......
...@@ -8,6 +8,7 @@ bytemuck = "1.7.2" ...@@ -8,6 +8,7 @@ bytemuck = "1.7.2"
bevy = { version = "0.6.0" } bevy = { version = "0.6.0" }
kayak_core = { path = "../kayak_core" } kayak_core = { path = "../kayak_core" }
kayak_font = { path = "../kayak_font" } kayak_font = { path = "../kayak_font" }
bevy_kayak_renderer = { path = "../bevy_kayak_renderer" }
serde = "1.0" serde = "1.0"
serde_json = "1.0" serde_json = "1.0"
serde_path_to_error = "0.1" serde_path_to_error = "0.1"
...@@ -7,17 +7,16 @@ use bevy::{ ...@@ -7,17 +7,16 @@ use bevy::{
}; };
mod bevy_context; mod bevy_context;
mod camera;
mod cursor; mod cursor;
mod key; mod key;
mod render; mod render;
use crate::cursor::convert_cursor_icon; use crate::cursor::convert_cursor_icon;
pub use bevy_context::BevyContext; pub use bevy_context::BevyContext;
pub use camera::*; pub use bevy_kayak_renderer::camera::*;
use kayak_core::{bind, Binding, InputEvent, MutableBound}; use kayak_core::{bind, Binding, InputEvent, MutableBound};
pub use render::unified::font::FontMapping; pub use render::font::FontMapping;
pub use render::unified::image::ImageManager; pub use render::image::ImageManager;
#[derive(Default)] #[derive(Default)]
pub struct BevyKayakUIPlugin; pub struct BevyKayakUIPlugin;
...@@ -25,8 +24,8 @@ pub struct BevyKayakUIPlugin; ...@@ -25,8 +24,8 @@ pub struct BevyKayakUIPlugin;
impl Plugin for BevyKayakUIPlugin { impl Plugin for BevyKayakUIPlugin {
fn build(&self, app: &mut bevy::prelude::App) { fn build(&self, app: &mut bevy::prelude::App) {
app.insert_resource(bind(WindowSize::default())) app.insert_resource(bind(WindowSize::default()))
.add_plugin(render::BevyKayakUIRenderPlugin) .add_plugin(bevy_kayak_renderer::BevyKayakRendererPlugin)
.add_plugin(camera::KayakUICameraPlugin) .add_plugin(render::BevyKayakUIExtractPlugin)
.add_system(update_window_size) .add_system(update_window_size)
.add_system(process_events.exclusive_system()) .add_system(process_events.exclusive_system())
.add_system(update.exclusive_system()); .add_system(update.exclusive_system());
......
...@@ -4,12 +4,12 @@ use bevy::{ ...@@ -4,12 +4,12 @@ use bevy::{
sprite::Rect, sprite::Rect,
}; };
use kayak_core::render_primitive::RenderPrimitive; use kayak_core::render_primitive::RenderPrimitive;
use kayak_core::styles::Corner;
use kayak_font::{Alignment, CoordinateSystem, KayakFont}; use kayak_font::{Alignment, CoordinateSystem, KayakFont};
use crate::{ use crate::to_bevy_color;
use bevy_kayak_renderer::{
render::unified::pipeline::{ExtractQuadBundle, ExtractedQuad, UIQuadType}, render::unified::pipeline::{ExtractQuadBundle, ExtractedQuad, UIQuadType},
to_bevy_color, Corner,
}; };
use super::font_mapping::FontMapping; use super::font_mapping::FontMapping;
......
...@@ -17,7 +17,7 @@ mod font_mapping; ...@@ -17,7 +17,7 @@ mod font_mapping;
use crate::BevyContext; use crate::BevyContext;
use super::pipeline::UnifiedPipeline; use bevy_kayak_renderer::render::unified::pipeline::UnifiedPipeline;
pub use extract::extract_texts; pub use extract::extract_texts;
pub use font_mapping::*; pub use font_mapping::*;
......
use bevy::{math::Vec2, prelude::Res, render::color::Color, sprite::Rect}; use bevy::{math::Vec2, prelude::Res, render::color::Color, sprite::Rect};
use kayak_core::render_primitive::RenderPrimitive; use kayak_core::render_primitive::RenderPrimitive;
use crate::{ use crate::ImageManager;
use bevy_kayak_renderer::{
render::unified::pipeline::{ExtractQuadBundle, ExtractedQuad, UIQuadType}, render::unified::pipeline::{ExtractQuadBundle, ExtractedQuad, UIQuadType},
ImageManager, Corner,
}; };
pub fn extract_images( pub fn extract_images(
...@@ -33,7 +34,12 @@ pub fn extract_images( ...@@ -33,7 +34,12 @@ pub fn extract_images(
font_handle: None, font_handle: None,
quad_type: UIQuadType::Image, quad_type: UIQuadType::Image,
type_index: 0, type_index: 0,
border_radius, border_radius: Corner {
top_left: border_radius.top_left,
top_right: border_radius.top_right,
bottom_left: border_radius.bottom_left,
bottom_right: border_radius.bottom_right,
},
image: image_manager image: image_manager
.get_handle(handle) .get_handle(handle)
.and_then(|a| Some(a.clone_weak())), .and_then(|a| Some(a.clone_weak())),
......
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