overflow: hidden/scroll scissor support, remove depth
This commit is contained in:
@@ -77,7 +77,7 @@ fn load_testbed(
|
|||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
init_logging();
|
init_logging();
|
||||||
|
|
||||||
let (gfx, event_loop, window, surface) = init_window()?;
|
let (gfx, event_loop, window, surface) = init_window("[-/=]: gui scale, F10: debug draw")?;
|
||||||
let inner_size = window.inner_size();
|
let inner_size = window.inner_size();
|
||||||
let mut swapchain_size = [inner_size.width, inner_size.height];
|
let mut swapchain_size = [inner_size.width, inner_size.height];
|
||||||
|
|
||||||
@@ -115,6 +115,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
render_context.update_viewport(&mut shared_context, swapchain_size, scale)?;
|
render_context.update_viewport(&mut shared_context, swapchain_size, scale)?;
|
||||||
log::trace!("new swapchain_size: {swapchain_size:?}");
|
log::trace!("new swapchain_size: {swapchain_size:?}");
|
||||||
|
|
||||||
|
let mut debug_draw_enabled = false;
|
||||||
|
|
||||||
let mut profiler = profiler::Profiler::new(1000);
|
let mut profiler = profiler::Profiler::new(1000);
|
||||||
let mut frame_index: u64 = 0;
|
let mut frame_index: u64 = 0;
|
||||||
|
|
||||||
@@ -218,6 +220,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if event.state == ElementState::Pressed {
|
if event.state == ElementState::Pressed {
|
||||||
|
if event.physical_key == PhysicalKey::Code(KeyCode::F10) {
|
||||||
|
debug_draw_enabled = !debug_draw_enabled;
|
||||||
|
testbed.layout().borrow_mut().mark_redraw();
|
||||||
|
}
|
||||||
|
|
||||||
if event.physical_key == PhysicalKey::Code(KeyCode::Equal) {
|
if event.physical_key == PhysicalKey::Code(KeyCode::Equal) {
|
||||||
scale *= 1.25;
|
scale *= 1.25;
|
||||||
render_context
|
render_context
|
||||||
@@ -323,7 +330,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.begin_rendering(tgt, WGfxClearMode::Clear([0.0, 0.0, 0.0, 0.1]))
|
.begin_rendering(tgt, WGfxClearMode::Clear([0.0, 0.0, 0.0, 0.1]))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let primitives = wgui::drawing::draw(&testbed.layout().borrow_mut()).unwrap();
|
let draw_params = wgui::drawing::DrawParams {
|
||||||
|
layout: &testbed.layout().borrow_mut(),
|
||||||
|
debug_draw: debug_draw_enabled,
|
||||||
|
};
|
||||||
|
|
||||||
|
let primitives = wgui::drawing::draw(&draw_params).unwrap();
|
||||||
render_context
|
render_context
|
||||||
.draw(&mut shared_context, &mut cmd_buf, &primitives)
|
.draw(&mut shared_context, &mut cmd_buf, &primitives)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ fn get_vulkan_library() -> &'static Arc<vulkano::VulkanLibrary> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn init_window() -> anyhow::Result<(
|
pub fn init_window(
|
||||||
|
title: &str,
|
||||||
|
) -> anyhow::Result<(
|
||||||
Arc<WGfx>,
|
Arc<WGfx>,
|
||||||
winit::event_loop::EventLoop<()>,
|
winit::event_loop::EventLoop<()>,
|
||||||
Arc<winit::window::Window>,
|
Arc<winit::window::Window>,
|
||||||
@@ -40,7 +42,11 @@ pub fn init_window() -> anyhow::Result<(
|
|||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let window = Arc::new(
|
let window = Arc::new(
|
||||||
event_loop
|
event_loop
|
||||||
.create_window(Window::default_attributes().with_transparent(true))
|
.create_window(
|
||||||
|
Window::default_attributes()
|
||||||
|
.with_transparent(true)
|
||||||
|
.with_title(title),
|
||||||
|
)
|
||||||
.unwrap(), // want panic
|
.unwrap(), // want panic
|
||||||
);
|
);
|
||||||
let surface = Surface::from_window(instance.clone(), window.clone())?;
|
let surface = Surface::from_window(instance.clone(), window.clone())?;
|
||||||
|
|||||||
@@ -233,6 +233,8 @@ pub fn construct<U1, U2>(
|
|||||||
style.align_items = Some(AlignItems::Center);
|
style.align_items = Some(AlignItems::Center);
|
||||||
style.justify_content = Some(JustifyContent::Center);
|
style.justify_content = Some(JustifyContent::Center);
|
||||||
style.padding = length(1.0);
|
style.padding = length(1.0);
|
||||||
|
style.overflow.x = taffy::Overflow::Hidden;
|
||||||
|
style.overflow.y = taffy::Overflow::Hidden;
|
||||||
|
|
||||||
// update colors to default ones if they are not specified
|
// update colors to default ones if they are not specified
|
||||||
let color = if let Some(color) = params.color {
|
let color = if let Some(color) = params.color {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::{
|
|||||||
drawing,
|
drawing,
|
||||||
layout::Widget,
|
layout::Widget,
|
||||||
renderer_vk::text::custom_glyph::CustomGlyph,
|
renderer_vk::text::custom_glyph::CustomGlyph,
|
||||||
transform_stack::{self, TransformStack},
|
stack::{self, ScissorStack, TransformStack},
|
||||||
widget::{self},
|
widget::{self},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,6 +37,22 @@ impl Boundary {
|
|||||||
size: Vec2::new(transform.dim.x, transform.dim.y),
|
size: Vec2::new(transform.dim.x, transform.dim.y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn top(&self) -> f32 {
|
||||||
|
self.pos.y
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn bottom(&self) -> f32 {
|
||||||
|
self.pos.y + self.size.y
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn left(&self) -> f32 {
|
||||||
|
self.pos.x
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn right(&self) -> f32 {
|
||||||
|
self.pos.x + self.size.x
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
@@ -115,7 +131,6 @@ pub struct Rectangle {
|
|||||||
pub struct PrimitiveExtent {
|
pub struct PrimitiveExtent {
|
||||||
pub(super) boundary: Boundary,
|
pub(super) boundary: Boundary,
|
||||||
pub(super) transform: Mat4,
|
pub(super) transform: Mat4,
|
||||||
pub(super) depth: f32, // FIXME: remove this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum RenderPrimitive {
|
pub enum RenderPrimitive {
|
||||||
@@ -126,15 +141,39 @@ pub enum RenderPrimitive {
|
|||||||
ScissorDisable,
|
ScissorDisable,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct DrawParams<'a> {
|
||||||
|
pub layout: &'a Layout,
|
||||||
|
pub debug_draw: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_overflow_clip(style: &taffy::Style) -> bool {
|
||||||
|
style.overflow.x != taffy::Overflow::Visible || style.overflow.y != taffy::Overflow::Visible
|
||||||
|
}
|
||||||
|
|
||||||
|
fn primitive_debug_rect(boundary: &Boundary, transform: &Mat4, color: drawing::Color) -> drawing::RenderPrimitive {
|
||||||
|
drawing::RenderPrimitive::Rectangle(
|
||||||
|
PrimitiveExtent {
|
||||||
|
boundary: *boundary,
|
||||||
|
transform: *transform,
|
||||||
|
},
|
||||||
|
Rectangle {
|
||||||
|
border: 1.0,
|
||||||
|
border_color: color,
|
||||||
|
color: Color::new(0.0, 0.0, 0.0, 0.0),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_widget(
|
fn draw_widget(
|
||||||
layout: &Layout,
|
params: &DrawParams,
|
||||||
state: &mut DrawState,
|
state: &mut DrawState,
|
||||||
node_id: taffy::NodeId,
|
node_id: taffy::NodeId,
|
||||||
style: &taffy::Style,
|
style: &taffy::Style,
|
||||||
widget: &Widget,
|
widget: &Widget,
|
||||||
parent_transform: &glam::Mat4,
|
parent_transform: &glam::Mat4,
|
||||||
) {
|
) {
|
||||||
let Ok(l) = layout.state.tree.layout(node_id) else {
|
let Ok(l) = params.layout.state.tree.layout(node_id) else {
|
||||||
debug_assert!(false);
|
debug_assert!(false);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -148,16 +187,34 @@ fn draw_widget(
|
|||||||
None => (Vec2::default(), None),
|
None => (Vec2::default(), None),
|
||||||
};
|
};
|
||||||
|
|
||||||
state.transform_stack.push(transform_stack::Transform {
|
state.transform_stack.push(stack::Transform {
|
||||||
pos: Vec2::new(l.location.x, l.location.y) - shift,
|
pos: Vec2::new(l.location.x, l.location.y) - shift,
|
||||||
transform,
|
transform,
|
||||||
dim: Vec2::new(l.size.width, l.size.height),
|
dim: Vec2::new(l.size.width, l.size.height),
|
||||||
});
|
});
|
||||||
|
|
||||||
// FIXME: this is temporary
|
if params.debug_draw {
|
||||||
// FIXME: implement scissor stack (do not allow growing!)
|
|
||||||
if info.is_some() {
|
|
||||||
let boundary = drawing::Boundary::construct(state.transform_stack);
|
let boundary = drawing::Boundary::construct(state.transform_stack);
|
||||||
|
state.primitives.push(primitive_debug_rect(
|
||||||
|
&boundary,
|
||||||
|
&transform,
|
||||||
|
Color::new(0.0, 1.0, 1.0, 0.5),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let scissor_pushed = info.is_some() && has_overflow_clip(style);
|
||||||
|
|
||||||
|
if scissor_pushed {
|
||||||
|
let boundary = drawing::Boundary::construct(state.transform_stack);
|
||||||
|
state.scissor_stack.push(boundary);
|
||||||
|
if params.debug_draw {
|
||||||
|
state.primitives.push(primitive_debug_rect(
|
||||||
|
&boundary,
|
||||||
|
&transform,
|
||||||
|
Color::new(1.0, 0.0, 1.0, 1.0),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
state.primitives.push(drawing::RenderPrimitive::ScissorEnable(boundary));
|
state.primitives.push(drawing::RenderPrimitive::ScissorEnable(boundary));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,10 +226,11 @@ fn draw_widget(
|
|||||||
|
|
||||||
widget_state.draw_all(state, &draw_params);
|
widget_state.draw_all(state, &draw_params);
|
||||||
|
|
||||||
draw_children(layout, state, node_id, &transform);
|
draw_children(params, state, node_id, &transform);
|
||||||
|
|
||||||
if info.is_some() {
|
if scissor_pushed {
|
||||||
state.primitives.push(drawing::RenderPrimitive::ScissorDisable);
|
state.primitives.push(drawing::RenderPrimitive::ScissorDisable);
|
||||||
|
state.scissor_stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
state.transform_stack.pop();
|
state.transform_stack.pop();
|
||||||
@@ -182,7 +240,9 @@ fn draw_widget(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_children(layout: &Layout, state: &mut DrawState, parent_node_id: taffy::NodeId, model: &glam::Mat4) {
|
fn draw_children(params: &DrawParams, state: &mut DrawState, parent_node_id: taffy::NodeId, model: &glam::Mat4) {
|
||||||
|
let layout = ¶ms.layout;
|
||||||
|
|
||||||
for node_id in layout.state.tree.child_ids(parent_node_id) {
|
for node_id in layout.state.tree.child_ids(parent_node_id) {
|
||||||
let Some(widget_id) = layout.state.tree.get_node_context(node_id).copied() else {
|
let Some(widget_id) = layout.state.tree.get_node_context(node_id).copied() else {
|
||||||
debug_assert!(false);
|
debug_assert!(false);
|
||||||
@@ -199,33 +259,37 @@ fn draw_children(layout: &Layout, state: &mut DrawState, parent_node_id: taffy::
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
state.depth += 0.01;
|
draw_widget(params, state, node_id, style, widget, model);
|
||||||
draw_widget(layout, state, node_id, style, widget, model);
|
|
||||||
state.depth -= 0.01;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(layout: &Layout) -> anyhow::Result<Vec<RenderPrimitive>> {
|
pub fn draw(params: &DrawParams) -> anyhow::Result<Vec<RenderPrimitive>> {
|
||||||
let mut primitives = Vec::<RenderPrimitive>::new();
|
let mut primitives = Vec::<RenderPrimitive>::new();
|
||||||
let mut transform_stack = TransformStack::new();
|
let mut transform_stack = TransformStack::new();
|
||||||
|
let mut scissor_stack = ScissorStack::new();
|
||||||
let model = glam::Mat4::IDENTITY;
|
let model = glam::Mat4::IDENTITY;
|
||||||
|
|
||||||
let Some(root_widget) = layout.state.widgets.get(layout.root_widget) else {
|
let Some(root_widget) = params.layout.state.widgets.get(params.layout.root_widget) else {
|
||||||
panic!();
|
panic!();
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(style) = layout.state.tree.style(layout.root_node) else {
|
let Ok(style) = params.layout.state.tree.style(params.layout.root_node) else {
|
||||||
panic!();
|
panic!();
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut params = DrawState {
|
scissor_stack.push(Boundary {
|
||||||
|
pos: Default::default(),
|
||||||
|
size: Vec2::splat(1.0e12),
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut state = DrawState {
|
||||||
primitives: &mut primitives,
|
primitives: &mut primitives,
|
||||||
transform_stack: &mut transform_stack,
|
transform_stack: &mut transform_stack,
|
||||||
layout,
|
scissor_stack: &mut scissor_stack,
|
||||||
depth: 0.0,
|
layout: params.layout,
|
||||||
};
|
};
|
||||||
|
|
||||||
draw_widget(layout, &mut params, layout.root_node, style, root_widget, &model);
|
draw_widget(params, &mut state, params.layout.root_node, style, root_widget, &model);
|
||||||
|
|
||||||
Ok(primitives)
|
Ok(primitives)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
animation::{self, Animation},
|
animation::{self, Animation},
|
||||||
i18n::I18n,
|
i18n::I18n,
|
||||||
layout::{LayoutState, WidgetID},
|
layout::{LayoutState, WidgetID},
|
||||||
transform_stack::{Transform, TransformStack},
|
stack::{Transform, TransformStack},
|
||||||
widget::{WidgetData, WidgetObj},
|
widget::{WidgetData, WidgetObj},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ impl CallbackMetadata {
|
|||||||
|
|
||||||
pub fn get_mouse_pos_relative(&self, transform_stack: &TransformStack) -> Option<Vec2> {
|
pub fn get_mouse_pos_relative(&self, transform_stack: &TransformStack) -> Option<Vec2> {
|
||||||
let mouse_pos_abs = self.get_mouse_pos_absolute()?;
|
let mouse_pos_abs = self.get_mouse_pos_absolute()?;
|
||||||
Some(mouse_pos_abs - transform_stack.get_pos())
|
Some(mouse_pos_abs - transform_stack.get().pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ impl<T> WCommandBuffer<T> {
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum WGfxClearMode {
|
pub enum WGfxClearMode {
|
||||||
Keep,
|
Keep,
|
||||||
|
DontCare,
|
||||||
Clear([f32; 4]),
|
Clear([f32; 4]),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,10 +59,12 @@ impl WCommandBuffer<CmdBufGfx> {
|
|||||||
load_op: match &clear_mode {
|
load_op: match &clear_mode {
|
||||||
WGfxClearMode::Keep => AttachmentLoadOp::Load,
|
WGfxClearMode::Keep => AttachmentLoadOp::Load,
|
||||||
WGfxClearMode::Clear(_) => AttachmentLoadOp::Clear,
|
WGfxClearMode::Clear(_) => AttachmentLoadOp::Clear,
|
||||||
|
WGfxClearMode::DontCare => AttachmentLoadOp::DontCare,
|
||||||
},
|
},
|
||||||
store_op: AttachmentStoreOp::Store,
|
store_op: AttachmentStoreOp::Store,
|
||||||
clear_value: match &clear_mode {
|
clear_value: match &clear_mode {
|
||||||
WGfxClearMode::Keep => None,
|
WGfxClearMode::Keep => None,
|
||||||
|
WGfxClearMode::DontCare => None,
|
||||||
WGfxClearMode::Clear(color) => Some(ClearValue::Float(*color)),
|
WGfxClearMode::Clear(color) => Some(ClearValue::Float(*color)),
|
||||||
},
|
},
|
||||||
..RenderingAttachmentInfo::image_view(render_target)
|
..RenderingAttachmentInfo::image_view(render_target)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use crate::{
|
|||||||
components::{Component, InitData},
|
components::{Component, InitData},
|
||||||
event::{self, CallbackDataCommon, EventAlterables, EventListenerCollection},
|
event::{self, CallbackDataCommon, EventAlterables, EventListenerCollection},
|
||||||
globals::WguiGlobals,
|
globals::WguiGlobals,
|
||||||
transform_stack::Transform,
|
stack::Transform,
|
||||||
widget::{self, EventParams, WidgetObj, WidgetState, div::WidgetDiv},
|
widget::{self, EventParams, WidgetObj, WidgetState, div::WidgetDiv},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,9 @@
|
|||||||
clippy::option_if_let_else,
|
clippy::option_if_let_else,
|
||||||
clippy::significant_drop_tightening,
|
clippy::significant_drop_tightening,
|
||||||
clippy::float_cmp,
|
clippy::float_cmp,
|
||||||
clippy::needless_pass_by_ref_mut
|
clippy::needless_pass_by_ref_mut,
|
||||||
|
clippy::use_self,
|
||||||
|
clippy::match_same_arms
|
||||||
)]
|
)]
|
||||||
|
|
||||||
pub mod animation;
|
pub mod animation;
|
||||||
@@ -30,7 +32,7 @@ pub mod i18n;
|
|||||||
pub mod layout;
|
pub mod layout;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod renderer_vk;
|
pub mod renderer_vk;
|
||||||
pub mod transform_stack;
|
pub mod stack;
|
||||||
pub mod widget;
|
pub mod widget;
|
||||||
|
|
||||||
// re-exported libs
|
// re-exported libs
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ impl Context {
|
|||||||
drawing::RenderPrimitive::Rectangle(extent, rectangle) => {
|
drawing::RenderPrimitive::Rectangle(extent, rectangle) => {
|
||||||
pass
|
pass
|
||||||
.rect_renderer
|
.rect_renderer
|
||||||
.add_rect(extent.boundary, *rectangle, &extent.transform, extent.depth);
|
.add_rect(extent.boundary, *rectangle, &extent.transform);
|
||||||
}
|
}
|
||||||
drawing::RenderPrimitive::Text(extent, text) => {
|
drawing::RenderPrimitive::Text(extent, text) => {
|
||||||
pass.text_areas.push(TextArea {
|
pass.text_areas.push(TextArea {
|
||||||
@@ -253,7 +253,6 @@ impl Context {
|
|||||||
scale: self.pixel_scale,
|
scale: self.pixel_scale,
|
||||||
default_color: cosmic_text::Color::rgb(0, 0, 0),
|
default_color: cosmic_text::Color::rgb(0, 0, 0),
|
||||||
custom_glyphs: &[],
|
custom_glyphs: &[],
|
||||||
depth: extent.depth,
|
|
||||||
transform: extent.transform,
|
transform: extent.transform,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -266,7 +265,6 @@ impl Context {
|
|||||||
scale: self.pixel_scale,
|
scale: self.pixel_scale,
|
||||||
custom_glyphs: sprites.as_slice(),
|
custom_glyphs: sprites.as_slice(),
|
||||||
default_color: cosmic_text::Color::rgb(255, 0, 255),
|
default_color: cosmic_text::Color::rgb(255, 0, 255),
|
||||||
depth: extent.depth,
|
|
||||||
transform: extent.transform,
|
transform: extent.transform,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ pub struct RectVertex {
|
|||||||
pub in_border_color: u32,
|
pub in_border_color: u32,
|
||||||
#[format(R32_UINT)]
|
#[format(R32_UINT)]
|
||||||
pub round_border_gradient: [u8; 4],
|
pub round_border_gradient: [u8; 4],
|
||||||
#[format(R32_SFLOAT)]
|
|
||||||
pub depth: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cloneable pipeline & shaders to be shared between `RectRenderer` instances.
|
/// Cloneable pipeline & shaders to be shared between `RectRenderer` instances.
|
||||||
@@ -68,7 +66,7 @@ pub struct RectRenderer {
|
|||||||
pipeline: RectPipeline,
|
pipeline: RectPipeline,
|
||||||
rect_vertices: Vec<RectVertex>,
|
rect_vertices: Vec<RectVertex>,
|
||||||
vert_buffer: Subbuffer<[RectVertex]>,
|
vert_buffer: Subbuffer<[RectVertex]>,
|
||||||
vert_buffer_size: usize,
|
vert_buffer_len: usize,
|
||||||
model_buffer: ModelBuffer,
|
model_buffer: ModelBuffer,
|
||||||
pass: Option<CachedPass>,
|
pass: Option<CachedPass>,
|
||||||
}
|
}
|
||||||
@@ -77,16 +75,17 @@ impl RectRenderer {
|
|||||||
pub fn new(pipeline: RectPipeline) -> anyhow::Result<Self> {
|
pub fn new(pipeline: RectPipeline) -> anyhow::Result<Self> {
|
||||||
const BUFFER_SIZE: usize = 32;
|
const BUFFER_SIZE: usize = 32;
|
||||||
|
|
||||||
let vert_buffer = pipeline
|
let vert_buffer = pipeline.gfx.empty_buffer(
|
||||||
.gfx
|
BufferUsage::VERTEX_BUFFER | BufferUsage::TRANSFER_DST,
|
||||||
.empty_buffer(BufferUsage::VERTEX_BUFFER | BufferUsage::TRANSFER_DST, BUFFER_SIZE as _)?;
|
(std::mem::size_of::<RectVertex>() * BUFFER_SIZE) as _,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
model_buffer: ModelBuffer::new(&pipeline.gfx)?,
|
model_buffer: ModelBuffer::new(&pipeline.gfx)?,
|
||||||
pipeline,
|
pipeline,
|
||||||
rect_vertices: vec![],
|
rect_vertices: vec![],
|
||||||
vert_buffer,
|
vert_buffer,
|
||||||
vert_buffer_size: BUFFER_SIZE,
|
vert_buffer_len: BUFFER_SIZE,
|
||||||
pass: None,
|
pass: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -96,7 +95,7 @@ impl RectRenderer {
|
|||||||
self.model_buffer.begin();
|
self.model_buffer.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_rect(&mut self, boundary: Boundary, rectangle: Rectangle, transform: &Mat4, depth: f32) {
|
pub fn add_rect(&mut self, boundary: Boundary, rectangle: Rectangle, transform: &Mat4) {
|
||||||
let in_model_idx = self
|
let in_model_idx = self
|
||||||
.model_buffer
|
.model_buffer
|
||||||
.register_pos_size(&boundary.pos, &boundary.size, transform);
|
.register_pos_size(&boundary.pos, &boundary.size, transform);
|
||||||
@@ -113,18 +112,17 @@ impl RectRenderer {
|
|||||||
rectangle.gradient as u8,
|
rectangle.gradient as u8,
|
||||||
0, // unused
|
0, // unused
|
||||||
],
|
],
|
||||||
depth,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upload_verts(&mut self) -> anyhow::Result<()> {
|
fn upload_verts(&mut self) -> anyhow::Result<()> {
|
||||||
if self.vert_buffer_size < self.rect_vertices.len() {
|
if self.vert_buffer_len < self.rect_vertices.len() {
|
||||||
let new_size = self.vert_buffer_size * 2;
|
let new_size = self.vert_buffer_len * 2;
|
||||||
self.vert_buffer = self
|
self.vert_buffer = self.pipeline.gfx.empty_buffer(
|
||||||
.pipeline
|
BufferUsage::VERTEX_BUFFER | BufferUsage::TRANSFER_DST,
|
||||||
.gfx
|
(std::mem::size_of::<RectVertex>() * new_size) as _,
|
||||||
.empty_buffer(BufferUsage::VERTEX_BUFFER | BufferUsage::TRANSFER_DST, new_size as _)?;
|
)?;
|
||||||
self.vert_buffer_size = new_size;
|
self.vert_buffer_len = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.vert_buffer.write()?[0..self.rect_vertices.len()].clone_from_slice(&self.rect_vertices);
|
self.vert_buffer.write()?[0..self.rect_vertices.len()].clone_from_slice(&self.rect_vertices);
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ layout(location = 2) in uint in_color;
|
|||||||
layout(location = 3) in uint in_color2;
|
layout(location = 3) in uint in_color2;
|
||||||
layout(location = 4) in uint in_border_color;
|
layout(location = 4) in uint in_border_color;
|
||||||
layout(location = 5) in uint round_border_gradient;
|
layout(location = 5) in uint round_border_gradient;
|
||||||
layout(location = 6) in float depth;
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 out_color;
|
layout(location = 0) out vec4 out_color;
|
||||||
layout(location = 1) out vec4 out_color2;
|
layout(location = 1) out vec4 out_color2;
|
||||||
@@ -41,8 +40,7 @@ void main() {
|
|||||||
|
|
||||||
out_rect_size = rect_size;
|
out_rect_size = rect_size;
|
||||||
|
|
||||||
gl_Position =
|
gl_Position = uniforms.projection * model_matrix * vec4(corner_pos, 0.0, 1.0);
|
||||||
uniforms.projection * model_matrix * vec4(corner_pos, depth, 1.0);
|
|
||||||
|
|
||||||
out_border_color =
|
out_border_color =
|
||||||
vec4(float((in_border_color & 0x00ff0000u) >> 16u) / 255.0,
|
vec4(float((in_border_color & 0x00ff0000u) >> 16u) / 255.0,
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ layout(location = 1) in uint in_rect_dim;
|
|||||||
layout(location = 2) in uint in_uv;
|
layout(location = 2) in uint in_uv;
|
||||||
layout(location = 3) in uint in_color;
|
layout(location = 3) in uint in_color;
|
||||||
layout(location = 4) in uint in_content_type;
|
layout(location = 4) in uint in_content_type;
|
||||||
layout(location = 5) in float depth;
|
|
||||||
layout(location = 7) in float scale;
|
layout(location = 7) in float scale;
|
||||||
|
|
||||||
layout(location = 0) out vec4 out_color;
|
layout(location = 0) out vec4 out_color;
|
||||||
@@ -41,7 +40,7 @@ void main() {
|
|||||||
mat4 model_matrix = model_buffer.models[in_model_idx];
|
mat4 model_matrix = model_buffer.models[in_model_idx];
|
||||||
|
|
||||||
gl_Position =
|
gl_Position =
|
||||||
uniforms.projection * model_matrix * vec4(corner_pos * scale, depth, 1.0);
|
uniforms.projection * model_matrix * vec4(corner_pos * scale, 0.0, 1.0);
|
||||||
|
|
||||||
out_content_type = in_content_type & 0xffffu;
|
out_content_type = in_content_type & 0xffffu;
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ pub mod text_renderer;
|
|||||||
|
|
||||||
use std::{cell::RefCell, rc::Rc, sync::LazyLock};
|
use std::{cell::RefCell, rc::Rc, sync::LazyLock};
|
||||||
|
|
||||||
use cosmic_text::{
|
use cosmic_text::{Align, Attrs, Buffer, Color, FontSystem, Metrics, Style, SwashCache, Weight, Wrap};
|
||||||
Align, Attrs, Buffer, Color, FontSystem, Metrics, Style, SwashCache, Weight, Wrap,
|
|
||||||
};
|
|
||||||
use custom_glyph::{ContentType, CustomGlyph};
|
use custom_glyph::{ContentType, CustomGlyph};
|
||||||
use etagere::AllocId;
|
use etagere::AllocId;
|
||||||
use glam::Mat4;
|
use glam::Mat4;
|
||||||
@@ -15,10 +13,8 @@ use parking_lot::Mutex;
|
|||||||
|
|
||||||
use crate::drawing::{self};
|
use crate::drawing::{self};
|
||||||
|
|
||||||
pub static FONT_SYSTEM: LazyLock<Mutex<FontSystem>> =
|
pub static FONT_SYSTEM: LazyLock<Mutex<FontSystem>> = LazyLock::new(|| Mutex::new(FontSystem::new()));
|
||||||
LazyLock::new(|| Mutex::new(FontSystem::new()));
|
pub static SWASH_CACHE: LazyLock<Mutex<SwashCache>> = LazyLock::new(|| Mutex::new(SwashCache::new()));
|
||||||
pub static SWASH_CACHE: LazyLock<Mutex<SwashCache>> =
|
|
||||||
LazyLock::new(|| Mutex::new(SwashCache::new()));
|
|
||||||
|
|
||||||
/// Used in case no `font_size` is defined
|
/// Used in case no `font_size` is defined
|
||||||
const DEFAULT_FONT_SIZE: f32 = 14.;
|
const DEFAULT_FONT_SIZE: f32 = 14.;
|
||||||
@@ -26,10 +22,8 @@ const DEFAULT_FONT_SIZE: f32 = 14.;
|
|||||||
/// In case no `line_height` is defined, use `font_size` * `DEFAULT_LINE_HEIGHT_RATIO`
|
/// In case no `line_height` is defined, use `font_size` * `DEFAULT_LINE_HEIGHT_RATIO`
|
||||||
const DEFAULT_LINE_HEIGHT_RATIO: f32 = 1.43;
|
const DEFAULT_LINE_HEIGHT_RATIO: f32 = 1.43;
|
||||||
|
|
||||||
pub(crate) const DEFAULT_METRICS: Metrics = Metrics::new(
|
pub(crate) const DEFAULT_METRICS: Metrics =
|
||||||
DEFAULT_FONT_SIZE,
|
Metrics::new(DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE * DEFAULT_LINE_HEIGHT_RATIO);
|
||||||
DEFAULT_FONT_SIZE * DEFAULT_LINE_HEIGHT_RATIO,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct TextStyle {
|
pub struct TextStyle {
|
||||||
@@ -66,11 +60,7 @@ impl From<&TextStyle> for Metrics {
|
|||||||
|
|
||||||
impl From<&TextStyle> for Wrap {
|
impl From<&TextStyle> for Wrap {
|
||||||
fn from(value: &TextStyle) -> Self {
|
fn from(value: &TextStyle) -> Self {
|
||||||
if value.wrap {
|
if value.wrap { Self::WordOrGlyph } else { Self::None }
|
||||||
Self::WordOrGlyph
|
|
||||||
} else {
|
|
||||||
Self::None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,11 +145,7 @@ impl From<cosmic_text::Color> for drawing::Color {
|
|||||||
// glyphon types below
|
// glyphon types below
|
||||||
|
|
||||||
pub(super) enum GpuCacheStatus {
|
pub(super) enum GpuCacheStatus {
|
||||||
InAtlas {
|
InAtlas { x: u16, y: u16, content_type: ContentType },
|
||||||
x: u16,
|
|
||||||
y: u16,
|
|
||||||
content_type: ContentType,
|
|
||||||
},
|
|
||||||
SkipRasterization,
|
SkipRasterization,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,8 +201,6 @@ pub struct TextArea<'a> {
|
|||||||
pub default_color: Color,
|
pub default_color: Color,
|
||||||
/// Additional custom glyphs to render.
|
/// Additional custom glyphs to render.
|
||||||
pub custom_glyphs: &'a [CustomGlyph],
|
pub custom_glyphs: &'a [CustomGlyph],
|
||||||
/// Distance from camera, 0.0..=1.0
|
|
||||||
pub depth: f32,
|
|
||||||
/// Text transformation
|
/// Text transformation
|
||||||
pub transform: Mat4,
|
pub transform: Mat4,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,10 +42,7 @@ impl TextPipeline {
|
|||||||
true,
|
true,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self { gfx, inner: pipeline })
|
||||||
gfx,
|
|
||||||
inner: pipeline,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,8 +60,6 @@ pub struct GlyphVertex {
|
|||||||
#[format(R32_UINT)]
|
#[format(R32_UINT)]
|
||||||
pub in_content_type: [u16; 2], // 2 bytes unused! TODO
|
pub in_content_type: [u16; 2], // 2 bytes unused! TODO
|
||||||
#[format(R32_SFLOAT)]
|
#[format(R32_SFLOAT)]
|
||||||
pub depth: f32,
|
|
||||||
#[format(R32_SFLOAT)]
|
|
||||||
pub scale: f32,
|
pub scale: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,12 +81,7 @@ impl InnerAtlas {
|
|||||||
const INITIAL_SIZE: u32 = 256;
|
const INITIAL_SIZE: u32 = 256;
|
||||||
|
|
||||||
fn new(common: TextPipeline, kind: Kind) -> anyhow::Result<Self> {
|
fn new(common: TextPipeline, kind: Kind) -> anyhow::Result<Self> {
|
||||||
let max_texture_dimension_2d = common
|
let max_texture_dimension_2d = common.gfx.device.physical_device().properties().max_image_dimension2_d;
|
||||||
.gfx
|
|
||||||
.device
|
|
||||||
.physical_device()
|
|
||||||
.properties()
|
|
||||||
.max_image_dimension2_d;
|
|
||||||
let size = Self::INITIAL_SIZE.min(max_texture_dimension_2d);
|
let size = Self::INITIAL_SIZE.min(max_texture_dimension_2d);
|
||||||
|
|
||||||
let packer = BucketedAtlasAllocator::new(size2(size as i32, size as i32));
|
let packer = BucketedAtlasAllocator::new(size2(size as i32, size as i32));
|
||||||
@@ -180,11 +170,7 @@ impl InnerAtlas {
|
|||||||
self.kind.num_channels()
|
self.kind.num_channels()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn grow(
|
pub(super) fn grow(&mut self, font_system: &mut FontSystem, cache: &mut SwashCache) -> anyhow::Result<bool> {
|
||||||
&mut self,
|
|
||||||
font_system: &mut FontSystem,
|
|
||||||
cache: &mut SwashCache,
|
|
||||||
) -> anyhow::Result<bool> {
|
|
||||||
const GROWTH_FACTOR: u32 = 2;
|
const GROWTH_FACTOR: u32 = 2;
|
||||||
|
|
||||||
if self.size >= self.max_texture_dimension_2d {
|
if self.size >= self.max_texture_dimension_2d {
|
||||||
@@ -327,10 +313,7 @@ impl TextAtlas {
|
|||||||
Ok(did_grow)
|
Ok(did_grow)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) const fn inner_for_content_mut(
|
pub(super) const fn inner_for_content_mut(&mut self, content_type: ContentType) -> &mut InnerAtlas {
|
||||||
&mut self,
|
|
||||||
content_type: ContentType,
|
|
||||||
) -> &mut InnerAtlas {
|
|
||||||
match content_type {
|
match content_type {
|
||||||
ContentType::Color => &mut self.color_atlas,
|
ContentType::Color => &mut self.color_atlas,
|
||||||
ContentType::Mask => &mut self.mask_atlas,
|
ContentType::Mask => &mut self.mask_atlas,
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ impl TextRenderer {
|
|||||||
bounds_min_y,
|
bounds_min_y,
|
||||||
bounds_max_x,
|
bounds_max_x,
|
||||||
bounds_max_y,
|
bounds_max_y,
|
||||||
depth: text_area.depth,
|
|
||||||
transform: &text_area.transform,
|
transform: &text_area.transform,
|
||||||
},
|
},
|
||||||
|_cache, _font_system| -> Option<GetGlyphImageResult> {
|
|_cache, _font_system| -> Option<GetGlyphImageResult> {
|
||||||
@@ -192,7 +191,6 @@ impl TextRenderer {
|
|||||||
bounds_min_y,
|
bounds_min_y,
|
||||||
bounds_max_x,
|
bounds_max_x,
|
||||||
bounds_max_y,
|
bounds_max_y,
|
||||||
depth: text_area.depth,
|
|
||||||
transform: &text_area.transform,
|
transform: &text_area.transform,
|
||||||
},
|
},
|
||||||
|cache, font_system| -> Option<GetGlyphImageResult> {
|
|cache, font_system| -> Option<GetGlyphImageResult> {
|
||||||
@@ -319,7 +317,6 @@ struct PrepareGlyphParams<'a> {
|
|||||||
bounds_min_y: i32,
|
bounds_min_y: i32,
|
||||||
bounds_max_x: i32,
|
bounds_max_x: i32,
|
||||||
bounds_max_y: i32,
|
bounds_max_y: i32,
|
||||||
depth: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
@@ -484,7 +481,6 @@ fn prepare_glyph(
|
|||||||
content_type as u16,
|
content_type as u16,
|
||||||
0, // unused (TODO!)
|
0, // unused (TODO!)
|
||||||
],
|
],
|
||||||
depth: par.depth,
|
|
||||||
scale: par.glyph_scale,
|
scale: par.glyph_scale,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|||||||
108
wgui/src/stack.rs
Normal file
108
wgui/src/stack.rs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
use glam::Vec2;
|
||||||
|
|
||||||
|
use crate::drawing;
|
||||||
|
|
||||||
|
pub trait Pushable<T> {
|
||||||
|
fn push(&mut self, item: &T);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GenericStack<T, const STACK_MAX: usize> {
|
||||||
|
pub stack: [T; STACK_MAX],
|
||||||
|
top: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait StackItem<T>: Default + Clone + Copy + Pushable<T> {}
|
||||||
|
|
||||||
|
impl<T: StackItem<T>, const STACK_MAX: usize> GenericStack<T, STACK_MAX> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
stack: [Default::default(); STACK_MAX],
|
||||||
|
top: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(&mut self, mut item: T) {
|
||||||
|
assert!(self.top < STACK_MAX as u8);
|
||||||
|
let idx = (self.top - 1) as usize;
|
||||||
|
let upper_item = &self.stack[idx];
|
||||||
|
item.push(upper_item);
|
||||||
|
self.stack[self.top as usize] = item;
|
||||||
|
self.top += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pop(&mut self) {
|
||||||
|
assert!(self.top > 0);
|
||||||
|
self.top -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn get(&self) -> &T {
|
||||||
|
&self.stack[(self.top - 1) as usize]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: StackItem<T>, const STACK_MAX: usize> Default for GenericStack<T, STACK_MAX> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ########################################
|
||||||
|
// Transform stack
|
||||||
|
// ########################################
|
||||||
|
|
||||||
|
#[derive(Default, Copy, Clone)]
|
||||||
|
pub struct Transform {
|
||||||
|
pub pos: Vec2,
|
||||||
|
pub transform: glam::Mat4,
|
||||||
|
pub dim: Vec2, // for convenience
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> StackItem<T> for Transform where Transform: Pushable<T> {}
|
||||||
|
|
||||||
|
impl Pushable<Transform> for Transform {
|
||||||
|
fn push(&mut self, upper: &Transform) {
|
||||||
|
self.pos += upper.pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type TransformStack = GenericStack<Transform, 64>;
|
||||||
|
|
||||||
|
// ########################################
|
||||||
|
// Scissor stack
|
||||||
|
// ########################################
|
||||||
|
|
||||||
|
impl<T> StackItem<T> for drawing::Boundary where drawing::Boundary: Pushable<T> {}
|
||||||
|
|
||||||
|
impl Pushable<drawing::Boundary> for drawing::Boundary {
|
||||||
|
fn push(&mut self, upper: &drawing::Boundary) {
|
||||||
|
let mut display_pos = self.pos;
|
||||||
|
let mut display_size = self.size;
|
||||||
|
|
||||||
|
// limit in x-coord
|
||||||
|
if display_pos.x < upper.left() {
|
||||||
|
display_size.x -= upper.left() - display_pos.x;
|
||||||
|
display_pos.x = upper.left();
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit in y-coord
|
||||||
|
if display_pos.y < upper.top() {
|
||||||
|
display_size.y -= upper.top() - display_pos.y;
|
||||||
|
display_pos.y = upper.top();
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit in width
|
||||||
|
if display_pos.x + display_size.x > upper.right() {
|
||||||
|
display_size.x = upper.right() - display_pos.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit in height
|
||||||
|
if display_pos.y + display_size.y > upper.bottom() {
|
||||||
|
display_size.y = upper.bottom() - display_pos.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.pos = display_pos;
|
||||||
|
self.size = display_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type ScissorStack = GenericStack<drawing::Boundary, 64>;
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
use glam::Vec2;
|
|
||||||
|
|
||||||
#[derive(Default, Copy, Clone)]
|
|
||||||
pub struct Transform {
|
|
||||||
pub pos: Vec2,
|
|
||||||
pub transform: glam::Mat4,
|
|
||||||
|
|
||||||
pub dim: Vec2, // for convenience
|
|
||||||
}
|
|
||||||
|
|
||||||
const TRANSFORM_STACK_MAX: usize = 64;
|
|
||||||
pub struct TransformStack {
|
|
||||||
pub stack: [Transform; TRANSFORM_STACK_MAX],
|
|
||||||
top: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TransformStack {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
stack: [Default::default(); TRANSFORM_STACK_MAX],
|
|
||||||
top: 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push(&mut self, mut t: Transform) {
|
|
||||||
assert!(self.top < TRANSFORM_STACK_MAX as u8);
|
|
||||||
let idx = (self.top - 1) as usize;
|
|
||||||
t.pos += self.stack[idx].pos;
|
|
||||||
self.stack[self.top as usize] = t;
|
|
||||||
self.top += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pop(&mut self) {
|
|
||||||
assert!(self.top > 0);
|
|
||||||
self.top -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn get(&self) -> &Transform {
|
|
||||||
&self.stack[(self.top - 1) as usize]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn get_pos(&self) -> Vec2 {
|
|
||||||
self.stack[(self.top - 1) as usize].pos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for TransformStack {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -121,7 +121,6 @@ impl WidgetObj for WidgetLabel {
|
|||||||
state.primitives.push(drawing::RenderPrimitive::Text(
|
state.primitives.push(drawing::RenderPrimitive::Text(
|
||||||
PrimitiveExtent {
|
PrimitiveExtent {
|
||||||
boundary,
|
boundary,
|
||||||
depth: state.depth,
|
|
||||||
transform: state.transform_stack.get().transform,
|
transform: state.transform_stack.get().transform,
|
||||||
},
|
},
|
||||||
self.buffer.clone(),
|
self.buffer.clone(),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
EventListenerVec, MouseWheelEvent,
|
EventListenerVec, MouseWheelEvent,
|
||||||
},
|
},
|
||||||
layout::{Layout, LayoutState, WidgetID},
|
layout::{Layout, LayoutState, WidgetID},
|
||||||
transform_stack::TransformStack,
|
stack::{ScissorStack, TransformStack},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod div;
|
pub mod div;
|
||||||
@@ -100,7 +100,7 @@ pub struct DrawState<'a> {
|
|||||||
pub layout: &'a Layout,
|
pub layout: &'a Layout,
|
||||||
pub primitives: &'a mut Vec<RenderPrimitive>,
|
pub primitives: &'a mut Vec<RenderPrimitive>,
|
||||||
pub transform_stack: &'a mut TransformStack,
|
pub transform_stack: &'a mut TransformStack,
|
||||||
pub depth: f32, //TODO: actually use this in shader
|
pub scissor_stack: &'a mut ScissorStack,
|
||||||
}
|
}
|
||||||
|
|
||||||
// per-widget draw params
|
// per-widget draw params
|
||||||
@@ -253,7 +253,6 @@ impl WidgetState {
|
|||||||
),
|
),
|
||||||
Vec2::new(transform.dim.x * info.handle_size.x, thickness),
|
Vec2::new(transform.dim.x * info.handle_size.x, thickness),
|
||||||
),
|
),
|
||||||
depth: state.depth,
|
|
||||||
transform: transform.transform,
|
transform: transform.transform,
|
||||||
},
|
},
|
||||||
rect_params,
|
rect_params,
|
||||||
@@ -271,7 +270,6 @@ impl WidgetState {
|
|||||||
),
|
),
|
||||||
Vec2::new(thickness, transform.dim.y * info.handle_size.y),
|
Vec2::new(thickness, transform.dim.y * info.handle_size.y),
|
||||||
),
|
),
|
||||||
depth: state.depth,
|
|
||||||
transform: transform.transform,
|
transform: transform.transform,
|
||||||
},
|
},
|
||||||
rect_params,
|
rect_params,
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ impl WidgetObj for WidgetRectangle {
|
|||||||
state.primitives.push(drawing::RenderPrimitive::Rectangle(
|
state.primitives.push(drawing::RenderPrimitive::Rectangle(
|
||||||
PrimitiveExtent {
|
PrimitiveExtent {
|
||||||
boundary,
|
boundary,
|
||||||
depth: state.depth,
|
|
||||||
transform: state.transform_stack.get().transform,
|
transform: state.transform_stack.get().transform,
|
||||||
},
|
},
|
||||||
drawing::Rectangle {
|
drawing::Rectangle {
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ impl WidgetObj for WidgetSprite {
|
|||||||
state.primitives.push(drawing::RenderPrimitive::Sprite(
|
state.primitives.push(drawing::RenderPrimitive::Sprite(
|
||||||
PrimitiveExtent {
|
PrimitiveExtent {
|
||||||
boundary,
|
boundary,
|
||||||
depth: state.depth,
|
|
||||||
transform: state.transform_stack.get().transform,
|
transform: state.transform_stack.get().transform,
|
||||||
},
|
},
|
||||||
Some(glyph),
|
Some(glyph),
|
||||||
@@ -79,12 +78,11 @@ impl WidgetObj for WidgetSprite {
|
|||||||
state.primitives.push(drawing::RenderPrimitive::Text(
|
state.primitives.push(drawing::RenderPrimitive::Text(
|
||||||
PrimitiveExtent {
|
PrimitiveExtent {
|
||||||
boundary,
|
boundary,
|
||||||
depth: state.depth,
|
|
||||||
transform: state.transform_stack.get().transform,
|
transform: state.transform_stack.get().transform,
|
||||||
},
|
},
|
||||||
Rc::new(RefCell::new(buffer)),
|
Rc::new(RefCell::new(buffer)),
|
||||||
))
|
));
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn measure(
|
fn measure(
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use std::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use wgui::gfx::{WGfx, pass::WGfxPass, pipeline::WGfxPipeline};
|
use wgui::gfx::{WGfx, cmd::WGfxClearMode, pass::WGfxPass, pipeline::WGfxPipeline};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::openxr::helpers,
|
backend::openxr::helpers,
|
||||||
@@ -71,6 +71,7 @@ impl LinePool {
|
|||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
vec![set0],
|
vec![set0],
|
||||||
|
&Default::default(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -161,7 +162,7 @@ impl LinePool {
|
|||||||
let mut cmd_buffer = app
|
let mut cmd_buffer = app
|
||||||
.gfx
|
.gfx
|
||||||
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
||||||
cmd_buffer.begin_rendering(tgt)?;
|
cmd_buffer.begin_rendering(tgt, WGfxClearMode::DontCare)?;
|
||||||
cmd_buffer.run_ref(&self.pass)?;
|
cmd_buffer.run_ref(&self.pass)?;
|
||||||
cmd_buffer.end_rendering()?;
|
cmd_buffer.end_rendering()?;
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use vulkano::{
|
|||||||
image::view::ImageView,
|
image::view::ImageView,
|
||||||
pipeline::graphics::{color_blend::AttachmentBlend, input_assembly::PrimitiveTopology},
|
pipeline::graphics::{color_blend::AttachmentBlend, input_assembly::PrimitiveTopology},
|
||||||
};
|
};
|
||||||
|
use wgui::gfx::cmd::WGfxClearMode;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::openxr::{helpers::translation_rotation_to_posef, swapchain::SwapchainOpts},
|
backend::openxr::{helpers::translation_rotation_to_posef, swapchain::SwapchainOpts},
|
||||||
@@ -112,12 +113,13 @@ impl Skybox {
|
|||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
vec![set0, set1],
|
vec![set0, set1],
|
||||||
|
&Default::default(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut cmd_buffer = app
|
let mut cmd_buffer = app
|
||||||
.gfx
|
.gfx
|
||||||
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
||||||
cmd_buffer.begin_rendering(tgt)?;
|
cmd_buffer.begin_rendering(tgt, WGfxClearMode::DontCare)?;
|
||||||
cmd_buffer.run_ref(&pass)?;
|
cmd_buffer.run_ref(&pass)?;
|
||||||
cmd_buffer.end_rendering()?;
|
cmd_buffer.end_rendering()?;
|
||||||
|
|
||||||
@@ -160,12 +162,13 @@ impl Skybox {
|
|||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
vec![],
|
vec![],
|
||||||
|
&Default::default(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut cmd_buffer = app
|
let mut cmd_buffer = app
|
||||||
.gfx
|
.gfx
|
||||||
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
||||||
cmd_buffer.begin_rendering(tgt)?;
|
cmd_buffer.begin_rendering(tgt, WGfxClearMode::Clear([0.0, 0.0, 0.0, 0.0]))?;
|
||||||
cmd_buffer.run_ref(&pass)?;
|
cmd_buffer.run_ref(&pass)?;
|
||||||
cmd_buffer.end_rendering()?;
|
cmd_buffer.end_rendering()?;
|
||||||
|
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ impl Display {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick_render(&mut self, renderer: &mut GlesRenderer, time_ms: u64) -> anyhow::Result<()> {
|
pub fn tick_render(&mut self, renderer: &mut GlesRenderer, time_ms: u64) -> anyhow::Result<()> {
|
||||||
renderer.bind(self.gles_texture.clone())?;
|
renderer.bind(&mut self.gles_texture)?;
|
||||||
|
|
||||||
let size = Size::from((i32::from(self.width), i32::from(self.height)));
|
let size = Size::from((i32::from(self.width), i32::from(self.height)));
|
||||||
let damage: Rectangle<i32, smithay::utils::Physical> = Rectangle::from_size(size);
|
let damage: Rectangle<i32, smithay::utils::Physical> = Rectangle::from_size(size);
|
||||||
|
|||||||
@@ -243,8 +243,15 @@ impl<S> OverlayBackend for GuiPanel<S> {
|
|||||||
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)
|
||||||
.unwrap(); // want panic
|
.unwrap(); // want panic
|
||||||
|
|
||||||
cmd_buf.begin_rendering(tgt)?;
|
cmd_buf.begin_rendering(
|
||||||
let primitives = wgui::drawing::draw(&self.layout)?;
|
tgt,
|
||||||
|
wgui::gfx::cmd::WGfxClearMode::Clear([0.0, 0.0, 0.0, 0.0]),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let primitives = wgui::drawing::draw(&wgui::drawing::DrawParams {
|
||||||
|
layout: &self.layout,
|
||||||
|
debug_draw: false,
|
||||||
|
})?;
|
||||||
self.context
|
self.context
|
||||||
.draw(&mut app.wgui_shared, &mut cmd_buf, &primitives)?;
|
.draw(&mut app.wgui_shared, &mut cmd_buf, &primitives)?;
|
||||||
cmd_buf.end_rendering()?;
|
cmd_buf.end_rendering()?;
|
||||||
|
|||||||
@@ -6,21 +6,22 @@ use vulkano::{
|
|||||||
command_buffer::CommandBufferUsage,
|
command_buffer::CommandBufferUsage,
|
||||||
device::Queue,
|
device::Queue,
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{sampler::Filter, view::ImageView, Image},
|
image::{Image, sampler::Filter, view::ImageView},
|
||||||
pipeline::graphics::{color_blend::AttachmentBlend, input_assembly::PrimitiveTopology},
|
pipeline::graphics::{color_blend::AttachmentBlend, input_assembly::PrimitiveTopology},
|
||||||
};
|
};
|
||||||
use wgui::gfx::{pass::WGfxPass, pipeline::WGfxPipeline, WGfx};
|
use wgui::gfx::{WGfx, cmd::WGfxClearMode, pass::WGfxPass, pipeline::WGfxPipeline};
|
||||||
use wlx_capture::{
|
use wlx_capture::{
|
||||||
frame::{self as wlx_frame, DrmFormat, FrameFormat, MouseMeta, Transform, WlxFrame},
|
|
||||||
WlxCapture,
|
WlxCapture,
|
||||||
|
frame::{self as wlx_frame, DrmFormat, FrameFormat, MouseMeta, Transform, WlxFrame},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::overlay::FrameMeta,
|
backend::overlay::FrameMeta,
|
||||||
config::GeneralConfig,
|
config::GeneralConfig,
|
||||||
graphics::{
|
graphics::{
|
||||||
dmabuf::{fourcc_to_vk, WGfxDmabuf},
|
CommandBuffers, Vert2Uv,
|
||||||
upload_quad_vertices, CommandBuffers, Vert2Uv,
|
dmabuf::{WGfxDmabuf, fourcc_to_vk},
|
||||||
|
upload_quad_vertices,
|
||||||
},
|
},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
};
|
};
|
||||||
@@ -91,6 +92,7 @@ impl ScreenPipeline {
|
|||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
vec![set0, set1],
|
vec![set0, set1],
|
||||||
|
&Default::default(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +125,14 @@ impl ScreenPipeline {
|
|||||||
|
|
||||||
let set0 = pipeline.uniform_sampler(0, view, Filter::Nearest)?;
|
let set0 = pipeline.uniform_sampler(0, view, Filter::Nearest)?;
|
||||||
let set1 = pipeline.buffer(1, buf_alpha)?;
|
let set1 = pipeline.buffer(1, buf_alpha)?;
|
||||||
let pass = pipeline.create_pass(extentf, buf_vert.clone(), 0..4, 0..1, vec![set0, set1])?;
|
let pass = pipeline.create_pass(
|
||||||
|
extentf,
|
||||||
|
buf_vert.clone(),
|
||||||
|
0..4,
|
||||||
|
0..1,
|
||||||
|
vec![set0, set1],
|
||||||
|
&Default::default(),
|
||||||
|
)?;
|
||||||
|
|
||||||
cmd_xfer.build_and_execute_now()?;
|
cmd_xfer.build_and_execute_now()?;
|
||||||
Ok(MousePass { pass, buf_vert })
|
Ok(MousePass { pass, buf_vert })
|
||||||
@@ -145,7 +154,7 @@ impl ScreenPipeline {
|
|||||||
let mut cmd = app
|
let mut cmd = app
|
||||||
.gfx
|
.gfx
|
||||||
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
||||||
cmd.begin_rendering(tgt)?;
|
cmd.begin_rendering(tgt, WGfxClearMode::DontCare)?;
|
||||||
cmd.run_ref(&self.pass)?;
|
cmd.run_ref(&self.pass)?;
|
||||||
|
|
||||||
if let Some(mouse) = capture.mouse.as_ref() {
|
if let Some(mouse) = capture.mouse.as_ref() {
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ impl WayVRBackend {
|
|||||||
0..4,
|
0..4,
|
||||||
0..1,
|
0..1,
|
||||||
vec![set0, set1],
|
vec![set0, set1],
|
||||||
|
&Default::default(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -683,7 +684,10 @@ impl OverlayBackend for WayVRBackend {
|
|||||||
let mut cmd_buffer = app
|
let mut cmd_buffer = app
|
||||||
.gfx
|
.gfx
|
||||||
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
||||||
cmd_buffer.begin_rendering(tgt)?;
|
cmd_buffer.begin_rendering(
|
||||||
|
tgt,
|
||||||
|
wgui::gfx::cmd::WGfxClearMode::Clear([0.0, 0.0, 0.0, 1.0]),
|
||||||
|
)?;
|
||||||
cmd_buffer.run_ref(&self.pass)?;
|
cmd_buffer.run_ref(&self.pass)?;
|
||||||
cmd_buffer.end_rendering()?;
|
cmd_buffer.end_rendering()?;
|
||||||
buf.push(cmd_buffer.build()?);
|
buf.push(cmd_buffer.build()?);
|
||||||
|
|||||||
@@ -96,10 +96,7 @@ impl AppState {
|
|||||||
toast_sound: toast_sound_wav,
|
toast_sound: toast_sound_wav,
|
||||||
wgui_globals: WguiGlobals::new(
|
wgui_globals: WguiGlobals::new(
|
||||||
Box::new(gui::asset::GuiAsset {}),
|
Box::new(gui::asset::GuiAsset {}),
|
||||||
wgui::globals::Defaults {
|
wgui::globals::Defaults::default(),
|
||||||
dark_mode: true,
|
|
||||||
text_color: wgui::drawing::Color::new(1.0, 1.0, 1.0, 1.0),
|
|
||||||
},
|
|
||||||
)?,
|
)?,
|
||||||
|
|
||||||
#[cfg(feature = "osc")]
|
#[cfg(feature = "osc")]
|
||||||
|
|||||||
Reference in New Issue
Block a user