Add border_width
and border_color
to Quad
This commit is contained in:
parent
649d72e7de
commit
9ab7c47dc7
@ -25,6 +25,14 @@ impl Color {
|
|||||||
a: 1.0,
|
a: 1.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// A color with no opacity.
|
||||||
|
pub const TRANSPARENT: Color = Color {
|
||||||
|
r: 0.0,
|
||||||
|
g: 0.0,
|
||||||
|
b: 0.0,
|
||||||
|
a: 0.0,
|
||||||
|
};
|
||||||
|
|
||||||
/// Creates a [`Color`] from its RGB8 components.
|
/// Creates a [`Color`] from its RGB8 components.
|
||||||
///
|
///
|
||||||
/// [`Color`]: struct.Color.html
|
/// [`Color`]: struct.Color.html
|
||||||
|
@ -63,6 +63,8 @@ mod circle {
|
|||||||
bounds: layout.bounds(),
|
bounds: layout.bounds(),
|
||||||
background: Background::Color(Color::BLACK),
|
background: Background::Color(Color::BLACK),
|
||||||
border_radius: self.radius,
|
border_radius: self.radius,
|
||||||
|
border_width: 0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
},
|
},
|
||||||
MouseCursor::OutOfBounds,
|
MouseCursor::OutOfBounds,
|
||||||
)
|
)
|
||||||
|
@ -27,7 +27,7 @@ impl Sandbox for Tour {
|
|||||||
scroll: scrollable::State::new(),
|
scroll: scrollable::State::new(),
|
||||||
back_button: button::State::new(),
|
back_button: button::State::new(),
|
||||||
next_button: button::State::new(),
|
next_button: button::State::new(),
|
||||||
debug: false,
|
debug: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,10 @@ pub enum Primitive {
|
|||||||
background: Background,
|
background: Background,
|
||||||
/// The border radius of the quad
|
/// The border radius of the quad
|
||||||
border_radius: u16,
|
border_radius: u16,
|
||||||
|
/// The border width of the quad
|
||||||
|
border_width: u16,
|
||||||
|
/// The border color of the quad
|
||||||
|
border_color: Color,
|
||||||
},
|
},
|
||||||
/// An image primitive
|
/// An image primitive
|
||||||
Image {
|
Image {
|
||||||
|
@ -125,9 +125,19 @@ impl Pipeline {
|
|||||||
},
|
},
|
||||||
wgpu::VertexAttributeDescriptor {
|
wgpu::VertexAttributeDescriptor {
|
||||||
shader_location: 4,
|
shader_location: 4,
|
||||||
format: wgpu::VertexFormat::Float,
|
format: wgpu::VertexFormat::Float4,
|
||||||
offset: 4 * (2 + 2 + 4),
|
offset: 4 * (2 + 2 + 4),
|
||||||
},
|
},
|
||||||
|
wgpu::VertexAttributeDescriptor {
|
||||||
|
shader_location: 5,
|
||||||
|
format: wgpu::VertexFormat::Float,
|
||||||
|
offset: 4 * (2 + 2 + 4 + 4),
|
||||||
|
},
|
||||||
|
wgpu::VertexAttributeDescriptor {
|
||||||
|
shader_location: 6,
|
||||||
|
format: wgpu::VertexFormat::Float,
|
||||||
|
offset: 4 * (2 + 2 + 4 + 4 + 1),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -233,7 +243,8 @@ impl Pipeline {
|
|||||||
bounds.x,
|
bounds.x,
|
||||||
bounds.y,
|
bounds.y,
|
||||||
bounds.width,
|
bounds.width,
|
||||||
bounds.height,
|
// TODO: Address anti-aliasing adjustments properly
|
||||||
|
bounds.height + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
render_pass.draw_indexed(
|
render_pass.draw_indexed(
|
||||||
@ -277,7 +288,9 @@ pub struct Quad {
|
|||||||
pub position: [f32; 2],
|
pub position: [f32; 2],
|
||||||
pub scale: [f32; 2],
|
pub scale: [f32; 2],
|
||||||
pub color: [f32; 4],
|
pub color: [f32; 4],
|
||||||
|
pub border_color: [f32; 4],
|
||||||
pub border_radius: f32,
|
pub border_radius: f32,
|
||||||
|
pub border_width: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Quad {
|
impl Quad {
|
||||||
|
@ -223,6 +223,8 @@ impl Renderer {
|
|||||||
bounds,
|
bounds,
|
||||||
background,
|
background,
|
||||||
border_radius,
|
border_radius,
|
||||||
|
border_width,
|
||||||
|
border_color,
|
||||||
} => {
|
} => {
|
||||||
// TODO: Move some of this computations to the GPU (?)
|
// TODO: Move some of this computations to the GPU (?)
|
||||||
layer.quads.push(Quad {
|
layer.quads.push(Quad {
|
||||||
@ -235,6 +237,8 @@ impl Renderer {
|
|||||||
Background::Color(color) => color.into_linear(),
|
Background::Color(color) => color.into_linear(),
|
||||||
},
|
},
|
||||||
border_radius: *border_radius as f32,
|
border_radius: *border_radius as f32,
|
||||||
|
border_width: *border_width as f32,
|
||||||
|
border_color: border_color.into_linear(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Primitive::Image { handle, bounds } => {
|
Primitive::Image { handle, bounds } => {
|
||||||
@ -470,11 +474,12 @@ fn explain_layout(
|
|||||||
color: Color,
|
color: Color,
|
||||||
primitives: &mut Vec<Primitive>,
|
primitives: &mut Vec<Primitive>,
|
||||||
) {
|
) {
|
||||||
// TODO: Draw borders instead
|
|
||||||
primitives.push(Primitive::Quad {
|
primitives.push(Primitive::Quad {
|
||||||
bounds: layout.bounds(),
|
bounds: layout.bounds(),
|
||||||
background: Background::Color([0.0, 0.0, 0.0, 0.05].into()),
|
background: Background::Color(Color::TRANSPARENT),
|
||||||
border_radius: 0,
|
border_radius: 0,
|
||||||
|
border_width: 1,
|
||||||
|
border_color: [0.6, 0.6, 0.6, 0.5].into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
for child in layout.children() {
|
for child in layout.children() {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use crate::{button::StyleSheet, defaults, Defaults, Primitive, Renderer};
|
use crate::{button::StyleSheet, defaults, Defaults, Primitive, Renderer};
|
||||||
use iced_native::{Background, Element, Layout, MouseCursor, Point, Rectangle};
|
use iced_native::{
|
||||||
|
Background, Color, Element, Layout, MouseCursor, Point, Rectangle,
|
||||||
|
};
|
||||||
|
|
||||||
impl iced_native::button::Renderer for Renderer {
|
impl iced_native::button::Renderer for Renderer {
|
||||||
type Style = Box<dyn StyleSheet>;
|
type Style = Box<dyn StyleSheet>;
|
||||||
@ -57,11 +59,15 @@ impl iced_native::button::Renderer for Renderer {
|
|||||||
[0.0, 0.0, 0.0, 0.5].into(),
|
[0.0, 0.0, 0.0, 0.5].into(),
|
||||||
),
|
),
|
||||||
border_radius: styling.border_radius,
|
border_radius: styling.border_radius,
|
||||||
|
border_width: 0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
},
|
},
|
||||||
Primitive::Quad {
|
Primitive::Quad {
|
||||||
bounds,
|
bounds,
|
||||||
background,
|
background,
|
||||||
border_radius: styling.border_radius,
|
border_radius: styling.border_radius,
|
||||||
|
border_width: 0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
},
|
},
|
||||||
content,
|
content,
|
||||||
],
|
],
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{
|
use iced_native::{
|
||||||
checkbox, Background, HorizontalAlignment, MouseCursor, Rectangle,
|
checkbox, Background, Color, HorizontalAlignment, MouseCursor, Rectangle,
|
||||||
VerticalAlignment,
|
VerticalAlignment,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -18,19 +18,8 @@ impl checkbox::Renderer for Renderer {
|
|||||||
is_mouse_over: bool,
|
is_mouse_over: bool,
|
||||||
(label, _): Self::Output,
|
(label, _): Self::Output,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let (checkbox_border, checkbox_box) = (
|
let checkbox = Primitive::Quad {
|
||||||
Primitive::Quad {
|
|
||||||
bounds,
|
bounds,
|
||||||
background: Background::Color([0.6, 0.6, 0.6].into()),
|
|
||||||
border_radius: 6,
|
|
||||||
},
|
|
||||||
Primitive::Quad {
|
|
||||||
bounds: Rectangle {
|
|
||||||
x: bounds.x + 1.0,
|
|
||||||
y: bounds.y + 1.0,
|
|
||||||
width: bounds.width - 2.0,
|
|
||||||
height: bounds.height - 2.0,
|
|
||||||
},
|
|
||||||
background: Background::Color(
|
background: Background::Color(
|
||||||
if is_mouse_over {
|
if is_mouse_over {
|
||||||
[0.90, 0.90, 0.90]
|
[0.90, 0.90, 0.90]
|
||||||
@ -40,8 +29,9 @@ impl checkbox::Renderer for Renderer {
|
|||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
border_radius: 5,
|
border_radius: 5,
|
||||||
},
|
border_width: 1,
|
||||||
);
|
border_color: Color::from_rgb(0.6, 0.6, 0.6),
|
||||||
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
Primitive::Group {
|
Primitive::Group {
|
||||||
@ -56,9 +46,9 @@ impl checkbox::Renderer for Renderer {
|
|||||||
vertical_alignment: VerticalAlignment::Center,
|
vertical_alignment: VerticalAlignment::Center,
|
||||||
};
|
};
|
||||||
|
|
||||||
vec![checkbox_border, checkbox_box, check, label]
|
vec![checkbox, check, label]
|
||||||
} else {
|
} else {
|
||||||
vec![checkbox_border, checkbox_box, label]
|
vec![checkbox, label]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
if is_mouse_over {
|
if is_mouse_over {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{container, defaults, Defaults, Primitive, Renderer};
|
use crate::{container, defaults, Defaults, Primitive, Renderer};
|
||||||
use iced_native::{Element, Layout, Point, Rectangle};
|
use iced_native::{Color, Element, Layout, Point, Rectangle};
|
||||||
|
|
||||||
impl iced_native::container::Renderer for Renderer {
|
impl iced_native::container::Renderer for Renderer {
|
||||||
type Style = Box<dyn container::StyleSheet>;
|
type Style = Box<dyn container::StyleSheet>;
|
||||||
@ -31,6 +31,8 @@ impl iced_native::container::Renderer for Renderer {
|
|||||||
bounds,
|
bounds,
|
||||||
background,
|
background,
|
||||||
border_radius: style.border_radius,
|
border_radius: style.border_radius,
|
||||||
|
border_width: 0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{radio, Background, MouseCursor, Rectangle};
|
use iced_native::{radio, Background, Color, MouseCursor, Rectangle};
|
||||||
|
|
||||||
const SIZE: f32 = 28.0;
|
const SIZE: f32 = 28.0;
|
||||||
const DOT_SIZE: f32 = SIZE / 2.0;
|
const DOT_SIZE: f32 = SIZE / 2.0;
|
||||||
@ -16,19 +16,8 @@ impl radio::Renderer for Renderer {
|
|||||||
is_mouse_over: bool,
|
is_mouse_over: bool,
|
||||||
(label, _): Self::Output,
|
(label, _): Self::Output,
|
||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let (radio_border, radio_box) = (
|
let radio = Primitive::Quad {
|
||||||
Primitive::Quad {
|
|
||||||
bounds,
|
bounds,
|
||||||
background: Background::Color([0.6, 0.6, 0.6].into()),
|
|
||||||
border_radius: (SIZE / 2.0) as u16,
|
|
||||||
},
|
|
||||||
Primitive::Quad {
|
|
||||||
bounds: Rectangle {
|
|
||||||
x: bounds.x + 1.0,
|
|
||||||
y: bounds.y + 1.0,
|
|
||||||
width: bounds.width - 2.0,
|
|
||||||
height: bounds.height - 2.0,
|
|
||||||
},
|
|
||||||
background: Background::Color(
|
background: Background::Color(
|
||||||
if is_mouse_over {
|
if is_mouse_over {
|
||||||
[0.90, 0.90, 0.90]
|
[0.90, 0.90, 0.90]
|
||||||
@ -37,9 +26,10 @@ impl radio::Renderer for Renderer {
|
|||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
border_radius: (SIZE / 2.0 - 1.0) as u16,
|
border_radius: (SIZE / 2.0) as u16,
|
||||||
},
|
border_width: 1,
|
||||||
);
|
border_color: Color::from_rgb(0.6, 0.6, 0.6),
|
||||||
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
Primitive::Group {
|
Primitive::Group {
|
||||||
@ -53,11 +43,13 @@ impl radio::Renderer for Renderer {
|
|||||||
},
|
},
|
||||||
background: Background::Color([0.3, 0.3, 0.3].into()),
|
background: Background::Color([0.3, 0.3, 0.3].into()),
|
||||||
border_radius: (DOT_SIZE / 2.0) as u16,
|
border_radius: (DOT_SIZE / 2.0) as u16,
|
||||||
|
border_width: 0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
vec![radio_border, radio_box, radio_circle, label]
|
vec![radio, radio_circle, label]
|
||||||
} else {
|
} else {
|
||||||
vec![radio_border, radio_box, label]
|
vec![radio, label]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
if is_mouse_over {
|
if is_mouse_over {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use crate::{Primitive, Renderer};
|
use crate::{Primitive, Renderer};
|
||||||
use iced_native::{scrollable, Background, MouseCursor, Rectangle, Vector};
|
use iced_native::{
|
||||||
|
scrollable, Background, Color, MouseCursor, Rectangle, Vector,
|
||||||
|
};
|
||||||
|
|
||||||
const SCROLLBAR_WIDTH: u16 = 10;
|
const SCROLLBAR_WIDTH: u16 = 10;
|
||||||
const SCROLLBAR_MARGIN: u16 = 2;
|
const SCROLLBAR_MARGIN: u16 = 2;
|
||||||
@ -68,6 +70,8 @@ impl scrollable::Renderer for Renderer {
|
|||||||
[0.0, 0.0, 0.0, 0.7].into(),
|
[0.0, 0.0, 0.0, 0.7].into(),
|
||||||
),
|
),
|
||||||
border_radius: 5,
|
border_radius: 5,
|
||||||
|
border_width: 0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_mouse_over_scrollbar || state.is_scroller_grabbed() {
|
if is_mouse_over_scrollbar || state.is_scroller_grabbed() {
|
||||||
@ -83,6 +87,8 @@ impl scrollable::Renderer for Renderer {
|
|||||||
[0.0, 0.0, 0.0, 0.3].into(),
|
[0.0, 0.0, 0.0, 0.3].into(),
|
||||||
),
|
),
|
||||||
border_radius: 5,
|
border_radius: 5,
|
||||||
|
border_width: 0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
Primitive::Group {
|
Primitive::Group {
|
||||||
|
@ -29,8 +29,10 @@ impl slider::Renderer for Renderer {
|
|||||||
width: bounds.width,
|
width: bounds.width,
|
||||||
height: 2.0,
|
height: 2.0,
|
||||||
},
|
},
|
||||||
background: Color::from_rgb(0.6, 0.6, 0.6).into(),
|
background: Background::Color([0.6, 0.6, 0.6, 0.5].into()),
|
||||||
border_radius: 0,
|
border_radius: 0,
|
||||||
|
border_width: 0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
},
|
},
|
||||||
Primitive::Quad {
|
Primitive::Quad {
|
||||||
bounds: Rectangle {
|
bounds: Rectangle {
|
||||||
@ -41,6 +43,8 @@ impl slider::Renderer for Renderer {
|
|||||||
},
|
},
|
||||||
background: Background::Color(Color::WHITE),
|
background: Background::Color(Color::WHITE),
|
||||||
border_radius: 0,
|
border_radius: 0,
|
||||||
|
border_width: 0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -49,18 +53,7 @@ impl slider::Renderer for Renderer {
|
|||||||
let handle_offset = (bounds.width - HANDLE_WIDTH)
|
let handle_offset = (bounds.width - HANDLE_WIDTH)
|
||||||
* ((value - range_start) / (range_end - range_start).max(1.0));
|
* ((value - range_start) / (range_end - range_start).max(1.0));
|
||||||
|
|
||||||
let (handle_border, handle) = (
|
let handle = Primitive::Quad {
|
||||||
Primitive::Quad {
|
|
||||||
bounds: Rectangle {
|
|
||||||
x: bounds.x + handle_offset.round() - 1.0,
|
|
||||||
y: rail_y - HANDLE_HEIGHT / 2.0 - 1.0,
|
|
||||||
width: HANDLE_WIDTH + 2.0,
|
|
||||||
height: HANDLE_HEIGHT + 2.0,
|
|
||||||
},
|
|
||||||
background: Color::from_rgb(0.6, 0.6, 0.6).into(),
|
|
||||||
border_radius: 5,
|
|
||||||
},
|
|
||||||
Primitive::Quad {
|
|
||||||
bounds: Rectangle {
|
bounds: Rectangle {
|
||||||
x: bounds.x + handle_offset.round(),
|
x: bounds.x + handle_offset.round(),
|
||||||
y: rail_y - HANDLE_HEIGHT / 2.0,
|
y: rail_y - HANDLE_HEIGHT / 2.0,
|
||||||
@ -78,12 +71,13 @@ impl slider::Renderer for Renderer {
|
|||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
border_radius: 4,
|
border_radius: 4,
|
||||||
},
|
border_width: 1,
|
||||||
);
|
border_color: Color::from_rgb(0.6, 0.6, 0.6),
|
||||||
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
Primitive::Group {
|
Primitive::Group {
|
||||||
primitives: vec![rail_top, rail_bottom, handle_border, handle],
|
primitives: vec![rail_top, rail_bottom, handle],
|
||||||
},
|
},
|
||||||
if is_dragging {
|
if is_dragging {
|
||||||
MouseCursor::Grabbing
|
MouseCursor::Grabbing
|
||||||
|
@ -64,28 +64,17 @@ impl text_input::Renderer for Renderer {
|
|||||||
) -> Self::Output {
|
) -> Self::Output {
|
||||||
let is_mouse_over = bounds.contains(cursor_position);
|
let is_mouse_over = bounds.contains(cursor_position);
|
||||||
|
|
||||||
let border = Primitive::Quad {
|
let input = Primitive::Quad {
|
||||||
bounds,
|
bounds,
|
||||||
background: Background::Color(
|
background: Background::Color(Color::WHITE),
|
||||||
if is_mouse_over || state.is_focused() {
|
border_radius: 5,
|
||||||
|
border_width: 1,
|
||||||
|
border_color: if is_mouse_over || state.is_focused() {
|
||||||
[0.5, 0.5, 0.5]
|
[0.5, 0.5, 0.5]
|
||||||
} else {
|
} else {
|
||||||
[0.7, 0.7, 0.7]
|
[0.7, 0.7, 0.7]
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
),
|
|
||||||
border_radius: 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
let input = Primitive::Quad {
|
|
||||||
bounds: Rectangle {
|
|
||||||
x: bounds.x + 1.0,
|
|
||||||
y: bounds.y + 1.0,
|
|
||||||
width: bounds.width - 2.0,
|
|
||||||
height: bounds.height - 2.0,
|
|
||||||
},
|
|
||||||
background: Background::Color(Color::WHITE),
|
|
||||||
border_radius: 4,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let text = value.to_string();
|
let text = value.to_string();
|
||||||
@ -130,6 +119,8 @@ impl text_input::Renderer for Renderer {
|
|||||||
},
|
},
|
||||||
background: Background::Color(Color::BLACK),
|
background: Background::Color(Color::BLACK),
|
||||||
border_radius: 0,
|
border_radius: 0,
|
||||||
|
border_width: 0,
|
||||||
|
border_color: Color::TRANSPARENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
@ -150,7 +141,7 @@ impl text_input::Renderer for Renderer {
|
|||||||
|
|
||||||
(
|
(
|
||||||
Primitive::Group {
|
Primitive::Group {
|
||||||
primitives: vec![border, input, contents],
|
primitives: vec![input, contents],
|
||||||
},
|
},
|
||||||
if is_mouse_over {
|
if is_mouse_over {
|
||||||
MouseCursor::Text
|
MouseCursor::Text
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout(location = 0) in vec4 v_Color;
|
layout(location = 0) in vec4 v_Color;
|
||||||
layout(location = 1) in vec2 v_Pos;
|
layout(location = 1) in vec4 v_BorderColor;
|
||||||
layout(location = 2) in vec2 v_Scale;
|
layout(location = 2) in vec2 v_Pos;
|
||||||
layout(location = 3) in float v_BorderRadius;
|
layout(location = 3) in vec2 v_Scale;
|
||||||
|
layout(location = 4) in float v_BorderRadius;
|
||||||
|
layout(location = 5) in float v_BorderWidth;
|
||||||
|
|
||||||
layout(location = 0) out vec4 o_Color;
|
layout(location = 0) out vec4 o_Color;
|
||||||
|
|
||||||
float rounded(in vec2 frag_coord, in vec2 position, in vec2 size, float radius, float s)
|
float distance(in vec2 frag_coord, in vec2 position, in vec2 size, float radius)
|
||||||
{
|
{
|
||||||
|
// TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN
|
||||||
vec2 inner_size = size - vec2(radius, radius) * 2.0;
|
vec2 inner_size = size - vec2(radius, radius) * 2.0;
|
||||||
vec2 top_left = position + vec2(radius, radius);
|
vec2 top_left = position + vec2(radius, radius);
|
||||||
vec2 bottom_right = top_left + inner_size;
|
vec2 bottom_right = top_left + inner_size;
|
||||||
@ -21,13 +24,43 @@ float rounded(in vec2 frag_coord, in vec2 position, in vec2 size, float radius,
|
|||||||
max(max(top_left_distance.y, bottom_right_distance.y), 0)
|
max(max(top_left_distance.y, bottom_right_distance.y), 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
float d = sqrt(distance.x * distance.x + distance.y * distance.y);
|
return sqrt(distance.x * distance.x + distance.y * distance.y);
|
||||||
|
|
||||||
return 1.0 - smoothstep(radius - s, radius + s, d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float radius_alpha = rounded(gl_FragCoord.xy, v_Pos, v_Scale, v_BorderRadius, 0.5);
|
vec4 mixed_color;
|
||||||
|
|
||||||
o_Color = vec4(v_Color.xyz, v_Color.w * radius_alpha);
|
// TODO: Remove branching (?)
|
||||||
|
if(v_BorderWidth > 0) {
|
||||||
|
float internal_border = max(v_BorderRadius - v_BorderWidth, 0);
|
||||||
|
|
||||||
|
float internal_distance = distance(
|
||||||
|
gl_FragCoord.xy,
|
||||||
|
v_Pos + vec2(v_BorderWidth),
|
||||||
|
v_Scale - vec2(v_BorderWidth * 2.0),
|
||||||
|
internal_border
|
||||||
|
);
|
||||||
|
|
||||||
|
float border_mix = smoothstep(
|
||||||
|
max(internal_border - 0.5, 0.0),
|
||||||
|
internal_border + 0.5,
|
||||||
|
internal_distance
|
||||||
|
);
|
||||||
|
|
||||||
|
mixed_color = mix(v_Color, v_BorderColor, border_mix);
|
||||||
|
} else {
|
||||||
|
mixed_color = v_Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
float d = distance(
|
||||||
|
gl_FragCoord.xy,
|
||||||
|
v_Pos,
|
||||||
|
v_Scale,
|
||||||
|
v_BorderRadius
|
||||||
|
);
|
||||||
|
|
||||||
|
float radius_alpha =
|
||||||
|
1.0 - smoothstep(max(v_BorderRadius - 0.5, 0), v_BorderRadius + 0.5, d);
|
||||||
|
|
||||||
|
o_Color = vec4(mixed_color.xyz, mixed_color.w * radius_alpha);
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -4,7 +4,9 @@ layout(location = 0) in vec2 v_Pos;
|
|||||||
layout(location = 1) in vec2 i_Pos;
|
layout(location = 1) in vec2 i_Pos;
|
||||||
layout(location = 2) in vec2 i_Scale;
|
layout(location = 2) in vec2 i_Scale;
|
||||||
layout(location = 3) in vec4 i_Color;
|
layout(location = 3) in vec4 i_Color;
|
||||||
layout(location = 4) in float i_BorderRadius;
|
layout(location = 4) in vec4 i_BorderColor;
|
||||||
|
layout(location = 5) in float i_BorderRadius;
|
||||||
|
layout(location = 6) in float i_BorderWidth;
|
||||||
|
|
||||||
layout (set = 0, binding = 0) uniform Globals {
|
layout (set = 0, binding = 0) uniform Globals {
|
||||||
mat4 u_Transform;
|
mat4 u_Transform;
|
||||||
@ -12,9 +14,11 @@ layout (set = 0, binding = 0) uniform Globals {
|
|||||||
};
|
};
|
||||||
|
|
||||||
layout(location = 0) out vec4 o_Color;
|
layout(location = 0) out vec4 o_Color;
|
||||||
layout(location = 1) out vec2 o_Pos;
|
layout(location = 1) out vec4 o_BorderColor;
|
||||||
layout(location = 2) out vec2 o_Scale;
|
layout(location = 2) out vec2 o_Pos;
|
||||||
layout(location = 3) out float o_BorderRadius;
|
layout(location = 3) out vec2 o_Scale;
|
||||||
|
layout(location = 4) out float o_BorderRadius;
|
||||||
|
layout(location = 5) out float o_BorderWidth;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 p_Pos = i_Pos * u_Scale;
|
vec2 p_Pos = i_Pos * u_Scale;
|
||||||
@ -28,9 +32,11 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
o_Color = i_Color;
|
o_Color = i_Color;
|
||||||
|
o_BorderColor = i_BorderColor;
|
||||||
o_Pos = p_Pos;
|
o_Pos = p_Pos;
|
||||||
o_Scale = p_Scale;
|
o_Scale = p_Scale;
|
||||||
o_BorderRadius = i_BorderRadius * u_Scale;
|
o_BorderRadius = i_BorderRadius * u_Scale;
|
||||||
|
o_BorderWidth = i_BorderWidth * u_Scale;
|
||||||
|
|
||||||
gl_Position = u_Transform * i_Transform * vec4(v_Pos, 0.0, 1.0);
|
gl_Position = u_Transform * i_Transform * vec4(v_Pos, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user