From 30432cbade3d9b25c4df62656a7494db3f4ea82a Mon Sep 17 00:00:00 2001 From: shan Date: Wed, 5 Oct 2022 10:49:58 -0700 Subject: Readjusted namespaces, removed Geometry example as it's no longer relevant. --- Cargo.toml | 1 - examples/arc/src/main.rs | 4 +- examples/geometry/Cargo.toml | 11 -- examples/geometry/README.md | 18 --- examples/geometry/src/main.rs | 222 ----------------------------------- examples/modern_art/src/main.rs | 9 +- glow/src/triangle.rs | 10 +- graphics/src/gradient.rs | 75 +----------- graphics/src/gradient/linear.rs | 71 +++++++++++ graphics/src/layer.rs | 111 ++---------------- graphics/src/layer/image.rs | 23 ++++ graphics/src/layer/mesh.rs | 39 ++++++ graphics/src/layer/quad.rs | 30 +++++ graphics/src/layer/text.rs | 26 ++++ graphics/src/lib.rs | 1 - graphics/src/primitive.rs | 5 +- graphics/src/shader.rs | 23 ---- graphics/src/widget/canvas.rs | 8 +- graphics/src/widget/canvas/fill.rs | 16 +-- graphics/src/widget/canvas/frame.rs | 32 +++-- graphics/src/widget/canvas/stroke.rs | 10 +- wgpu/src/buffers.rs | 124 ++++++++++++++++++- wgpu/src/buffers/buffer.rs | 124 ------------------- wgpu/src/buffers/dynamic.rs | 201 +++++++++++++++++++++++++++++++ wgpu/src/buffers/dynamic_buffers.rs | 201 ------------------------------- wgpu/src/triangle.rs | 22 ++-- wgpu/src/triangle/gradient.rs | 2 +- wgpu/src/triangle/solid.rs | 2 +- 28 files changed, 595 insertions(+), 826 deletions(-) delete mode 100644 examples/geometry/Cargo.toml delete mode 100644 examples/geometry/README.md delete mode 100644 examples/geometry/src/main.rs create mode 100644 graphics/src/gradient/linear.rs create mode 100644 graphics/src/layer/image.rs create mode 100644 graphics/src/layer/mesh.rs create mode 100644 graphics/src/layer/quad.rs create mode 100644 graphics/src/layer/text.rs delete mode 100644 graphics/src/shader.rs delete mode 100644 wgpu/src/buffers/buffer.rs create mode 100644 wgpu/src/buffers/dynamic.rs delete mode 100644 wgpu/src/buffers/dynamic_buffers.rs diff --git a/Cargo.toml b/Cargo.toml index d8f5eccb..e4754782 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,7 +69,6 @@ members = [ "examples/events", "examples/exit", "examples/game_of_life", - "examples/geometry", "examples/integration_opengl", "examples/integration_wgpu", "examples/modern_art", diff --git a/examples/arc/src/main.rs b/examples/arc/src/main.rs index bc7e49c6..7b6ea0e1 100644 --- a/examples/arc/src/main.rs +++ b/examples/arc/src/main.rs @@ -2,7 +2,7 @@ use std::{f32::consts::PI, time::Instant}; use iced::executor; use iced::widget::canvas::{ - self, Cache, Canvas, Cursor, Geometry, Path, Stroke, Style, + self, stroke, Cache, Canvas, Cursor, Geometry, Path, Stroke, }; use iced::{ Application, Command, Element, Length, Point, Rectangle, Settings, @@ -114,7 +114,7 @@ impl canvas::Program for Arc { frame.stroke( &path, Stroke { - style: Style::Solid(palette.text), + style: stroke::Style::Solid(palette.text), width: 10.0, ..Stroke::default() }, diff --git a/examples/geometry/Cargo.toml b/examples/geometry/Cargo.toml deleted file mode 100644 index 22ede0e0..00000000 --- a/examples/geometry/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "geometry" -version = "0.1.0" -authors = ["Héctor Ramón Jiménez "] -edition = "2021" -publish = false - -[dependencies] -iced = { path = "../.." } -iced_native = { path = "../../native" } -iced_graphics = { path = "../../graphics" } diff --git a/examples/geometry/README.md b/examples/geometry/README.md deleted file mode 100644 index 4d5c81cb..00000000 --- a/examples/geometry/README.md +++ /dev/null @@ -1,18 +0,0 @@ -## Geometry - -A custom widget showcasing how to draw geometry with the `Mesh2D` primitive in [`iced_wgpu`](../../wgpu). - -The __[`main`]__ file contains all the code of the example. - -
- - - -
- -You can run it with `cargo run`: -``` -cargo run --package geometry -``` - -[`main`]: src/main.rs diff --git a/examples/geometry/src/main.rs b/examples/geometry/src/main.rs deleted file mode 100644 index a8ce26f8..00000000 --- a/examples/geometry/src/main.rs +++ /dev/null @@ -1,222 +0,0 @@ -//! This example showcases a simple native custom widget that renders using -//! arbitrary low-level geometry. -//! -//TODO need to update this now that vertex data doesn't contain color data -mod rainbow { - use iced::Color; - // For now, to implement a custom native widget you will need to add - // `iced_native` and `iced_wgpu` to your dependencies. - // - // Then, you simply need to define your widget type and implement the - // `iced_native::Widget` trait with the `iced_wgpu::Renderer`. - // - // Of course, you can choose to make the implementation renderer-agnostic, - // if you wish to, by creating your own `Renderer` trait, which could be - // implemented by `iced_wgpu` and other renderers. - use iced_graphics::renderer::{self, Renderer}; - use iced_graphics::{Backend, Primitive}; - use iced_graphics::shader::Shader; - - use iced_native::widget::{self, Widget}; - use iced_native::{ - layout, Element, Layout, Length, Point, Rectangle, Size, Vector, - }; - - #[derive(Default)] - pub struct Rainbow; - - impl Rainbow { - pub fn new() -> Self { - Self - } - } - - pub fn rainbow() -> Rainbow { - Rainbow - } - - impl Widget> for Rainbow - where - B: Backend, - { - fn width(&self) -> Length { - Length::Fill - } - - fn height(&self) -> Length { - Length::Shrink - } - - fn layout( - &self, - _renderer: &Renderer, - limits: &layout::Limits, - ) -> layout::Node { - let size = limits.width(Length::Fill).resolve(Size::ZERO); - - layout::Node::new(Size::new(size.width, size.width)) - } - - fn draw( - &self, - _tree: &widget::Tree, - renderer: &mut Renderer, - _theme: &T, - _style: &renderer::Style, - layout: Layout<'_>, - cursor_position: Point, - _viewport: &Rectangle, - ) { - use iced_graphics::triangle::{Mesh2D, Shader, Vertex2D}; - use iced_native::Renderer as _; - - let b = layout.bounds(); - - // R O Y G B I V - // let color_r = [1.0, 0.0, 0.0, 1.0]; - // let color_o = [1.0, 0.5, 0.0, 1.0]; - // let color_y = [1.0, 1.0, 0.0, 1.0]; - // let color_g = [0.0, 1.0, 0.0, 1.0]; - // let color_gb = [0.0, 1.0, 0.5, 1.0]; - // let color_b = [0.0, 0.2, 1.0, 1.0]; - // let color_i = [0.5, 0.0, 1.0, 1.0]; - // let color_v = [0.75, 0.0, 0.5, 1.0]; - - let posn_center = { - if b.contains(cursor_position) { - [cursor_position.x - b.x, cursor_position.y - b.y] - } else { - [b.width / 2.0, b.height / 2.0] - } - }; - - let posn_tl = [0.0, 0.0]; - let posn_t = [b.width / 2.0, 0.0]; - let posn_tr = [b.width, 0.0]; - let posn_r = [b.width, b.height / 2.0]; - let posn_br = [b.width, b.height]; - let posn_b = [(b.width / 2.0), b.height]; - let posn_bl = [0.0, b.height]; - let posn_l = [0.0, b.height / 2.0]; - - let mesh = Primitive::Mesh2D { - size: b.size(), - buffers: Mesh2D { - vertices: vec![ - Vertex2D { - position: posn_center, - // color: [1.0, 1.0, 1.0, 1.0], - }, - Vertex2D { - position: posn_tl, - // color: color_r, - }, - Vertex2D { - position: posn_t, - // color: color_o, - }, - Vertex2D { - position: posn_tr, - // color: color_y, - }, - Vertex2D { - position: posn_r, - // color: color_g, - }, - Vertex2D { - position: posn_br, - // color: color_gb, - }, - Vertex2D { - position: posn_b, - // color: color_b, - }, - Vertex2D { - position: posn_bl, - // color: color_i, - }, - Vertex2D { - position: posn_l, - // color: color_v, - }, - ], - indices: vec![ - 0, 1, 2, // TL - 0, 2, 3, // T - 0, 3, 4, // TR - 0, 4, 5, // R - 0, 5, 6, // BR - 0, 6, 7, // B - 0, 7, 8, // BL - 0, 8, 1, // L - ], - }, - shader: Shader::Solid(Color::BLACK), - }; - - renderer.with_translation(Vector::new(b.x, b.y), |renderer| { - renderer.draw_primitive(mesh); - }); - } - } - - impl<'a, Message, B, T> From for Element<'a, Message, Renderer> - where - B: Backend, - { - fn from(rainbow: Rainbow) -> Self { - Self::new(rainbow) - } - } -} - -use iced::widget::{column, container, scrollable}; -use iced::{Alignment, Element, Length, Sandbox, Settings}; -use rainbow::rainbow; - -pub fn main() -> iced::Result { - Example::run(Settings::default()) -} - -struct Example; - -impl Sandbox for Example { - type Message = (); - - fn new() -> Self { - Example - } - - fn title(&self) -> String { - String::from("Custom 2D geometry - Iced") - } - - fn update(&mut self, _: ()) {} - - fn view(&self) -> Element<()> { - let content = column![ - rainbow(), - "In this example we draw a custom widget Rainbow, using \ - the Mesh2D primitive. This primitive supplies a list of \ - triangles, expressed as vertices and indices.", - "Move your cursor over it, and see the center vertex \ - follow you!", - "Every Vertex2D defines its own color. You could use the \ - Mesh2D primitive to render virtually any two-dimensional \ - geometry for your widget.", - ] - .padding(20) - .spacing(20) - .max_width(500) - .align_items(Alignment::Start); - - let scrollable = - scrollable(container(content).width(Length::Fill).center_x()); - - container(scrollable) - .width(Length::Fill) - .height(Length::Fill) - .center_y() - .into() - } -} diff --git a/examples/modern_art/src/main.rs b/examples/modern_art/src/main.rs index 238c9a0f..14e117b3 100644 --- a/examples/modern_art/src/main.rs +++ b/examples/modern_art/src/main.rs @@ -1,14 +1,13 @@ use rand::{Rng, thread_rng}; use crate::canvas::{Cursor, Geometry}; -use iced::widget::canvas::{Cache, Fill, Frame}; +use iced::widget::canvas::{Cache, Fill, Frame, Gradient}; use iced::widget::{canvas, Canvas}; use iced::Settings; use iced::{ executor, Application, Color, Command, Element, Length, Point, Rectangle, Renderer, Size, Theme, }; -use iced_graphics::gradient::Gradient; -use iced_graphics::widget::canvas::Style; +use iced_graphics::widget::canvas::fill; fn main() -> iced::Result { ModernArt::run(Settings { @@ -121,7 +120,7 @@ fn generate_box(frame: &mut Frame, bounds: Size) -> bool { top_left, size, Fill { - style: Style::Solid(random_color()), + style: fill::Style::Solid(random_color()), .. Default::default() } ); @@ -130,7 +129,7 @@ fn generate_box(frame: &mut Frame, bounds: Size) -> bool { top_left, size, Fill { - style: Style::Gradient(&gradient( + style: fill::Style::Gradient(&gradient( top_left, Point::new(top_left.x + size.width, top_left.y + size.height) )), diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index f16f8af4..5e58f4e4 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -5,13 +5,13 @@ mod solid; use crate::{program, Transformation}; use glow::HasContext; use iced_graphics::layer::{attribute_count_of, Mesh}; -use iced_graphics::shader; use std::marker::PhantomData; +use iced_graphics::layer; use crate::triangle::gradient::GradientProgram; use crate::triangle::solid::SolidProgram; pub use iced_graphics::triangle::{Mesh2D, Vertex2D}; -use shader::Shader; +use layer::mesh; #[derive(Debug)] pub(crate) struct Pipeline { @@ -139,11 +139,11 @@ impl Pipeline { clip_bounds.height as i32, ); - match mesh.shader { - Shader::Solid(color) => { + match mesh.style { + mesh::Style::Solid(color) => { self.programs.solid.use_program(gl, &color, &transform); } - Shader::Gradient(gradient) => { + mesh::Style::Gradient(gradient) => { self.programs.gradient.use_program(gl, &gradient, &transform); } } diff --git a/graphics/src/gradient.rs b/graphics/src/gradient.rs index 0c394e8b..33453c67 100644 --- a/graphics/src/gradient.rs +++ b/graphics/src/gradient.rs @@ -1,4 +1,6 @@ //! For creating a Gradient. +mod linear; + use iced_native::Color; pub use crate::gradient::linear::Linear; use crate::Point; @@ -28,76 +30,3 @@ impl Gradient { } } -/// Linear gradient builder & definition. -pub mod linear { - use crate::gradient::{ColorStop, Gradient}; - use crate::{Color, Point}; - - /// A linear gradient that can be used in the style of [`super::Fill`] or [`super::Stroke`]. - #[derive(Debug, Clone, PartialEq)] - pub struct Linear { - /// The point where the linear gradient begins. - pub start: Point, - /// The point where the linear gradient ends. - pub end: Point, - /// [`ColorStop`]s along the linear gradient path. - pub color_stops: Vec, - } - - /// A [`Linear`] builder. - #[derive(Debug)] - pub struct Builder { - start: Point, - end: Point, - stops: Vec<(f32, Color)>, - valid: bool, - } - - impl Builder { - /// Creates a new [`Builder`]. - pub fn new(start: Point, end: Point) -> Self { - Self { - start, - end, - stops: vec![], - valid: true, - } - } - - /// Adds a new stop, defined by an offset and a color, to the gradient. - /// - /// `offset` must be between `0.0` and `1.0`. - pub fn add_stop(mut self, offset: f32, color: Color) -> Self { - if !(0.0..=1.0).contains(&offset) { - self.valid = false; - } - - self.stops.push((offset, color)); - self - } - - /// Builds the linear [`Gradient`] of this [`Builder`]. - /// - /// Returns `None` if no stops were added to the builder or - /// if stops not between 0.0 and 1.0 were added. - pub fn build(self) -> Option { - if self.stops.is_empty() || !self.valid { - return None; - } - - let mut stops: Vec = self.stops.clone().into_iter().map(|f| ColorStop { - offset: f.0, - color: f.1 - }).collect(); - - stops.sort_by(|a, b| a.offset.partial_cmp(&b.offset).unwrap()); - - Some(Gradient::Linear(Linear { - start: self.start, - end: self.end, - color_stops: stops - })) - } - } -} - diff --git a/graphics/src/gradient/linear.rs b/graphics/src/gradient/linear.rs new file mode 100644 index 00000000..00f94adc --- /dev/null +++ b/graphics/src/gradient/linear.rs @@ -0,0 +1,71 @@ +//! Linear gradient builder & definition. + +use crate::gradient::{ColorStop, Gradient}; +use crate::{Color, Point}; + +/// A linear gradient that can be used in the style of [`super::Fill`] or [`super::Stroke`]. +#[derive(Debug, Clone, PartialEq)] +pub struct Linear { + /// The point where the linear gradient begins. + pub start: Point, + /// The point where the linear gradient ends. + pub end: Point, + /// [`ColorStop`]s along the linear gradient path. + pub color_stops: Vec, +} + +/// A [`Linear`] builder. +#[derive(Debug)] +pub struct Builder { + start: Point, + end: Point, + stops: Vec<(f32, Color)>, + valid: bool, +} + +impl Builder { + /// Creates a new [`Builder`]. + pub fn new(start: Point, end: Point) -> Self { + Self { + start, + end, + stops: vec![], + valid: true, + } + } + + /// Adds a new stop, defined by an offset and a color, to the gradient. + /// + /// `offset` must be between `0.0` and `1.0`. + pub fn add_stop(mut self, offset: f32, color: Color) -> Self { + if !(0.0..=1.0).contains(&offset) { + self.valid = false; + } + + self.stops.push((offset, color)); + self + } + + /// Builds the linear [`Gradient`] of this [`Builder`]. + /// + /// Returns `None` if no stops were added to the builder or + /// if stops not between 0.0 and 1.0 were added. + pub fn build(self) -> Option { + if self.stops.is_empty() || !self.valid { + return None; + } + + let mut stops: Vec = self.stops.clone().into_iter().map(|f| ColorStop { + offset: f.0, + color: f.1 + }).collect(); + + stops.sort_by(|a, b| a.offset.partial_cmp(&b.offset).unwrap()); + + Some(Gradient::Linear(Linear { + start: self.start, + end: self.end, + color_stops: stops + })) + } +} \ No newline at end of file diff --git a/graphics/src/layer.rs b/graphics/src/layer.rs index 096c50dc..65e70cb3 100644 --- a/graphics/src/layer.rs +++ b/graphics/src/layer.rs @@ -1,13 +1,17 @@ //! Organize rendering primitives into a flattened list of layers. +pub mod mesh; +mod quad; +mod text; +mod image; + use crate::alignment; -use crate::triangle; use crate::{ Background, Font, Point, Primitive, Rectangle, Size, Vector, Viewport, }; - -use iced_native::image; -use iced_native::svg; -use crate::shader::Shader; +pub use crate::layer::image::Image; +pub use crate::layer::mesh::Mesh; +pub use crate::layer::quad::Quad; +pub use crate::layer::text::Text; /// A group of primitives that should be clipped together. #[derive(Debug)] @@ -163,7 +167,7 @@ impl<'a> Layer<'a> { Primitive::Mesh2D { buffers, size, - shader, + style, } => { let layer = &mut layers[current_layer]; @@ -179,7 +183,7 @@ impl<'a> Layer<'a> { origin: Point::new(translation.x, translation.y), buffers, clip_bounds, - shader, + style, } ); } @@ -242,99 +246,6 @@ impl<'a> Layer<'a> { } } -/// A colored rectangle with a border. -/// -/// This type can be directly uploaded to GPU memory. -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Quad { - /// The position of the [`Quad`]. - pub position: [f32; 2], - - /// The size of the [`Quad`]. - pub size: [f32; 2], - - /// The color of the [`Quad`], in __linear RGB__. - pub color: [f32; 4], - - /// The border color of the [`Quad`], in __linear RGB__. - pub border_color: [f32; 4], - - /// The border radius of the [`Quad`]. - pub border_radius: f32, - - /// The border width of the [`Quad`]. - pub border_width: f32, -} - -/// A mesh of triangles. -#[derive(Debug, Clone, Copy)] -pub struct Mesh<'a> { - /// The origin of the vertices of the [`Mesh`]. - pub origin: Point, - - /// The vertex and index buffers of the [`Mesh`]. - pub buffers: &'a triangle::Mesh2D, - - /// The clipping bounds of the [`Mesh`]. - pub clip_bounds: Rectangle, - - /// The shader of the [`Mesh`]. - pub shader: &'a Shader, -} - -/// A paragraph of text. -#[derive(Debug, Clone, Copy)] -pub struct Text<'a> { - /// The content of the [`Text`]. - pub content: &'a str, - - /// The layout bounds of the [`Text`]. - pub bounds: Rectangle, - - /// The color of the [`Text`], in __linear RGB_. - pub color: [f32; 4], - - /// The size of the [`Text`]. - pub size: f32, - - /// The font of the [`Text`]. - pub font: Font, - - /// The horizontal alignment of the [`Text`]. - pub horizontal_alignment: alignment::Horizontal, - - /// The vertical alignment of the [`Text`]. - pub vertical_alignment: alignment::Vertical, -} - -/// A raster or vector image. -#[derive(Debug, Clone)] -pub enum Image { - /// A raster image. - Raster { - /// The handle of a raster image. - handle: image::Handle, - - /// The bounds of the image. - bounds: Rectangle, - }, - /// A vector image. - Vector { - /// The handle of a vector image. - handle: svg::Handle, - - /// The bounds of the image. - bounds: Rectangle, - }, -} - -#[allow(unsafe_code)] -unsafe impl bytemuck::Zeroable for Quad {} - -#[allow(unsafe_code)] -unsafe impl bytemuck::Pod for Quad {} - /// Returns the number of total vertices & total indices of all [`Mesh`]es. pub fn attribute_count_of<'a>(meshes: &'a [Mesh<'a>]) -> (usize, usize) { meshes diff --git a/graphics/src/layer/image.rs b/graphics/src/layer/image.rs new file mode 100644 index 00000000..387b60ed --- /dev/null +++ b/graphics/src/layer/image.rs @@ -0,0 +1,23 @@ +use iced_native::{image, svg}; +use crate::Rectangle; + +/// A raster or vector image. +#[derive(Debug, Clone)] +pub enum Image { + /// A raster image. + Raster { + /// The handle of a raster image. + handle: image::Handle, + + /// The bounds of the image. + bounds: Rectangle, + }, + /// A vector image. + Vector { + /// The handle of a vector image. + handle: svg::Handle, + + /// The bounds of the image. + bounds: Rectangle, + }, +} \ No newline at end of file diff --git a/graphics/src/layer/mesh.rs b/graphics/src/layer/mesh.rs new file mode 100644 index 00000000..a025675a --- /dev/null +++ b/graphics/src/layer/mesh.rs @@ -0,0 +1,39 @@ +//! A collection of triangle primitives. + +use crate::{Color, Point, Rectangle, triangle}; +use crate::gradient::Gradient; + +/// A mesh of triangles. +#[derive(Debug, Clone, Copy)] +pub struct Mesh<'a> { + /// The origin of the vertices of the [`Mesh`]. + pub origin: Point, + + /// The vertex and index buffers of the [`Mesh`]. + pub buffers: &'a triangle::Mesh2D, + + /// The clipping bounds of the [`Mesh`]. + pub clip_bounds: Rectangle, + + /// The shader of the [`Mesh`]. + pub style: &'a Style, +} + +#[derive(Debug, Clone)] +/// Supported shaders for primitives. +pub enum Style { + /// Fill a primitive with a solid color. + Solid(Color), + /// Fill a primitive with an interpolated color. + Gradient(Gradient) +} + +impl <'a> Into