Fix antialiasing for non-retina screens
This commit is contained in:
parent
68db833a3a
commit
f2040c6fc5
2 changed files with 81 additions and 59 deletions
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
label, layout,
|
label, layout,
|
||||||
layout::{show_popup, LayoutOptions, Region},
|
layout::{show_popup, LayoutOptions, Region},
|
||||||
math::{clamp, remap_clamp, vec2},
|
math::{clamp, remap_clamp, vec2},
|
||||||
mesher::Vertex,
|
mesher::{Mesher, Vertex},
|
||||||
style,
|
style,
|
||||||
types::{Color, GuiCmd, GuiInput, PaintCmd},
|
types::{Color, GuiCmd, GuiInput, PaintCmd},
|
||||||
widgets::*,
|
widgets::*,
|
||||||
|
@ -164,7 +164,10 @@ impl Emigui {
|
||||||
pub fn paint(&mut self) -> Frame {
|
pub fn paint(&mut self) -> Frame {
|
||||||
let gui_commands = self.data.graphics.lock().unwrap().drain();
|
let gui_commands = self.data.graphics.lock().unwrap().drain();
|
||||||
let paint_commands = style::into_paint_commands(gui_commands, &self.style);
|
let paint_commands = style::into_paint_commands(gui_commands, &self.style);
|
||||||
let frame = Frame::paint(&self.data.fonts, &paint_commands);
|
|
||||||
|
let mut mesher = Mesher::new(self.last_input.pixels_per_point);
|
||||||
|
mesher.paint(&self.data.fonts, &paint_commands);
|
||||||
|
let frame = mesher.frame;
|
||||||
self.stats.num_vertices = frame.vertices.len();
|
self.stats.num_vertices = frame.vertices.len();
|
||||||
self.stats.num_triangles = frame.indices.len() / 3;
|
self.stats.num_triangles = frame.indices.len() / 3;
|
||||||
frame
|
frame
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
#![allow(clippy::identity_op)]
|
#![allow(clippy::identity_op)]
|
||||||
|
|
||||||
const ANTI_ALIAS: bool = true;
|
|
||||||
const AA_SIZE: f32 = 0.5; // TODO: 1.0 / pixels_per_point
|
|
||||||
|
|
||||||
/// Outputs render info in a format suitable for e.g. OpenGL.
|
/// Outputs render info in a format suitable for e.g. OpenGL.
|
||||||
use crate::{
|
use crate::{
|
||||||
fonts::Fonts,
|
fonts::Fonts,
|
||||||
|
@ -27,13 +24,6 @@ pub struct Frame {
|
||||||
pub vertices: Vec<Vertex>,
|
pub vertices: Vec<Vertex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
|
||||||
pub enum PathType {
|
|
||||||
Open,
|
|
||||||
Closed,
|
|
||||||
}
|
|
||||||
use self::PathType::*;
|
|
||||||
|
|
||||||
impl Frame {
|
impl Frame {
|
||||||
pub fn append(&mut self, frame: &Frame) {
|
pub fn append(&mut self, frame: &Frame) {
|
||||||
let index_offset = self.vertices.len() as u32;
|
let index_offset = self.vertices.len() as u32;
|
||||||
|
@ -70,6 +60,31 @@ impl Frame {
|
||||||
self.vertices.push(botom_left);
|
self.vertices.push(botom_left);
|
||||||
self.vertices.push(bottom_right);
|
self.vertices.push(bottom_right);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub enum PathType {
|
||||||
|
Open,
|
||||||
|
Closed,
|
||||||
|
}
|
||||||
|
use self::PathType::*;
|
||||||
|
|
||||||
|
pub struct Mesher {
|
||||||
|
pub anti_alias: bool,
|
||||||
|
pub aa_size: f32,
|
||||||
|
|
||||||
|
/// Where the output goes
|
||||||
|
pub frame: Frame,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mesher {
|
||||||
|
pub fn new(pixels_per_point: f32) -> Mesher {
|
||||||
|
Mesher {
|
||||||
|
anti_alias: true,
|
||||||
|
aa_size: 1.0 / pixels_per_point,
|
||||||
|
frame: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fill_closed_path(&mut self, points: &[Vec2], normals: &[Vec2], color: Color) {
|
pub fn fill_closed_path(&mut self, points: &[Vec2], normals: &[Vec2], color: Color) {
|
||||||
assert_eq!(points.len(), normals.len());
|
assert_eq!(points.len(), normals.len());
|
||||||
|
@ -79,29 +94,32 @@ impl Frame {
|
||||||
uv: (0, 0),
|
uv: (0, 0),
|
||||||
color,
|
color,
|
||||||
};
|
};
|
||||||
if ANTI_ALIAS {
|
let frame = &mut self.frame;
|
||||||
|
if self.anti_alias {
|
||||||
let color_outer = color.transparent();
|
let color_outer = color.transparent();
|
||||||
let idx_inner = self.vertices.len() as u32;
|
let idx_inner = frame.vertices.len() as u32;
|
||||||
let idx_outer = idx_inner + 1;
|
let idx_outer = idx_inner + 1;
|
||||||
for i in 2..n {
|
for i in 2..n {
|
||||||
self.triangle(idx_inner + 2 * (i - 1), idx_inner, idx_inner + 2 * i);
|
frame.triangle(idx_inner + 2 * (i - 1), idx_inner, idx_inner + 2 * i);
|
||||||
}
|
}
|
||||||
let mut i0 = n - 1;
|
let mut i0 = n - 1;
|
||||||
for i1 in 0..n {
|
for i1 in 0..n {
|
||||||
let dm = normals[i1 as usize] * AA_SIZE * 0.5;
|
let dm = normals[i1 as usize] * self.aa_size * 0.5;
|
||||||
self.vertices.push(vert(points[i1 as usize] - dm, color));
|
frame.vertices.push(vert(points[i1 as usize] - dm, color));
|
||||||
self.vertices
|
frame
|
||||||
|
.vertices
|
||||||
.push(vert(points[i1 as usize] + dm, color_outer));
|
.push(vert(points[i1 as usize] + dm, color_outer));
|
||||||
self.triangle(idx_inner + i1 * 2, idx_inner + i0 * 2, idx_outer + 2 * i0);
|
frame.triangle(idx_inner + i1 * 2, idx_inner + i0 * 2, idx_outer + 2 * i0);
|
||||||
self.triangle(idx_outer + i0 * 2, idx_outer + i1 * 2, idx_inner + 2 * i1);
|
frame.triangle(idx_outer + i0 * 2, idx_outer + i1 * 2, idx_inner + 2 * i1);
|
||||||
i0 = i1;
|
i0 = i1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let idx = self.vertices.len() as u32;
|
let idx = frame.vertices.len() as u32;
|
||||||
self.vertices
|
frame
|
||||||
|
.vertices
|
||||||
.extend(points.iter().map(|&pos| vert(pos, color)));
|
.extend(points.iter().map(|&pos| vert(pos, color)));
|
||||||
for i in 2..n {
|
for i in 2..n {
|
||||||
self.triangle(idx, idx + i - 1, idx + i);
|
frame.triangle(idx, idx + i - 1, idx + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,15 +135,16 @@ impl Frame {
|
||||||
assert_eq!(points.len(), normals.len());
|
assert_eq!(points.len(), normals.len());
|
||||||
let n = points.len() as u32;
|
let n = points.len() as u32;
|
||||||
let hw = width / 2.0;
|
let hw = width / 2.0;
|
||||||
let idx = self.vertices.len() as u32;
|
let idx = self.frame.vertices.len() as u32;
|
||||||
|
|
||||||
let vert = |pos, color| Vertex {
|
let vert = |pos, color| Vertex {
|
||||||
pos,
|
pos,
|
||||||
uv: (0, 0),
|
uv: (0, 0),
|
||||||
color,
|
color,
|
||||||
};
|
};
|
||||||
|
let frame = &mut self.frame;
|
||||||
|
|
||||||
if ANTI_ALIAS {
|
if self.anti_alias {
|
||||||
let color_outer = color.transparent();
|
let color_outer = color.transparent();
|
||||||
let thin_line = width <= 1.0;
|
let thin_line = width <= 1.0;
|
||||||
let mut color_inner = color;
|
let mut color_inner = color;
|
||||||
|
@ -140,37 +159,39 @@ impl Frame {
|
||||||
if thin_line {
|
if thin_line {
|
||||||
let p = points[i1 as usize];
|
let p = points[i1 as usize];
|
||||||
let n = normals[i1 as usize];
|
let n = normals[i1 as usize];
|
||||||
self.vertices.push(vert(p + n * AA_SIZE, color_outer));
|
frame.vertices.push(vert(p + n * self.aa_size, color_outer));
|
||||||
self.vertices.push(vert(p, color_inner));
|
frame.vertices.push(vert(p, color_inner));
|
||||||
self.vertices.push(vert(p - n * AA_SIZE, color_outer));
|
frame.vertices.push(vert(p - n * self.aa_size, color_outer));
|
||||||
|
|
||||||
if connect_with_previous {
|
if connect_with_previous {
|
||||||
self.triangle(idx + 3 * i0 + 0, idx + 3 * i0 + 1, idx + 3 * i1 + 0);
|
frame.triangle(idx + 3 * i0 + 0, idx + 3 * i0 + 1, idx + 3 * i1 + 0);
|
||||||
self.triangle(idx + 3 * i0 + 1, idx + 3 * i1 + 0, idx + 3 * i1 + 1);
|
frame.triangle(idx + 3 * i0 + 1, idx + 3 * i1 + 0, idx + 3 * i1 + 1);
|
||||||
|
|
||||||
self.triangle(idx + 3 * i0 + 1, idx + 3 * i0 + 2, idx + 3 * i1 + 1);
|
frame.triangle(idx + 3 * i0 + 1, idx + 3 * i0 + 2, idx + 3 * i1 + 1);
|
||||||
self.triangle(idx + 3 * i0 + 2, idx + 3 * i1 + 1, idx + 3 * i1 + 2);
|
frame.triangle(idx + 3 * i0 + 2, idx + 3 * i1 + 1, idx + 3 * i1 + 2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let hw = (width - AA_SIZE) * 0.5;
|
let hw = (width - self.aa_size) * 0.5;
|
||||||
let p = points[i1 as usize];
|
let p = points[i1 as usize];
|
||||||
let n = normals[i1 as usize];
|
let n = normals[i1 as usize];
|
||||||
self.vertices
|
frame
|
||||||
.push(vert(p + n * (hw + AA_SIZE), color_outer));
|
.vertices
|
||||||
self.vertices.push(vert(p + n * (hw + 0.0), color_inner));
|
.push(vert(p + n * (hw + self.aa_size), color_outer));
|
||||||
self.vertices.push(vert(p - n * (hw + 0.0), color_inner));
|
frame.vertices.push(vert(p + n * (hw + 0.0), color_inner));
|
||||||
self.vertices
|
frame.vertices.push(vert(p - n * (hw + 0.0), color_inner));
|
||||||
.push(vert(p - n * (hw + AA_SIZE), color_outer));
|
frame
|
||||||
|
.vertices
|
||||||
|
.push(vert(p - n * (hw + self.aa_size), color_outer));
|
||||||
|
|
||||||
if connect_with_previous {
|
if connect_with_previous {
|
||||||
self.triangle(idx + 4 * i0 + 0, idx + 4 * i0 + 1, idx + 4 * i1 + 0);
|
frame.triangle(idx + 4 * i0 + 0, idx + 4 * i0 + 1, idx + 4 * i1 + 0);
|
||||||
self.triangle(idx + 4 * i0 + 1, idx + 4 * i1 + 0, idx + 4 * i1 + 1);
|
frame.triangle(idx + 4 * i0 + 1, idx + 4 * i1 + 0, idx + 4 * i1 + 1);
|
||||||
|
|
||||||
self.triangle(idx + 4 * i0 + 1, idx + 4 * i0 + 2, idx + 4 * i1 + 1);
|
frame.triangle(idx + 4 * i0 + 1, idx + 4 * i0 + 2, idx + 4 * i1 + 1);
|
||||||
self.triangle(idx + 4 * i0 + 2, idx + 4 * i1 + 1, idx + 4 * i1 + 2);
|
frame.triangle(idx + 4 * i0 + 2, idx + 4 * i1 + 1, idx + 4 * i1 + 2);
|
||||||
|
|
||||||
self.triangle(idx + 4 * i0 + 2, idx + 4 * i0 + 3, idx + 4 * i1 + 2);
|
frame.triangle(idx + 4 * i0 + 2, idx + 4 * i0 + 3, idx + 4 * i1 + 2);
|
||||||
self.triangle(idx + 4 * i0 + 3, idx + 4 * i1 + 2, idx + 4 * i1 + 3);
|
frame.triangle(idx + 4 * i0 + 3, idx + 4 * i1 + 2, idx + 4 * i1 + 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i0 = i1;
|
i0 = i1;
|
||||||
|
@ -178,12 +199,12 @@ impl Frame {
|
||||||
} else {
|
} else {
|
||||||
let last_index = if path_type == Closed { n } else { n - 1 };
|
let last_index = if path_type == Closed { n } else { n - 1 };
|
||||||
for i in 0..last_index {
|
for i in 0..last_index {
|
||||||
self.triangle(
|
frame.triangle(
|
||||||
idx + (2 * i + 0) % (2 * n),
|
idx + (2 * i + 0) % (2 * n),
|
||||||
idx + (2 * i + 1) % (2 * n),
|
idx + (2 * i + 1) % (2 * n),
|
||||||
idx + (2 * i + 2) % (2 * n),
|
idx + (2 * i + 2) % (2 * n),
|
||||||
);
|
);
|
||||||
self.triangle(
|
frame.triangle(
|
||||||
idx + (2 * i + 2) % (2 * n),
|
idx + (2 * i + 2) % (2 * n),
|
||||||
idx + (2 * i + 1) % (2 * n),
|
idx + (2 * i + 1) % (2 * n),
|
||||||
idx + (2 * i + 3) % (2 * n),
|
idx + (2 * i + 3) % (2 * n),
|
||||||
|
@ -191,17 +212,16 @@ impl Frame {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (&p, &n) in points.iter().zip(normals) {
|
for (&p, &n) in points.iter().zip(normals) {
|
||||||
self.vertices.push(vert(p + hw * n, color));
|
frame.vertices.push(vert(p + hw * n, color));
|
||||||
self.vertices.push(vert(p - hw * n, color));
|
frame.vertices.push(vert(p - hw * n, color));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint(fonts: &Fonts, commands: &[PaintCmd]) -> Frame {
|
pub fn paint(&mut self, fonts: &Fonts, commands: &[PaintCmd]) {
|
||||||
let mut path_points = Vec::new();
|
let mut path_points = Vec::new();
|
||||||
let mut path_normals = Vec::new();
|
let mut path_normals = Vec::new();
|
||||||
|
|
||||||
let mut frame = Frame::default();
|
|
||||||
for cmd in commands {
|
for cmd in commands {
|
||||||
match cmd {
|
match cmd {
|
||||||
PaintCmd::Circle {
|
PaintCmd::Circle {
|
||||||
|
@ -222,10 +242,10 @@ impl Frame {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(color) = fill_color {
|
if let Some(color) = fill_color {
|
||||||
frame.fill_closed_path(&path_points, &path_normals, *color);
|
self.fill_closed_path(&path_points, &path_normals, *color);
|
||||||
}
|
}
|
||||||
if let Some(outline) = outline {
|
if let Some(outline) = outline {
|
||||||
frame.paint_path(
|
self.paint_path(
|
||||||
Closed,
|
Closed,
|
||||||
&path_points,
|
&path_points,
|
||||||
&path_normals,
|
&path_normals,
|
||||||
|
@ -235,7 +255,7 @@ impl Frame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintCmd::Frame(cmd_frame) => {
|
PaintCmd::Frame(cmd_frame) => {
|
||||||
frame.append(cmd_frame);
|
self.frame.append(cmd_frame);
|
||||||
}
|
}
|
||||||
PaintCmd::Line {
|
PaintCmd::Line {
|
||||||
points,
|
points,
|
||||||
|
@ -261,7 +281,7 @@ impl Frame {
|
||||||
.rot90(),
|
.rot90(),
|
||||||
);
|
);
|
||||||
|
|
||||||
frame.paint_path(Open, &path_points, &path_normals, *color, *width);
|
self.paint_path(Open, &path_points, &path_normals, *color, *width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintCmd::Rect {
|
PaintCmd::Rect {
|
||||||
|
@ -315,10 +335,10 @@ impl Frame {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(color) = fill_color {
|
if let Some(color) = fill_color {
|
||||||
frame.fill_closed_path(&path_points, &path_normals, *color);
|
self.fill_closed_path(&path_points, &path_normals, *color);
|
||||||
}
|
}
|
||||||
if let Some(outline) = outline {
|
if let Some(outline) = outline {
|
||||||
frame.paint_path(
|
self.paint_path(
|
||||||
Closed,
|
Closed,
|
||||||
&path_points,
|
&path_points,
|
||||||
&path_normals,
|
&path_normals,
|
||||||
|
@ -349,12 +369,11 @@ impl Frame {
|
||||||
uv: glyph.max,
|
uv: glyph.max,
|
||||||
color: *color,
|
color: *color,
|
||||||
};
|
};
|
||||||
frame.add_rect(top_left, bottom_right);
|
self.frame.add_rect(top_left, bottom_right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
frame
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue