From cf495be002db2d9568e10e14a252338e8e6db846 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 5 Jan 2019 16:23:40 +0100 Subject: [PATCH] Draw lines --- docs/emgui_wasm_bg.wasm | Bin 346638 -> 350870 bytes emgui/src/math.rs | 42 ++++++++ emgui/src/painter.rs | 224 +++++++++++++++++++++------------------- emgui_wasm/src/app.rs | 2 +- emgui_wasm/src/webgl.rs | 8 +- 5 files changed, 163 insertions(+), 113 deletions(-) diff --git a/docs/emgui_wasm_bg.wasm b/docs/emgui_wasm_bg.wasm index f9fd3d1df13f0add46388a92cfe9c41164d6eb66..04cd0991ea76643db540a46af5c675ecf6088162 100644 GIT binary patch delta 49936 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 delta 46241 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 T>u^-fpFOYAvYdxbrRx6!x(bgo diff --git a/emgui/src/math.rs b/emgui/src/math.rs index e333aa49..7d300666 100644 --- a/emgui/src/math.rs +++ b/emgui/src/math.rs @@ -4,6 +4,38 @@ pub struct Vec2 { pub y: f32, } +impl Vec2 { + pub fn normalized(self) -> Vec2 { + let len = self.x.hypot(self.y); + if len <= 0.0 { + self + } else { + self / len + } + } + + pub fn rot90(self) -> Vec2 { + vec2(self.y, -self.x) + } + + pub fn length(self) -> f32 { + self.x.hypot(self.y) + } + + pub fn length_sq(self) -> f32 { + self.x * self.x + self.y * self.y + } +} + +impl std::ops::AddAssign for Vec2 { + fn add_assign(&mut self, other: Vec2) { + *self = Vec2 { + x: self.x + other.x, + y: self.y + other.y, + }; + } +} + impl std::ops::Add for Vec2 { type Output = Vec2; fn add(self, rhs: Vec2) -> Vec2 { @@ -44,6 +76,16 @@ impl std::ops::Mul for f32 { } } +impl std::ops::Div for Vec2 { + type Output = Vec2; + fn div(self, factor: f32) -> Vec2 { + Vec2 { + x: self.x / factor, + y: self.y / factor, + } + } +} + pub fn vec2(x: f32, y: f32) -> Vec2 { Vec2 { x, y } } diff --git a/emgui/src/painter.rs b/emgui/src/painter.rs index 66406a37..171f03ae 100644 --- a/emgui/src/painter.rs +++ b/emgui/src/painter.rs @@ -1,20 +1,18 @@ +#![allow(unused_variables)] + /// Outputs render info in a format suitable for e.g. OpenGL. use crate::{ font::Font, - math::{remap, Vec2, TAU}, + math::{remap, vec2, Vec2, TAU}, types::{Color, PaintCmd}, }; #[derive(Clone, Copy, Debug, Default)] pub struct Vertex { - /// Pixel coordinated - pub x: f32, - /// Pixel coordinated - pub y: f32, + /// Pixel coordinates + pub pos: Vec2, /// Texel indices into the texture - pub u: u16, - /// Texel indices into the texture - pub v: u16, + pub uv: (u16, u16), /// sRGBA pub color: Color, } @@ -27,6 +25,13 @@ pub struct Frame { pub vertices: Vec, } +#[derive(Clone, Copy, PartialEq)] +pub enum PathType { + Open, + Closed, +} +use self::PathType::*; + impl Frame { /// Uniformly colored rectangle pub fn add_rect(&mut self, top_left: Vertex, bottom_right: Vertex) { @@ -39,17 +44,13 @@ impl Frame { self.indices.push(idx + 3); let top_right = Vertex { - x: bottom_right.x, - y: top_left.y, - u: bottom_right.u, - v: top_left.v, + pos: vec2(bottom_right.pos.x, top_left.pos.y), + uv: (bottom_right.uv.0, top_left.uv.1), color: top_left.color, }; let botom_left = Vertex { - x: top_left.x, - y: bottom_right.y, - u: top_left.u, - v: bottom_right.v, + pos: vec2(top_left.pos.x, bottom_right.pos.y), + uv: (top_left.uv.0, bottom_right.uv.1), color: top_left.color, }; self.vertices.push(top_left); @@ -59,17 +60,15 @@ impl Frame { } pub fn fill_closed_path(&mut self, points: &[Vec2], normals: &[Vec2], color: Color) { - self.vertices.extend(points.iter().map(|p| Vertex { - x: p.x, - y: p.y, - u: 0, - v: 0, - color, - })); // TODO: use normals for anti-aliasing assert_eq!(points.len(), normals.len()); let n = points.len() as u32; let idx = self.vertices.len() as u32; + self.vertices.extend(points.iter().map(|&pos| Vertex { + pos, + uv: (0, 0), + color, + })); for i in 2..n { self.indices.push(idx); self.indices.push(idx + i - 1); @@ -77,12 +76,13 @@ impl Frame { } } - pub fn draw_closed_path( + pub fn paint_path( &mut self, + path_type: PathType, points: &[Vec2], normals: &[Vec2], - width: f32, color: Color, + width: f32, ) { // TODO: anti-aliasing assert_eq!(points.len(), normals.len()); @@ -90,7 +90,8 @@ impl Frame { let hw = width / 2.0; let idx = self.vertices.len() as u32; - for i in 0..n { + let last_index = if path_type == Closed { n } else { n - 1 }; + for i in 0..last_index { self.indices.push(idx + (2 * i + 0) % (2 * n)); self.indices.push(idx + (2 * i + 1) % (2 * n)); self.indices.push(idx + (2 * i + 2) % (2 * n)); @@ -99,19 +100,15 @@ impl Frame { self.indices.push(idx + (2 * i + 3) % (2 * n)); } - for (p, n) in points.iter().zip(normals) { + for (&p, &n) in points.iter().zip(normals) { self.vertices.push(Vertex { - x: p.x + hw * n.x, - y: p.y + hw * n.x, - u: 0, - v: 0, + pos: p + hw * n, + uv: (0, 0), color, }); self.vertices.push(Vertex { - x: p.x - hw * n.x, - y: p.y - hw * n.x, - u: 0, - v: 0, + pos: p - hw * n, + uv: (0, 0), color, }); } @@ -136,8 +133,8 @@ impl Painter { } pub fn paint(&self, commands: &[PaintCmd]) -> Frame { - // let mut path_points = Vec::new(); - // let mut path_normals = Vec::new(); + let mut path_points = Vec::new(); + let mut path_normals = Vec::new(); let mut frame = Frame::default(); for cmd in commands { @@ -148,34 +145,60 @@ impl Painter { outline, radius, } => { - let n = 64; // TODO: parameter - if let Some(color) = fill_color { - let idx = frame.vertices.len() as u32; - for i in 2..n { - frame.indices.push(idx); - frame.indices.push(idx + i - 1); - frame.indices.push(idx + i); - } + path_points.clear(); + path_normals.clear(); - for i in 0..n { - let angle = remap(i as f32, 0.0, n as f32, 0.0, TAU); - frame.vertices.push(Vertex { - x: center.x + radius * angle.cos(), - y: center.y + radius * angle.sin(), - u: 0, - v: 0, - color: *color, - }); - } + let n = 32; // TODO: parameter + for i in 0..n { + let angle = remap(i as f32, 0.0, n as f32, 0.0, TAU); + let normal = vec2(angle.cos(), angle.sin()); + path_normals.push(normal); + path_points.push(*center + *radius * normal); } - if let Some(_outline) = outline { - // TODO + + if let Some(color) = fill_color { + frame.fill_closed_path(&path_points, &path_normals, *color); + } + if let Some(outline) = outline { + frame.paint_path( + Closed, + &path_points, + &path_normals, + outline.color, + outline.width, + ); } } PaintCmd::Clear { fill_color } => { frame.clear_color = Some(*fill_color); } - PaintCmd::Line { .. } => {} // TODO + PaintCmd::Line { + points, + color, + width, + } => { + let n = points.len(); + if n >= 2 { + path_points = points.clone(); + path_normals.clear(); + + path_normals.push((path_points[1] - path_points[0]).normalized().rot90()); + for i in 1..n - 1 { + let n0 = (path_points[i] - path_points[i - 1]).normalized().rot90(); + let n1 = (path_points[i + 1] - path_points[i]).normalized().rot90(); + let v = (n0 + n1) / 2.0; + let normal = v / v.length_sq(); + path_normals.push(normal); // TODO: handle VERY sharp turns better + } + path_normals.push( + (path_points[n - 1] - path_points[n - 2]) + .normalized() + .rot90(), + ); + + frame.paint_path(Open, &path_points, &path_normals, *color, *width); + } + } PaintCmd::Rect { fill_color, outline, @@ -183,52 +206,33 @@ impl Painter { size, .. } => { + path_points.clear(); + path_normals.clear(); + + let min = *pos; + let max = *pos + *size; + // TODO: rounded corners - // TODO: anti-aliasing - // TODO: FilledRect and RectOutline as separate commands? + path_points.push(vec2(min.x, min.y)); + path_normals.push(vec2(-1.0, -1.0)); + path_points.push(vec2(max.x, min.y)); + path_normals.push(vec2(1.0, -1.0)); + path_points.push(vec2(max.x, max.y)); + path_normals.push(vec2(1.0, 1.0)); + path_points.push(vec2(min.x, max.y)); + path_normals.push(vec2(-1.0, 1.0)); + if let Some(color) = fill_color { - let vert = |pos: Vec2| Vertex { - x: pos.x, - y: pos.y, - u: 0, - v: 0, - color: *color, - }; - frame.add_rect(vert(*pos), vert(*pos + *size)); + frame.fill_closed_path(&path_points, &path_normals, *color); } if let Some(outline) = outline { - let vert = |x, y| Vertex { - x, - y, - u: 0, - v: 0, - color: outline.color, - }; - - // Draw this counter-clockwise from top-left corner, - // outer to inner on each step. - let hw = outline.width / 2.0; - - let idx = frame.vertices.len() as u32; - for i in 0..4 { - frame.indices.push(idx + (2 * i + 0) % 8); - frame.indices.push(idx + (2 * i + 1) % 8); - frame.indices.push(idx + (2 * i + 2) % 8); - frame.indices.push(idx + (2 * i + 2) % 8); - frame.indices.push(idx + (2 * i + 1) % 8); - frame.indices.push(idx + (2 * i + 3) % 8); - } - - let min = *pos; - let max = *pos + *size; - frame.vertices.push(vert(min.x - hw, min.y - hw)); - frame.vertices.push(vert(min.x + hw, min.y + hw)); - frame.vertices.push(vert(max.x + hw, min.y - hw)); - frame.vertices.push(vert(max.x - hw, min.y + hw)); - frame.vertices.push(vert(max.x + hw, max.y + hw)); - frame.vertices.push(vert(max.x - hw, max.y - hw)); - frame.vertices.push(vert(min.x - hw, max.y + hw)); - frame.vertices.push(vert(min.x + hw, max.y - hw)); + frame.paint_path( + Closed, + &path_points, + &path_normals, + outline.color, + outline.width, + ); } } PaintCmd::Text { @@ -240,17 +244,21 @@ impl Painter { for (c, x_offset) in text.chars().zip(x_offsets.iter()) { if let Some(glyph) = self.font.glyph_info(c) { let top_left = Vertex { - x: pos.x + x_offset + (glyph.offset_x as f32), - y: pos.y + (glyph.offset_y as f32), - u: glyph.min_x, - v: glyph.min_y, + pos: *pos + + vec2( + x_offset + (glyph.offset_x as f32), + glyph.offset_y as f32, + ), + uv: (glyph.min_x, glyph.min_y), color: *color, }; let bottom_right = Vertex { - x: top_left.x + (1 + glyph.max_x - glyph.min_x) as f32, - y: top_left.y + (1 + glyph.max_y - glyph.min_y) as f32, - u: glyph.max_x + 1, - v: glyph.max_y + 1, + pos: top_left.pos + + vec2( + (1 + glyph.max_x - glyph.min_x) as f32, + (1 + glyph.max_y - glyph.min_y) as f32, + ), + uv: (glyph.max_x + 1, glyph.max_y + 1), color: *color, }; frame.add_rect(top_left, bottom_right); diff --git a/emgui_wasm/src/app.rs b/emgui_wasm/src/app.rs index f138ce78..7864f25f 100644 --- a/emgui_wasm/src/app.rs +++ b/emgui_wasm/src/app.rs @@ -18,7 +18,7 @@ pub struct App { impl Default for App { fn default() -> App { App { - checked: false, + checked: true, selected_alternative: 0, count: 0, width: 100.0, diff --git a/emgui_wasm/src/webgl.rs b/emgui_wasm/src/webgl.rs index 7ccb724e..280fc08a 100644 --- a/emgui_wasm/src/webgl.rs +++ b/emgui_wasm/src/webgl.rs @@ -141,10 +141,10 @@ impl Painter { let mut positions: Vec = Vec::with_capacity(2 * frame.vertices.len()); let mut tex_coords: Vec = Vec::with_capacity(2 * frame.vertices.len()); for v in &frame.vertices { - positions.push(v.x); - positions.push(v.y); - tex_coords.push(v.u); - tex_coords.push(v.v); + positions.push(v.pos.x); + positions.push(v.pos.y); + tex_coords.push(v.uv.0); + tex_coords.push(v.uv.1); } let mut colors: Vec = Vec::with_capacity(4 * frame.vertices.len());