Decouple Mesh primitives from main Primitive type
This commit is contained in:
parent
2128472c2a
commit
fa5650cfd1
15 changed files with 248 additions and 205 deletions
|
|
@ -2,7 +2,6 @@
|
||||||
//! arbitrary low-level geometry.
|
//! arbitrary low-level geometry.
|
||||||
mod rainbow {
|
mod rainbow {
|
||||||
use iced::advanced::graphics::color;
|
use iced::advanced::graphics::color;
|
||||||
use iced::advanced::graphics::primitive::{ColoredVertex2D, Primitive};
|
|
||||||
use iced::advanced::layout::{self, Layout};
|
use iced::advanced::layout::{self, Layout};
|
||||||
use iced::advanced::renderer;
|
use iced::advanced::renderer;
|
||||||
use iced::advanced::widget::{self, Widget};
|
use iced::advanced::widget::{self, Widget};
|
||||||
|
|
@ -45,7 +44,7 @@ mod rainbow {
|
||||||
cursor: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
_viewport: &Rectangle,
|
_viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
use iced::advanced::graphics::primitive::Mesh2D;
|
use iced::advanced::graphics::mesh::{self, Mesh, SolidVertex2D};
|
||||||
use iced::advanced::Renderer as _;
|
use iced::advanced::Renderer as _;
|
||||||
|
|
||||||
let bounds = layout.bounds();
|
let bounds = layout.bounds();
|
||||||
|
|
@ -77,43 +76,43 @@ mod rainbow {
|
||||||
let posn_bl = [0.0, bounds.height];
|
let posn_bl = [0.0, bounds.height];
|
||||||
let posn_l = [0.0, bounds.height / 2.0];
|
let posn_l = [0.0, bounds.height / 2.0];
|
||||||
|
|
||||||
let mesh = Primitive::SolidMesh {
|
let mesh = Mesh::Solid {
|
||||||
size: bounds.size(),
|
size: bounds.size(),
|
||||||
buffers: Mesh2D {
|
buffers: mesh::Indexed {
|
||||||
vertices: vec![
|
vertices: vec![
|
||||||
ColoredVertex2D {
|
SolidVertex2D {
|
||||||
position: posn_center,
|
position: posn_center,
|
||||||
color: color::pack([1.0, 1.0, 1.0, 1.0]),
|
color: color::pack([1.0, 1.0, 1.0, 1.0]),
|
||||||
},
|
},
|
||||||
ColoredVertex2D {
|
SolidVertex2D {
|
||||||
position: posn_tl,
|
position: posn_tl,
|
||||||
color: color::pack(color_r),
|
color: color::pack(color_r),
|
||||||
},
|
},
|
||||||
ColoredVertex2D {
|
SolidVertex2D {
|
||||||
position: posn_t,
|
position: posn_t,
|
||||||
color: color::pack(color_o),
|
color: color::pack(color_o),
|
||||||
},
|
},
|
||||||
ColoredVertex2D {
|
SolidVertex2D {
|
||||||
position: posn_tr,
|
position: posn_tr,
|
||||||
color: color::pack(color_y),
|
color: color::pack(color_y),
|
||||||
},
|
},
|
||||||
ColoredVertex2D {
|
SolidVertex2D {
|
||||||
position: posn_r,
|
position: posn_r,
|
||||||
color: color::pack(color_g),
|
color: color::pack(color_g),
|
||||||
},
|
},
|
||||||
ColoredVertex2D {
|
SolidVertex2D {
|
||||||
position: posn_br,
|
position: posn_br,
|
||||||
color: color::pack(color_gb),
|
color: color::pack(color_gb),
|
||||||
},
|
},
|
||||||
ColoredVertex2D {
|
SolidVertex2D {
|
||||||
position: posn_b,
|
position: posn_b,
|
||||||
color: color::pack(color_b),
|
color: color::pack(color_b),
|
||||||
},
|
},
|
||||||
ColoredVertex2D {
|
SolidVertex2D {
|
||||||
position: posn_bl,
|
position: posn_bl,
|
||||||
color: color::pack(color_i),
|
color: color::pack(color_i),
|
||||||
},
|
},
|
||||||
ColoredVertex2D {
|
SolidVertex2D {
|
||||||
position: posn_l,
|
position: posn_l,
|
||||||
color: color::pack(color_v),
|
color: color::pack(color_v),
|
||||||
},
|
},
|
||||||
|
|
@ -134,7 +133,7 @@ mod rainbow {
|
||||||
renderer.with_translation(
|
renderer.with_translation(
|
||||||
Vector::new(bounds.x, bounds.y),
|
Vector::new(bounds.x, bounds.y),
|
||||||
|renderer| {
|
|renderer| {
|
||||||
renderer.draw_with_wgpu(mesh);
|
renderer.draw_mesh(mesh);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,6 @@ impl<T: Damage> Damage for Primitive<T> {
|
||||||
| Self::Image { bounds, .. }
|
| Self::Image { bounds, .. }
|
||||||
| Self::Svg { bounds, .. } => bounds.expand(1.0),
|
| Self::Svg { bounds, .. } => bounds.expand(1.0),
|
||||||
Self::Clip { bounds, .. } => bounds.expand(1.0),
|
Self::Clip { bounds, .. } => bounds.expand(1.0),
|
||||||
Self::SolidMesh { size, .. } | Self::GradientMesh { size, .. } => {
|
|
||||||
Rectangle::with_size(*size)
|
|
||||||
}
|
|
||||||
Self::Group { primitives } => primitives
|
Self::Group { primitives } => primitives
|
||||||
.iter()
|
.iter()
|
||||||
.map(Self::bounds)
|
.map(Self::bounds)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use crate::color;
|
||||||
use crate::core::gradient::ColorStop;
|
use crate::core::gradient::ColorStop;
|
||||||
use crate::core::{self, Color, Point, Rectangle};
|
use crate::core::{self, Color, Point, Rectangle};
|
||||||
|
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
use half::f16;
|
use half::f16;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
|
@ -135,7 +136,7 @@ impl Linear {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Packed [`Gradient`] data for use in shader code.
|
/// Packed [`Gradient`] data for use in shader code.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Zeroable, Pod)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Packed {
|
pub struct Packed {
|
||||||
// 8 colors, each channel = 16 bit float, 2 colors packed into 1 u32
|
// 8 colors, each channel = 16 bit float, 2 colors packed into 1 u32
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ pub mod color;
|
||||||
pub mod compositor;
|
pub mod compositor;
|
||||||
pub mod damage;
|
pub mod damage;
|
||||||
pub mod gradient;
|
pub mod gradient;
|
||||||
|
pub mod mesh;
|
||||||
pub mod primitive;
|
pub mod primitive;
|
||||||
pub mod renderer;
|
pub mod renderer;
|
||||||
|
|
||||||
|
|
@ -46,6 +47,7 @@ pub use compositor::Compositor;
|
||||||
pub use damage::Damage;
|
pub use damage::Damage;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use gradient::Gradient;
|
pub use gradient::Gradient;
|
||||||
|
pub use mesh::Mesh;
|
||||||
pub use primitive::Primitive;
|
pub use primitive::Primitive;
|
||||||
pub use renderer::Renderer;
|
pub use renderer::Renderer;
|
||||||
pub use transformation::Transformation;
|
pub use transformation::Transformation;
|
||||||
|
|
|
||||||
75
graphics/src/mesh.rs
Normal file
75
graphics/src/mesh.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
use crate::color;
|
||||||
|
use crate::core::{Rectangle, Size};
|
||||||
|
use crate::gradient;
|
||||||
|
use crate::Damage;
|
||||||
|
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
|
||||||
|
/// A low-level primitive to render a mesh of triangles.
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum Mesh {
|
||||||
|
/// A mesh with a solid color.
|
||||||
|
Solid {
|
||||||
|
/// The vertices and indices of the mesh.
|
||||||
|
buffers: Indexed<SolidVertex2D>,
|
||||||
|
|
||||||
|
/// The size of the drawable region of the mesh.
|
||||||
|
///
|
||||||
|
/// Any geometry that falls out of this region will be clipped.
|
||||||
|
size: Size,
|
||||||
|
},
|
||||||
|
/// A mesh with a gradient.
|
||||||
|
Gradient {
|
||||||
|
/// The vertices and indices of the mesh.
|
||||||
|
buffers: Indexed<GradientVertex2D>,
|
||||||
|
|
||||||
|
/// The size of the drawable region of the mesh.
|
||||||
|
///
|
||||||
|
/// Any geometry that falls out of this region will be clipped.
|
||||||
|
size: Size,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Damage for Mesh {
|
||||||
|
fn bounds(&self) -> Rectangle {
|
||||||
|
match self {
|
||||||
|
Self::Solid { size, .. } | Self::Gradient { size, .. } => {
|
||||||
|
Rectangle::with_size(*size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A set of [`Vertex2D`] and indices representing a list of triangles.
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct Indexed<T> {
|
||||||
|
/// The vertices of the mesh
|
||||||
|
pub vertices: Vec<T>,
|
||||||
|
|
||||||
|
/// The list of vertex indices that defines the triangles of the mesh.
|
||||||
|
///
|
||||||
|
/// Therefore, this list should always have a length that is a multiple of 3.
|
||||||
|
pub indices: Vec<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A two-dimensional vertex with a color.
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct SolidVertex2D {
|
||||||
|
/// The vertex position in 2D space.
|
||||||
|
pub position: [f32; 2],
|
||||||
|
|
||||||
|
/// The color of the vertex in __linear__ RGBA.
|
||||||
|
pub color: color::Packed,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A vertex which contains 2D position & packed gradient data.
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct GradientVertex2D {
|
||||||
|
/// The vertex position in 2D space.
|
||||||
|
pub position: [f32; 2],
|
||||||
|
|
||||||
|
/// The packed vertex data of the gradient.
|
||||||
|
pub gradient: gradient::Packed,
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
//! Draw using different graphical primitives.
|
//! Draw using different graphical primitives.
|
||||||
use crate::color;
|
|
||||||
use crate::core::alignment;
|
use crate::core::alignment;
|
||||||
use crate::core::image;
|
use crate::core::image;
|
||||||
use crate::core::svg;
|
use crate::core::svg;
|
||||||
use crate::core::text;
|
use crate::core::text;
|
||||||
use crate::core::{Background, Color, Font, Rectangle, Size, Vector};
|
use crate::core::{Background, Color, Font, Rectangle, Vector};
|
||||||
use crate::gradient;
|
|
||||||
|
|
||||||
use bytemuck::{Pod, Zeroable};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A rendering primitive.
|
/// A rendering primitive.
|
||||||
|
|
@ -65,30 +62,6 @@ pub enum Primitive<T> {
|
||||||
/// The bounds of the viewport
|
/// The bounds of the viewport
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
},
|
},
|
||||||
/// A low-level primitive to render a mesh of triangles with a solid color.
|
|
||||||
///
|
|
||||||
/// It can be used to render many kinds of geometry freely.
|
|
||||||
SolidMesh {
|
|
||||||
/// The vertices and indices of the mesh.
|
|
||||||
buffers: Mesh2D<ColoredVertex2D>,
|
|
||||||
|
|
||||||
/// The size of the drawable region of the mesh.
|
|
||||||
///
|
|
||||||
/// Any geometry that falls out of this region will be clipped.
|
|
||||||
size: Size,
|
|
||||||
},
|
|
||||||
/// A low-level primitive to render a mesh of triangles with a gradient.
|
|
||||||
///
|
|
||||||
/// It can be used to render many kinds of geometry freely.
|
|
||||||
GradientMesh {
|
|
||||||
/// The vertices and indices of the mesh.
|
|
||||||
buffers: Mesh2D<GradientVertex2D>,
|
|
||||||
|
|
||||||
/// The size of the drawable region of the mesh.
|
|
||||||
///
|
|
||||||
/// Any geometry that falls out of this region will be clipped.
|
|
||||||
size: Size,
|
|
||||||
},
|
|
||||||
/// A group of primitives
|
/// A group of primitives
|
||||||
Group {
|
Group {
|
||||||
/// The primitives of the group
|
/// The primitives of the group
|
||||||
|
|
@ -143,43 +116,3 @@ impl<T> Primitive<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A set of [`Vertex2D`] and indices representing a list of triangles.
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
||||||
pub struct Mesh2D<T> {
|
|
||||||
/// The vertices of the mesh
|
|
||||||
pub vertices: Vec<T>,
|
|
||||||
|
|
||||||
/// The list of vertex indices that defines the triangles of the mesh.
|
|
||||||
///
|
|
||||||
/// Therefore, this list should always have a length that is a multiple of 3.
|
|
||||||
pub indices: Vec<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A two-dimensional vertex with a color.
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct ColoredVertex2D {
|
|
||||||
/// The vertex position in 2D space.
|
|
||||||
pub position: [f32; 2],
|
|
||||||
|
|
||||||
/// The color of the vertex in __linear__ RGBA.
|
|
||||||
pub color: color::Packed,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A vertex which contains 2D position & packed gradient data.
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct GradientVertex2D {
|
|
||||||
/// The vertex position in 2D space.
|
|
||||||
pub position: [f32; 2],
|
|
||||||
|
|
||||||
/// The packed vertex data of the gradient.
|
|
||||||
pub gradient: gradient::Packed,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe impl Zeroable for GradientVertex2D {}
|
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
unsafe impl Pod for GradientVertex2D {}
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ web-colors = ["iced_wgpu?/web-colors"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
raw-window-handle = "0.5"
|
raw-window-handle = "0.5"
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
|
log = "0.4"
|
||||||
|
|
||||||
[dependencies.iced_graphics]
|
[dependencies.iced_graphics]
|
||||||
version = "0.8"
|
version = "0.8"
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ pub use geometry::Geometry;
|
||||||
use crate::core::renderer;
|
use crate::core::renderer;
|
||||||
use crate::core::text::{self, Text};
|
use crate::core::text::{self, Text};
|
||||||
use crate::core::{Background, Font, Point, Rectangle, Size, Vector};
|
use crate::core::{Background, Font, Point, Rectangle, Size, Vector};
|
||||||
|
use crate::graphics::Mesh;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
|
@ -40,10 +41,17 @@ macro_rules! delegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Renderer<T> {
|
impl<T> Renderer<T> {
|
||||||
#[cfg(feature = "wgpu")]
|
pub fn draw_mesh(&mut self, mesh: Mesh) {
|
||||||
pub fn draw_with_wgpu(&mut self, primitive: iced_wgpu::Primitive) {
|
match self {
|
||||||
if let Self::Wgpu(renderer) = self {
|
Self::TinySkia(_) => {
|
||||||
renderer.draw_primitive(primitive);
|
log::warn!("Unsupported mesh primitive: {:?}", mesh)
|
||||||
|
}
|
||||||
|
#[cfg(feature = "wgpu")]
|
||||||
|
Self::Wgpu(renderer) => {
|
||||||
|
renderer.draw_primitive(iced_wgpu::Primitive::Custom(
|
||||||
|
iced_wgpu::primitive::Custom::Mesh(mesh),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -595,14 +595,6 @@ impl Backend {
|
||||||
translation,
|
translation,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Primitive::SolidMesh { .. } | Primitive::GradientMesh { .. } => {
|
|
||||||
// Not supported!
|
|
||||||
// TODO: Draw a placeholder (?)
|
|
||||||
log::warn!(
|
|
||||||
"Unsupported primitive in `iced_tiny_skia`: {:?}",
|
|
||||||
primitive
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ use crate::graphics::geometry::{
|
||||||
LineCap, LineDash, LineJoin, Path, Stroke, Style, Text,
|
LineCap, LineDash, LineJoin, Path, Stroke, Style, Text,
|
||||||
};
|
};
|
||||||
use crate::graphics::gradient::{self, Gradient};
|
use crate::graphics::gradient::{self, Gradient};
|
||||||
use crate::graphics::primitive;
|
use crate::graphics::mesh::{self, Mesh};
|
||||||
use crate::Primitive;
|
use crate::primitive::{self, Primitive};
|
||||||
|
|
||||||
use lyon::geom::euclid;
|
use lyon::geom::euclid;
|
||||||
use lyon::tessellation;
|
use lyon::tessellation;
|
||||||
|
|
@ -25,8 +25,8 @@ pub struct Frame {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Buffer {
|
enum Buffer {
|
||||||
Solid(tessellation::VertexBuffers<primitive::ColoredVertex2D, u32>),
|
Solid(tessellation::VertexBuffers<mesh::SolidVertex2D, u32>),
|
||||||
Gradient(tessellation::VertexBuffers<primitive::GradientVertex2D, u32>),
|
Gradient(tessellation::VertexBuffers<mesh::GradientVertex2D, u32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BufferStack {
|
struct BufferStack {
|
||||||
|
|
@ -464,24 +464,28 @@ impl Frame {
|
||||||
match buffer {
|
match buffer {
|
||||||
Buffer::Solid(buffer) => {
|
Buffer::Solid(buffer) => {
|
||||||
if !buffer.indices.is_empty() {
|
if !buffer.indices.is_empty() {
|
||||||
self.primitives.push(Primitive::SolidMesh {
|
self.primitives.push(Primitive::Custom(
|
||||||
buffers: primitive::Mesh2D {
|
primitive::Custom::Mesh(Mesh::Solid {
|
||||||
vertices: buffer.vertices,
|
buffers: mesh::Indexed {
|
||||||
indices: buffer.indices,
|
vertices: buffer.vertices,
|
||||||
},
|
indices: buffer.indices,
|
||||||
size: self.size,
|
},
|
||||||
})
|
size: self.size,
|
||||||
|
}),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Buffer::Gradient(buffer) => {
|
Buffer::Gradient(buffer) => {
|
||||||
if !buffer.indices.is_empty() {
|
if !buffer.indices.is_empty() {
|
||||||
self.primitives.push(Primitive::GradientMesh {
|
self.primitives.push(Primitive::Custom(
|
||||||
buffers: primitive::Mesh2D {
|
primitive::Custom::Mesh(Mesh::Gradient {
|
||||||
vertices: buffer.vertices,
|
buffers: mesh::Indexed {
|
||||||
indices: buffer.indices,
|
vertices: buffer.vertices,
|
||||||
},
|
indices: buffer.indices,
|
||||||
size: self.size,
|
},
|
||||||
})
|
size: self.size,
|
||||||
|
}),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -495,32 +499,32 @@ struct GradientVertex2DBuilder {
|
||||||
gradient: gradient::Packed,
|
gradient: gradient::Packed,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl tessellation::FillVertexConstructor<primitive::GradientVertex2D>
|
impl tessellation::FillVertexConstructor<mesh::GradientVertex2D>
|
||||||
for GradientVertex2DBuilder
|
for GradientVertex2DBuilder
|
||||||
{
|
{
|
||||||
fn new_vertex(
|
fn new_vertex(
|
||||||
&mut self,
|
&mut self,
|
||||||
vertex: tessellation::FillVertex<'_>,
|
vertex: tessellation::FillVertex<'_>,
|
||||||
) -> primitive::GradientVertex2D {
|
) -> mesh::GradientVertex2D {
|
||||||
let position = vertex.position();
|
let position = vertex.position();
|
||||||
|
|
||||||
primitive::GradientVertex2D {
|
mesh::GradientVertex2D {
|
||||||
position: [position.x, position.y],
|
position: [position.x, position.y],
|
||||||
gradient: self.gradient,
|
gradient: self.gradient,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl tessellation::StrokeVertexConstructor<primitive::GradientVertex2D>
|
impl tessellation::StrokeVertexConstructor<mesh::GradientVertex2D>
|
||||||
for GradientVertex2DBuilder
|
for GradientVertex2DBuilder
|
||||||
{
|
{
|
||||||
fn new_vertex(
|
fn new_vertex(
|
||||||
&mut self,
|
&mut self,
|
||||||
vertex: tessellation::StrokeVertex<'_, '_>,
|
vertex: tessellation::StrokeVertex<'_, '_>,
|
||||||
) -> primitive::GradientVertex2D {
|
) -> mesh::GradientVertex2D {
|
||||||
let position = vertex.position();
|
let position = vertex.position();
|
||||||
|
|
||||||
primitive::GradientVertex2D {
|
mesh::GradientVertex2D {
|
||||||
position: [position.x, position.y],
|
position: [position.x, position.y],
|
||||||
gradient: self.gradient,
|
gradient: self.gradient,
|
||||||
}
|
}
|
||||||
|
|
@ -529,32 +533,32 @@ impl tessellation::StrokeVertexConstructor<primitive::GradientVertex2D>
|
||||||
|
|
||||||
struct TriangleVertex2DBuilder(color::Packed);
|
struct TriangleVertex2DBuilder(color::Packed);
|
||||||
|
|
||||||
impl tessellation::FillVertexConstructor<primitive::ColoredVertex2D>
|
impl tessellation::FillVertexConstructor<mesh::SolidVertex2D>
|
||||||
for TriangleVertex2DBuilder
|
for TriangleVertex2DBuilder
|
||||||
{
|
{
|
||||||
fn new_vertex(
|
fn new_vertex(
|
||||||
&mut self,
|
&mut self,
|
||||||
vertex: tessellation::FillVertex<'_>,
|
vertex: tessellation::FillVertex<'_>,
|
||||||
) -> primitive::ColoredVertex2D {
|
) -> mesh::SolidVertex2D {
|
||||||
let position = vertex.position();
|
let position = vertex.position();
|
||||||
|
|
||||||
primitive::ColoredVertex2D {
|
mesh::SolidVertex2D {
|
||||||
position: [position.x, position.y],
|
position: [position.x, position.y],
|
||||||
color: self.0,
|
color: self.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl tessellation::StrokeVertexConstructor<primitive::ColoredVertex2D>
|
impl tessellation::StrokeVertexConstructor<mesh::SolidVertex2D>
|
||||||
for TriangleVertex2DBuilder
|
for TriangleVertex2DBuilder
|
||||||
{
|
{
|
||||||
fn new_vertex(
|
fn new_vertex(
|
||||||
&mut self,
|
&mut self,
|
||||||
vertex: tessellation::StrokeVertex<'_, '_>,
|
vertex: tessellation::StrokeVertex<'_, '_>,
|
||||||
) -> primitive::ColoredVertex2D {
|
) -> mesh::SolidVertex2D {
|
||||||
let position = vertex.position();
|
let position = vertex.position();
|
||||||
|
|
||||||
primitive::ColoredVertex2D {
|
mesh::SolidVertex2D {
|
||||||
position: [position.x, position.y],
|
position: [position.x, position.y],
|
||||||
color: self.0,
|
color: self.0,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,11 @@ pub use text::Text;
|
||||||
use crate::core;
|
use crate::core;
|
||||||
use crate::core::alignment;
|
use crate::core::alignment;
|
||||||
use crate::core::{Color, Font, Point, Rectangle, Size, Vector};
|
use crate::core::{Color, Font, Point, Rectangle, Size, Vector};
|
||||||
|
use crate::graphics;
|
||||||
use crate::graphics::color;
|
use crate::graphics::color;
|
||||||
use crate::graphics::Viewport;
|
use crate::graphics::Viewport;
|
||||||
|
use crate::primitive::{self, Primitive};
|
||||||
use crate::quad::{self, Quad};
|
use crate::quad::{self, Quad};
|
||||||
use crate::Primitive;
|
|
||||||
|
|
||||||
/// A group of primitives that should be clipped together.
|
/// A group of primitives that should be clipped together.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -180,40 +181,6 @@ impl<'a> Layer<'a> {
|
||||||
bounds: *bounds + translation,
|
bounds: *bounds + translation,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Primitive::SolidMesh { buffers, size } => {
|
|
||||||
let layer = &mut layers[current_layer];
|
|
||||||
|
|
||||||
let bounds = Rectangle::new(
|
|
||||||
Point::new(translation.x, translation.y),
|
|
||||||
*size,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Only draw visible content
|
|
||||||
if let Some(clip_bounds) = layer.bounds.intersection(&bounds) {
|
|
||||||
layer.meshes.push(Mesh::Solid {
|
|
||||||
origin: Point::new(translation.x, translation.y),
|
|
||||||
buffers,
|
|
||||||
clip_bounds,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Primitive::GradientMesh { buffers, size } => {
|
|
||||||
let layer = &mut layers[current_layer];
|
|
||||||
|
|
||||||
let bounds = Rectangle::new(
|
|
||||||
Point::new(translation.x, translation.y),
|
|
||||||
*size,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Only draw visible content
|
|
||||||
if let Some(clip_bounds) = layer.bounds.intersection(&bounds) {
|
|
||||||
layer.meshes.push(Mesh::Gradient {
|
|
||||||
origin: Point::new(translation.x, translation.y),
|
|
||||||
buffers,
|
|
||||||
clip_bounds,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Primitive::Group { primitives } => {
|
Primitive::Group { primitives } => {
|
||||||
// TODO: Inspect a bit and regroup (?)
|
// TODO: Inspect a bit and regroup (?)
|
||||||
for primitive in primitives {
|
for primitive in primitives {
|
||||||
|
|
@ -263,7 +230,54 @@ impl<'a> Layer<'a> {
|
||||||
current_layer,
|
current_layer,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Primitive::Custom(()) => {}
|
Primitive::Custom(custom) => match custom {
|
||||||
|
primitive::Custom::Mesh(mesh) => match mesh {
|
||||||
|
graphics::Mesh::Solid { buffers, size } => {
|
||||||
|
let layer = &mut layers[current_layer];
|
||||||
|
|
||||||
|
let bounds = Rectangle::new(
|
||||||
|
Point::new(translation.x, translation.y),
|
||||||
|
*size,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Only draw visible content
|
||||||
|
if let Some(clip_bounds) =
|
||||||
|
layer.bounds.intersection(&bounds)
|
||||||
|
{
|
||||||
|
layer.meshes.push(Mesh::Solid {
|
||||||
|
origin: Point::new(
|
||||||
|
translation.x,
|
||||||
|
translation.y,
|
||||||
|
),
|
||||||
|
buffers,
|
||||||
|
clip_bounds,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
graphics::Mesh::Gradient { buffers, size } => {
|
||||||
|
let layer = &mut layers[current_layer];
|
||||||
|
|
||||||
|
let bounds = Rectangle::new(
|
||||||
|
Point::new(translation.x, translation.y),
|
||||||
|
*size,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Only draw visible content
|
||||||
|
if let Some(clip_bounds) =
|
||||||
|
layer.bounds.intersection(&bounds)
|
||||||
|
{
|
||||||
|
layer.meshes.push(Mesh::Gradient {
|
||||||
|
origin: Point::new(
|
||||||
|
translation.x,
|
||||||
|
translation.y,
|
||||||
|
),
|
||||||
|
buffers,
|
||||||
|
clip_bounds,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
//! A collection of triangle primitives.
|
//! A collection of triangle primitives.
|
||||||
use crate::core::{Point, Rectangle};
|
use crate::core::{Point, Rectangle};
|
||||||
use crate::graphics::primitive;
|
use crate::graphics::mesh;
|
||||||
|
|
||||||
/// A mesh of triangles.
|
/// A mesh of triangles.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
@ -11,7 +11,7 @@ pub enum Mesh<'a> {
|
||||||
origin: Point,
|
origin: Point,
|
||||||
|
|
||||||
/// The vertex and index buffers of the [`Mesh`].
|
/// The vertex and index buffers of the [`Mesh`].
|
||||||
buffers: &'a primitive::Mesh2D<primitive::ColoredVertex2D>,
|
buffers: &'a mesh::Indexed<mesh::SolidVertex2D>,
|
||||||
|
|
||||||
/// The clipping bounds of the [`Mesh`].
|
/// The clipping bounds of the [`Mesh`].
|
||||||
clip_bounds: Rectangle<f32>,
|
clip_bounds: Rectangle<f32>,
|
||||||
|
|
@ -22,7 +22,7 @@ pub enum Mesh<'a> {
|
||||||
origin: Point,
|
origin: Point,
|
||||||
|
|
||||||
/// The vertex and index buffers of the [`Mesh`].
|
/// The vertex and index buffers of the [`Mesh`].
|
||||||
buffers: &'a primitive::Mesh2D<primitive::GradientVertex2D>,
|
buffers: &'a mesh::Indexed<mesh::GradientVertex2D>,
|
||||||
|
|
||||||
/// The clipping bounds of the [`Mesh`].
|
/// The clipping bounds of the [`Mesh`].
|
||||||
clip_bounds: Rectangle<f32>,
|
clip_bounds: Rectangle<f32>,
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
#![allow(clippy::inherent_to_string, clippy::type_complexity)]
|
#![allow(clippy::inherent_to_string, clippy::type_complexity)]
|
||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||||
pub mod layer;
|
pub mod layer;
|
||||||
|
pub mod primitive;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
|
|
||||||
|
|
@ -47,7 +48,6 @@ pub mod geometry;
|
||||||
mod backend;
|
mod backend;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod color;
|
mod color;
|
||||||
mod primitive;
|
|
||||||
mod quad;
|
mod quad;
|
||||||
mod text;
|
mod text;
|
||||||
mod triangle;
|
mod triangle;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,17 @@
|
||||||
|
use crate::core::Rectangle;
|
||||||
|
use crate::graphics::{Damage, Mesh};
|
||||||
|
|
||||||
pub type Primitive = crate::graphics::Primitive<Custom>;
|
pub type Primitive = crate::graphics::Primitive<Custom>;
|
||||||
|
|
||||||
pub type Custom = ();
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum Custom {
|
||||||
|
Mesh(Mesh),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Damage for Custom {
|
||||||
|
fn bounds(&self) -> Rectangle {
|
||||||
|
match self {
|
||||||
|
Self::Mesh(mesh) => mesh.bounds(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -393,7 +393,7 @@ impl Uniforms {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod solid {
|
mod solid {
|
||||||
use crate::graphics::primitive;
|
use crate::graphics::mesh;
|
||||||
use crate::graphics::Antialiasing;
|
use crate::graphics::Antialiasing;
|
||||||
use crate::triangle;
|
use crate::triangle;
|
||||||
use crate::Buffer;
|
use crate::Buffer;
|
||||||
|
|
@ -406,7 +406,7 @@ mod solid {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Layer {
|
pub struct Layer {
|
||||||
pub vertices: Buffer<primitive::ColoredVertex2D>,
|
pub vertices: Buffer<mesh::SolidVertex2D>,
|
||||||
pub uniforms: Buffer<triangle::Uniforms>,
|
pub uniforms: Buffer<triangle::Uniforms>,
|
||||||
pub constants: wgpu::BindGroup,
|
pub constants: wgpu::BindGroup,
|
||||||
}
|
}
|
||||||
|
|
@ -493,38 +493,40 @@ mod solid {
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
let pipeline = device.create_render_pipeline(
|
let pipeline =
|
||||||
&wgpu::RenderPipelineDescriptor {
|
device.create_render_pipeline(
|
||||||
label: Some("iced_wgpu::triangle::solid pipeline"),
|
&wgpu::RenderPipelineDescriptor {
|
||||||
layout: Some(&layout),
|
label: Some("iced_wgpu::triangle::solid pipeline"),
|
||||||
vertex: wgpu::VertexState {
|
layout: Some(&layout),
|
||||||
module: &shader,
|
vertex: wgpu::VertexState {
|
||||||
entry_point: "solid_vs_main",
|
module: &shader,
|
||||||
buffers: &[wgpu::VertexBufferLayout {
|
entry_point: "solid_vs_main",
|
||||||
array_stride: std::mem::size_of::<
|
buffers: &[wgpu::VertexBufferLayout {
|
||||||
primitive::ColoredVertex2D,
|
array_stride: std::mem::size_of::<
|
||||||
>()
|
mesh::SolidVertex2D,
|
||||||
as u64,
|
>(
|
||||||
step_mode: wgpu::VertexStepMode::Vertex,
|
)
|
||||||
attributes: &wgpu::vertex_attr_array!(
|
as u64,
|
||||||
// Position
|
step_mode: wgpu::VertexStepMode::Vertex,
|
||||||
0 => Float32x2,
|
attributes: &wgpu::vertex_attr_array!(
|
||||||
// Color
|
// Position
|
||||||
1 => Float32x4,
|
0 => Float32x2,
|
||||||
),
|
// Color
|
||||||
}],
|
1 => Float32x4,
|
||||||
|
),
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: "solid_fs_main",
|
||||||
|
targets: &[triangle::fragment_target(format)],
|
||||||
|
}),
|
||||||
|
primitive: triangle::primitive_state(),
|
||||||
|
depth_stencil: None,
|
||||||
|
multisample: triangle::multisample_state(antialiasing),
|
||||||
|
multiview: None,
|
||||||
},
|
},
|
||||||
fragment: Some(wgpu::FragmentState {
|
);
|
||||||
module: &shader,
|
|
||||||
entry_point: "solid_fs_main",
|
|
||||||
targets: &[triangle::fragment_target(format)],
|
|
||||||
}),
|
|
||||||
primitive: triangle::primitive_state(),
|
|
||||||
depth_stencil: None,
|
|
||||||
multisample: triangle::multisample_state(antialiasing),
|
|
||||||
multiview: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
pipeline,
|
pipeline,
|
||||||
|
|
@ -535,7 +537,8 @@ mod solid {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod gradient {
|
mod gradient {
|
||||||
use crate::graphics::{primitive, Antialiasing};
|
use crate::graphics::mesh;
|
||||||
|
use crate::graphics::Antialiasing;
|
||||||
use crate::triangle;
|
use crate::triangle;
|
||||||
use crate::Buffer;
|
use crate::Buffer;
|
||||||
|
|
||||||
|
|
@ -547,7 +550,7 @@ mod gradient {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Layer {
|
pub struct Layer {
|
||||||
pub vertices: Buffer<primitive::GradientVertex2D>,
|
pub vertices: Buffer<mesh::GradientVertex2D>,
|
||||||
pub uniforms: Buffer<triangle::Uniforms>,
|
pub uniforms: Buffer<triangle::Uniforms>,
|
||||||
pub constants: wgpu::BindGroup,
|
pub constants: wgpu::BindGroup,
|
||||||
}
|
}
|
||||||
|
|
@ -645,7 +648,7 @@ mod gradient {
|
||||||
entry_point: "gradient_vs_main",
|
entry_point: "gradient_vs_main",
|
||||||
buffers: &[wgpu::VertexBufferLayout {
|
buffers: &[wgpu::VertexBufferLayout {
|
||||||
array_stride: std::mem::size_of::<
|
array_stride: std::mem::size_of::<
|
||||||
primitive::GradientVertex2D,
|
mesh::GradientVertex2D,
|
||||||
>()
|
>()
|
||||||
as u64,
|
as u64,
|
||||||
step_mode: wgpu::VertexStepMode::Vertex,
|
step_mode: wgpu::VertexStepMode::Vertex,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue