terminology: remove uses of the word "mesh". Prefer "triangles".
This commit is contained in:
parent
3ec552392f
commit
aeaa611005
8 changed files with 141 additions and 135 deletions
|
@ -98,7 +98,7 @@ Add extremely quick animations for some things, maybe 2-3 frames. For instance:
|
||||||
* [x] Combine Emigui and Context?
|
* [x] Combine Emigui and Context?
|
||||||
* [x] Solve which parts of Context are behind a mutex
|
* [x] Solve which parts of Context are behind a mutex
|
||||||
* [x] Rename Region to Ui
|
* [x] Rename Region to Ui
|
||||||
* [ ] Move Path and Mesh to own crate
|
* [ ] Move Path and Triangles to own crate
|
||||||
* [ ] Maybe find a shorter name for the library like `egui`?
|
* [ ] Maybe find a shorter name for the library like `egui`?
|
||||||
|
|
||||||
### Global widget search
|
### Global widget search
|
||||||
|
|
|
@ -19,7 +19,7 @@ struct PaintStats {
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
/// The default style for new `Ui`:s
|
/// The default style for new `Ui`:s
|
||||||
style: Mutex<Style>,
|
style: Mutex<Style>,
|
||||||
mesher_options: Mutex<mesher::MesherOptions>,
|
paint_options: Mutex<mesher::PaintOptions>,
|
||||||
fonts: Arc<Fonts>,
|
fonts: Arc<Fonts>,
|
||||||
/// HACK: set a new font next frame
|
/// HACK: set a new font next frame
|
||||||
new_fonts: Mutex<Option<Arc<Fonts>>>,
|
new_fonts: Mutex<Option<Arc<Fonts>>>,
|
||||||
|
@ -45,7 +45,7 @@ impl Clone for Context {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Context {
|
Context {
|
||||||
style: Mutex::new(self.style()),
|
style: Mutex::new(self.style()),
|
||||||
mesher_options: Mutex::new(*self.mesher_options.lock()),
|
paint_options: Mutex::new(*self.paint_options.lock()),
|
||||||
fonts: self.fonts.clone(),
|
fonts: self.fonts.clone(),
|
||||||
new_fonts: Mutex::new(self.new_fonts.lock().clone()),
|
new_fonts: Mutex::new(self.new_fonts.lock().clone()),
|
||||||
memory: self.memory.clone(),
|
memory: self.memory.clone(),
|
||||||
|
@ -65,7 +65,7 @@ impl Context {
|
||||||
pub fn new(pixels_per_point: f32) -> Arc<Context> {
|
pub fn new(pixels_per_point: f32) -> Arc<Context> {
|
||||||
Arc::new(Context {
|
Arc::new(Context {
|
||||||
style: Default::default(),
|
style: Default::default(),
|
||||||
mesher_options: Default::default(),
|
paint_options: Default::default(),
|
||||||
fonts: Arc::new(Fonts::new(pixels_per_point)),
|
fonts: Arc::new(Fonts::new(pixels_per_point)),
|
||||||
new_fonts: Default::default(),
|
new_fonts: Default::default(),
|
||||||
memory: Default::default(),
|
memory: Default::default(),
|
||||||
|
@ -214,20 +214,21 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(&self) -> PaintBatches {
|
fn paint(&self) -> PaintBatches {
|
||||||
let mut mesher_options = *self.mesher_options.lock();
|
let mut paint_options = *self.paint_options.lock();
|
||||||
mesher_options.aa_size = 1.0 / self.pixels_per_point();
|
paint_options.aa_size = 1.0 / self.pixels_per_point();
|
||||||
mesher_options.aa_size *= 1.5; // Looks better, but TODO: should not be needed
|
paint_options.aa_size *= 1.5; // Looks better, but TODO: should not be needed
|
||||||
let paint_commands = self.drain_paint_lists();
|
let paint_commands = self.drain_paint_lists();
|
||||||
let num_primitives = paint_commands.len();
|
let num_primitives = paint_commands.len();
|
||||||
let batches = mesher::mesh_paint_commands(mesher_options, self.fonts(), paint_commands);
|
let batches =
|
||||||
|
mesher::paint_commands_into_triangles(paint_options, self.fonts(), paint_commands);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut stats = PaintStats::default();
|
let mut stats = PaintStats::default();
|
||||||
stats.num_batches = batches.len();
|
stats.num_batches = batches.len();
|
||||||
stats.num_primitives = num_primitives;
|
stats.num_primitives = num_primitives;
|
||||||
for (_, mesh) in &batches {
|
for (_, triangles) in &batches {
|
||||||
stats.num_vertices += mesh.vertices.len();
|
stats.num_vertices += triangles.vertices.len();
|
||||||
stats.num_triangles += mesh.indices.len() / 3;
|
stats.num_triangles += triangles.indices.len() / 3;
|
||||||
}
|
}
|
||||||
*self.paint_stats.lock() = stats;
|
*self.paint_stats.lock() = stats;
|
||||||
}
|
}
|
||||||
|
@ -477,7 +478,7 @@ impl Context {
|
||||||
CollapsingHeader::new("Style")
|
CollapsingHeader::new("Style")
|
||||||
// .default_open()
|
// .default_open()
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
self.mesher_options.lock().ui(ui);
|
self.paint_options.lock().ui(ui);
|
||||||
self.style_ui(ui);
|
self.style_ui(ui);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -603,7 +604,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mesher::MesherOptions {
|
impl mesher::PaintOptions {
|
||||||
pub fn ui(&mut self, ui: &mut Ui) {
|
pub fn ui(&mut self, ui: &mut Ui) {
|
||||||
use crate::widgets::*;
|
use crate::widgets::*;
|
||||||
ui.add(Checkbox::new(&mut self.anti_alias, "Antialias"));
|
ui.add(Checkbox::new(&mut self.anti_alias, "Antialias"));
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub use {
|
||||||
layout::*,
|
layout::*,
|
||||||
math::*,
|
math::*,
|
||||||
memory::Memory,
|
memory::Memory,
|
||||||
mesher::{Mesh, PaintBatches, Vertex},
|
mesher::{PaintBatches, Triangles, Vertex},
|
||||||
movement_tracker::MovementTracker,
|
movement_tracker::MovementTracker,
|
||||||
style::Style,
|
style::Style,
|
||||||
texture_atlas::Texture,
|
texture_atlas::Texture,
|
||||||
|
|
|
@ -22,24 +22,24 @@ pub struct Vertex {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, serde_derive::Serialize)]
|
#[derive(Clone, Debug, Default, serde_derive::Serialize)]
|
||||||
pub struct Mesh {
|
pub struct Triangles {
|
||||||
/// Draw as triangles (i.e. the length is a multiple of three)
|
/// Draw as triangles (i.e. the length is a multiple of three)
|
||||||
pub indices: Vec<u32>,
|
pub indices: Vec<u32>,
|
||||||
pub vertices: Vec<Vertex>,
|
pub vertices: Vec<Vertex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Grouped by clip rectangles, in pixel coordinates
|
/// Grouped by clip rectangles, in pixel coordinates
|
||||||
pub type PaintBatches = Vec<(Rect, Mesh)>;
|
pub type PaintBatches = Vec<(Rect, Triangles)>;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
impl Mesh {
|
impl Triangles {
|
||||||
pub fn append(&mut self, mesh: &Mesh) {
|
pub fn append(&mut self, triangles: &Triangles) {
|
||||||
let index_offset = self.vertices.len() as u32;
|
let index_offset = self.vertices.len() as u32;
|
||||||
for index in &mesh.indices {
|
for index in &triangles.indices {
|
||||||
self.indices.push(index_offset + index);
|
self.indices.push(index_offset + index);
|
||||||
}
|
}
|
||||||
self.vertices.extend(mesh.vertices.iter());
|
self.vertices.extend(triangles.vertices.iter());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn triangle(&mut self, a: u32, b: u32, c: u32) {
|
fn triangle(&mut self, a: u32, b: u32, c: u32) {
|
||||||
|
@ -72,9 +72,10 @@ impl Mesh {
|
||||||
self.vertices.push(bottom_right);
|
self.vertices.push(bottom_right);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Split a large mesh into many small.
|
/// This is for platsform that only support 16-bit index buffers.
|
||||||
/// All the returned meshes will have indices that fit into u16.
|
/// Splits this mesh into many small if needed.
|
||||||
pub fn split_to_u16(self) -> Vec<Mesh> {
|
/// All the returned meshes will have indices that fit into a `u16`.
|
||||||
|
pub fn split_to_u16(self) -> Vec<Triangles> {
|
||||||
const MAX_SIZE: u32 = 1 << 16;
|
const MAX_SIZE: u32 = 1 << 16;
|
||||||
|
|
||||||
if self.vertices.len() < MAX_SIZE as usize {
|
if self.vertices.len() < MAX_SIZE as usize {
|
||||||
|
@ -113,7 +114,7 @@ impl Mesh {
|
||||||
MAX_SIZE
|
MAX_SIZE
|
||||||
);
|
);
|
||||||
|
|
||||||
output.push(Mesh {
|
output.push(Triangles {
|
||||||
indices: self.indices[span_start..index_cursor]
|
indices: self.indices[span_start..index_cursor]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|vi| vi - min_vindex)
|
.map(|vi| vi - min_vindex)
|
||||||
|
@ -276,14 +277,14 @@ pub enum PathType {
|
||||||
use self::PathType::{Closed, Open};
|
use self::PathType::{Closed, Open};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct MesherOptions {
|
pub struct PaintOptions {
|
||||||
pub anti_alias: bool,
|
pub anti_alias: bool,
|
||||||
/// Size of a pixel in points, e.g. 0.5
|
/// Size of a pixel in points, e.g. 0.5
|
||||||
pub aa_size: f32,
|
pub aa_size: f32,
|
||||||
pub debug_paint_clip_rects: bool,
|
pub debug_paint_clip_rects: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MesherOptions {
|
impl Default for PaintOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
anti_alias: true,
|
anti_alias: true,
|
||||||
|
@ -293,7 +294,12 @@ impl Default for MesherOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fill_closed_path(mesh: &mut Mesh, options: MesherOptions, path: &[PathPoint], color: Color) {
|
pub fn fill_closed_path(
|
||||||
|
triangles: &mut Triangles,
|
||||||
|
options: PaintOptions,
|
||||||
|
path: &[PathPoint],
|
||||||
|
color: Color,
|
||||||
|
) {
|
||||||
if color == color::TRANSPARENT {
|
if color == color::TRANSPARENT {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -306,34 +312,35 @@ pub fn fill_closed_path(mesh: &mut Mesh, options: MesherOptions, path: &[PathPoi
|
||||||
};
|
};
|
||||||
if options.anti_alias {
|
if options.anti_alias {
|
||||||
let color_outer = color::TRANSPARENT;
|
let color_outer = color::TRANSPARENT;
|
||||||
let idx_inner = mesh.vertices.len() as u32;
|
let idx_inner = triangles.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 {
|
||||||
mesh.triangle(idx_inner + 2 * (i - 1), idx_inner, idx_inner + 2 * i);
|
triangles.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 p1 = &path[i1 as usize];
|
let p1 = &path[i1 as usize];
|
||||||
let dm = p1.normal * options.aa_size * 0.5;
|
let dm = p1.normal * options.aa_size * 0.5;
|
||||||
mesh.vertices.push(vert(p1.pos - dm, color));
|
triangles.vertices.push(vert(p1.pos - dm, color));
|
||||||
mesh.vertices.push(vert(p1.pos + dm, color_outer));
|
triangles.vertices.push(vert(p1.pos + dm, color_outer));
|
||||||
mesh.triangle(idx_inner + i1 * 2, idx_inner + i0 * 2, idx_outer + 2 * i0);
|
triangles.triangle(idx_inner + i1 * 2, idx_inner + i0 * 2, idx_outer + 2 * i0);
|
||||||
mesh.triangle(idx_outer + i0 * 2, idx_outer + i1 * 2, idx_inner + 2 * i1);
|
triangles.triangle(idx_outer + i0 * 2, idx_outer + i1 * 2, idx_inner + 2 * i1);
|
||||||
i0 = i1;
|
i0 = i1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let idx = mesh.vertices.len() as u32;
|
let idx = triangles.vertices.len() as u32;
|
||||||
mesh.vertices
|
triangles
|
||||||
|
.vertices
|
||||||
.extend(path.iter().map(|p| vert(p.pos, color)));
|
.extend(path.iter().map(|p| vert(p.pos, color)));
|
||||||
for i in 2..n {
|
for i in 2..n {
|
||||||
mesh.triangle(idx, idx + i - 1, idx + i);
|
triangles.triangle(idx, idx + i - 1, idx + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint_path(
|
pub fn paint_path(
|
||||||
mesh: &mut Mesh,
|
triangles: &mut Triangles,
|
||||||
options: MesherOptions,
|
options: PaintOptions,
|
||||||
path_type: PathType,
|
path_type: PathType,
|
||||||
path: &[PathPoint],
|
path: &[PathPoint],
|
||||||
color: Color,
|
color: Color,
|
||||||
|
@ -344,7 +351,7 @@ pub fn paint_path(
|
||||||
}
|
}
|
||||||
|
|
||||||
let n = path.len() as u32;
|
let n = path.len() as u32;
|
||||||
let idx = mesh.vertices.len() as u32;
|
let idx = triangles.vertices.len() as u32;
|
||||||
|
|
||||||
let vert = |pos, color| Vertex {
|
let vert = |pos, color| Vertex {
|
||||||
pos,
|
pos,
|
||||||
|
@ -377,18 +384,20 @@ pub fn paint_path(
|
||||||
let p1 = &path[i1 as usize];
|
let p1 = &path[i1 as usize];
|
||||||
let p = p1.pos;
|
let p = p1.pos;
|
||||||
let n = p1.normal;
|
let n = p1.normal;
|
||||||
mesh.vertices
|
triangles
|
||||||
|
.vertices
|
||||||
.push(vert(p + n * options.aa_size, color_outer));
|
.push(vert(p + n * options.aa_size, color_outer));
|
||||||
mesh.vertices.push(vert(p, color_inner));
|
triangles.vertices.push(vert(p, color_inner));
|
||||||
mesh.vertices
|
triangles
|
||||||
|
.vertices
|
||||||
.push(vert(p - n * options.aa_size, color_outer));
|
.push(vert(p - n * options.aa_size, color_outer));
|
||||||
|
|
||||||
if connect_with_previous {
|
if connect_with_previous {
|
||||||
mesh.triangle(idx + 3 * i0 + 0, idx + 3 * i0 + 1, idx + 3 * i1 + 0);
|
triangles.triangle(idx + 3 * i0 + 0, idx + 3 * i0 + 1, idx + 3 * i1 + 0);
|
||||||
mesh.triangle(idx + 3 * i0 + 1, idx + 3 * i1 + 0, idx + 3 * i1 + 1);
|
triangles.triangle(idx + 3 * i0 + 1, idx + 3 * i1 + 0, idx + 3 * i1 + 1);
|
||||||
|
|
||||||
mesh.triangle(idx + 3 * i0 + 1, idx + 3 * i0 + 2, idx + 3 * i1 + 1);
|
triangles.triangle(idx + 3 * i0 + 1, idx + 3 * i0 + 2, idx + 3 * i1 + 1);
|
||||||
mesh.triangle(idx + 3 * i0 + 2, idx + 3 * i1 + 1, idx + 3 * i1 + 2);
|
triangles.triangle(idx + 3 * i0 + 2, idx + 3 * i1 + 1, idx + 3 * i1 + 2);
|
||||||
}
|
}
|
||||||
i0 = i1;
|
i0 = i1;
|
||||||
}
|
}
|
||||||
|
@ -413,20 +422,28 @@ pub fn paint_path(
|
||||||
let p1 = &path[i1 as usize];
|
let p1 = &path[i1 as usize];
|
||||||
let p = p1.pos;
|
let p = p1.pos;
|
||||||
let n = p1.normal;
|
let n = p1.normal;
|
||||||
mesh.vertices.push(vert(p + n * outer_rad, color_outer));
|
triangles
|
||||||
mesh.vertices.push(vert(p + n * inner_rad, color_inner));
|
.vertices
|
||||||
mesh.vertices.push(vert(p - n * inner_rad, color_inner));
|
.push(vert(p + n * outer_rad, color_outer));
|
||||||
mesh.vertices.push(vert(p - n * outer_rad, color_outer));
|
triangles
|
||||||
|
.vertices
|
||||||
|
.push(vert(p + n * inner_rad, color_inner));
|
||||||
|
triangles
|
||||||
|
.vertices
|
||||||
|
.push(vert(p - n * inner_rad, color_inner));
|
||||||
|
triangles
|
||||||
|
.vertices
|
||||||
|
.push(vert(p - n * outer_rad, color_outer));
|
||||||
|
|
||||||
if connect_with_previous {
|
if connect_with_previous {
|
||||||
mesh.triangle(idx + 4 * i0 + 0, idx + 4 * i0 + 1, idx + 4 * i1 + 0);
|
triangles.triangle(idx + 4 * i0 + 0, idx + 4 * i0 + 1, idx + 4 * i1 + 0);
|
||||||
mesh.triangle(idx + 4 * i0 + 1, idx + 4 * i1 + 0, idx + 4 * i1 + 1);
|
triangles.triangle(idx + 4 * i0 + 1, idx + 4 * i1 + 0, idx + 4 * i1 + 1);
|
||||||
|
|
||||||
mesh.triangle(idx + 4 * i0 + 1, idx + 4 * i0 + 2, idx + 4 * i1 + 1);
|
triangles.triangle(idx + 4 * i0 + 1, idx + 4 * i0 + 2, idx + 4 * i1 + 1);
|
||||||
mesh.triangle(idx + 4 * i0 + 2, idx + 4 * i1 + 1, idx + 4 * i1 + 2);
|
triangles.triangle(idx + 4 * i0 + 2, idx + 4 * i1 + 1, idx + 4 * i1 + 2);
|
||||||
|
|
||||||
mesh.triangle(idx + 4 * i0 + 2, idx + 4 * i0 + 3, idx + 4 * i1 + 2);
|
triangles.triangle(idx + 4 * i0 + 2, idx + 4 * i0 + 3, idx + 4 * i1 + 2);
|
||||||
mesh.triangle(idx + 4 * i0 + 3, idx + 4 * i1 + 2, idx + 4 * i1 + 3);
|
triangles.triangle(idx + 4 * i0 + 3, idx + 4 * i1 + 2, idx + 4 * i1 + 3);
|
||||||
}
|
}
|
||||||
i0 = i1;
|
i0 = i1;
|
||||||
}
|
}
|
||||||
|
@ -434,12 +451,12 @@ pub fn paint_path(
|
||||||
} 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 {
|
||||||
mesh.triangle(
|
triangles.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),
|
||||||
);
|
);
|
||||||
mesh.triangle(
|
triangles.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),
|
||||||
|
@ -455,14 +472,22 @@ pub fn paint_path(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for p in path {
|
for p in path {
|
||||||
mesh.vertices.push(vert(p.pos + radius * p.normal, color));
|
triangles
|
||||||
mesh.vertices.push(vert(p.pos - radius * p.normal, color));
|
.vertices
|
||||||
|
.push(vert(p.pos + radius * p.normal, color));
|
||||||
|
triangles
|
||||||
|
.vertices
|
||||||
|
.push(vert(p.pos - radius * p.normal, color));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let radius = width / 2.0;
|
let radius = width / 2.0;
|
||||||
for p in path {
|
for p in path {
|
||||||
mesh.vertices.push(vert(p.pos + radius * p.normal, color));
|
triangles
|
||||||
mesh.vertices.push(vert(p.pos - radius * p.normal, color));
|
.vertices
|
||||||
|
.push(vert(p.pos + radius * p.normal, color));
|
||||||
|
triangles
|
||||||
|
.vertices
|
||||||
|
.push(vert(p.pos - radius * p.normal, color));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,14 +506,15 @@ fn mul_color(color: Color, factor: f32) -> Color {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// path: only used to reuse memory
|
/// `reused_path`: only used to reuse memory
|
||||||
pub fn mesh_command(
|
pub fn paint_command_into_triangles(
|
||||||
path: &mut Path,
|
reused_path: &mut Path,
|
||||||
options: MesherOptions,
|
options: PaintOptions,
|
||||||
fonts: &Fonts,
|
fonts: &Fonts,
|
||||||
command: PaintCmd,
|
command: PaintCmd,
|
||||||
out_mesh: &mut Mesh,
|
out: &mut Triangles,
|
||||||
) {
|
) {
|
||||||
|
let path = reused_path;
|
||||||
path.clear();
|
path.clear();
|
||||||
|
|
||||||
match command {
|
match command {
|
||||||
|
@ -500,21 +526,14 @@ pub fn mesh_command(
|
||||||
} => {
|
} => {
|
||||||
path.add_circle(center, radius);
|
path.add_circle(center, radius);
|
||||||
if let Some(color) = fill_color {
|
if let Some(color) = fill_color {
|
||||||
fill_closed_path(out_mesh, options, &path.0, color);
|
fill_closed_path(out, options, &path.0, color);
|
||||||
}
|
}
|
||||||
if let Some(outline) = outline {
|
if let Some(outline) = outline {
|
||||||
paint_path(
|
paint_path(out, options, Closed, &path.0, outline.color, outline.width);
|
||||||
out_mesh,
|
|
||||||
options,
|
|
||||||
Closed,
|
|
||||||
&path.0,
|
|
||||||
outline.color,
|
|
||||||
outline.width,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintCmd::Mesh(mesh) => {
|
PaintCmd::Triangles(triangles) => {
|
||||||
out_mesh.append(&mesh);
|
out.append(&triangles);
|
||||||
}
|
}
|
||||||
PaintCmd::LineSegment {
|
PaintCmd::LineSegment {
|
||||||
points,
|
points,
|
||||||
|
@ -522,7 +541,7 @@ pub fn mesh_command(
|
||||||
width,
|
width,
|
||||||
} => {
|
} => {
|
||||||
path.add_line_segment(points);
|
path.add_line_segment(points);
|
||||||
paint_path(out_mesh, options, Open, &path.0, color, width);
|
paint_path(out, options, Open, &path.0, color, width);
|
||||||
}
|
}
|
||||||
PaintCmd::LinePath {
|
PaintCmd::LinePath {
|
||||||
points,
|
points,
|
||||||
|
@ -532,7 +551,7 @@ pub fn mesh_command(
|
||||||
let n = points.len();
|
let n = points.len();
|
||||||
if n >= 2 {
|
if n >= 2 {
|
||||||
path.add_line(&points);
|
path.add_line(&points);
|
||||||
paint_path(out_mesh, options, Open, &path.0, color, width);
|
paint_path(out, options, Open, &path.0, color, width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintCmd::Path {
|
PaintCmd::Path {
|
||||||
|
@ -546,18 +565,11 @@ pub fn mesh_command(
|
||||||
closed,
|
closed,
|
||||||
"You asked to fill a path that is not closed. That makes no sense."
|
"You asked to fill a path that is not closed. That makes no sense."
|
||||||
);
|
);
|
||||||
fill_closed_path(out_mesh, options, &path.0, fill_color);
|
fill_closed_path(out, options, &path.0, fill_color);
|
||||||
}
|
}
|
||||||
if let Some(outline) = outline {
|
if let Some(outline) = outline {
|
||||||
let typ = if closed { Closed } else { Open };
|
let typ = if closed { Closed } else { Open };
|
||||||
paint_path(
|
paint_path(out, options, typ, &path.0, outline.color, outline.width);
|
||||||
out_mesh,
|
|
||||||
options,
|
|
||||||
typ,
|
|
||||||
&path.0,
|
|
||||||
outline.color,
|
|
||||||
outline.width,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintCmd::Rect {
|
PaintCmd::Rect {
|
||||||
|
@ -573,17 +585,10 @@ pub fn mesh_command(
|
||||||
|
|
||||||
path.add_rounded_rectangle(rect, corner_radius);
|
path.add_rounded_rectangle(rect, corner_radius);
|
||||||
if let Some(fill_color) = fill_color {
|
if let Some(fill_color) = fill_color {
|
||||||
fill_closed_path(out_mesh, options, &path.0, fill_color);
|
fill_closed_path(out, options, &path.0, fill_color);
|
||||||
}
|
}
|
||||||
if let Some(outline) = outline {
|
if let Some(outline) = outline {
|
||||||
paint_path(
|
paint_path(out, options, Closed, &path.0, outline.color, outline.width);
|
||||||
out_mesh,
|
|
||||||
options,
|
|
||||||
Closed,
|
|
||||||
&path.0,
|
|
||||||
outline.color,
|
|
||||||
outline.width,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PaintCmd::Text {
|
PaintCmd::Text {
|
||||||
|
@ -614,7 +619,7 @@ pub fn mesh_command(
|
||||||
uv: glyph.max,
|
uv: glyph.max,
|
||||||
color,
|
color,
|
||||||
};
|
};
|
||||||
out_mesh.add_rect(top_left, bottom_right);
|
out.add_rect(top_left, bottom_right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,11 +628,12 @@ pub fn mesh_command(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mesh_paint_commands(
|
/// Turns `PaintCmd`:s into sets of triangles
|
||||||
options: MesherOptions,
|
pub fn paint_commands_into_triangles(
|
||||||
|
options: PaintOptions,
|
||||||
fonts: &Fonts,
|
fonts: &Fonts,
|
||||||
commands: Vec<(Rect, PaintCmd)>,
|
commands: Vec<(Rect, PaintCmd)>,
|
||||||
) -> Vec<(Rect, Mesh)> {
|
) -> Vec<(Rect, Triangles)> {
|
||||||
let mut reused_path = Path::default();
|
let mut reused_path = Path::default();
|
||||||
|
|
||||||
let mut batches = PaintBatches::default();
|
let mut batches = PaintBatches::default();
|
||||||
|
@ -635,16 +641,16 @@ pub fn mesh_paint_commands(
|
||||||
// TODO: cull(clip_rect, cmd)
|
// TODO: cull(clip_rect, cmd)
|
||||||
|
|
||||||
if batches.is_empty() || batches.last().unwrap().0 != clip_rect {
|
if batches.is_empty() || batches.last().unwrap().0 != clip_rect {
|
||||||
batches.push((clip_rect, Mesh::default()));
|
batches.push((clip_rect, Triangles::default()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let out_mesh = &mut batches.last_mut().unwrap().1;
|
let out = &mut batches.last_mut().unwrap().1;
|
||||||
mesh_command(&mut reused_path, options, fonts, cmd, out_mesh);
|
paint_command_into_triangles(&mut reused_path, options, fonts, cmd, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.debug_paint_clip_rects {
|
if options.debug_paint_clip_rects {
|
||||||
for (clip_rect, mesh) in &mut batches {
|
for (clip_rect, triangles) in &mut batches {
|
||||||
mesh_command(
|
paint_command_into_triangles(
|
||||||
&mut reused_path,
|
&mut reused_path,
|
||||||
options,
|
options,
|
||||||
fonts,
|
fonts,
|
||||||
|
@ -654,7 +660,7 @@ pub fn mesh_paint_commands(
|
||||||
fill_color: None,
|
fill_color: None,
|
||||||
outline: Some(Outline::new(2.0, srgba(150, 255, 150, 255))),
|
outline: Some(Outline::new(2.0, srgba(150, 255, 150, 255))),
|
||||||
},
|
},
|
||||||
mesh,
|
triangles,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ impl TextureAtlas {
|
||||||
impl Texture {
|
impl Texture {
|
||||||
pub fn ui(&self, ui: &mut crate::Ui) {
|
pub fn ui(&self, ui: &mut crate::Ui) {
|
||||||
use crate::{
|
use crate::{
|
||||||
color::WHITE, containers::show_tooltip, label, math::*, Mesh, PaintCmd, Vertex,
|
color::WHITE, containers::show_tooltip, label, math::*, PaintCmd, Triangles, Vertex,
|
||||||
};
|
};
|
||||||
|
|
||||||
ui.add(label!(
|
ui.add(label!(
|
||||||
|
@ -117,9 +117,9 @@ impl Texture {
|
||||||
uv: (self.width as u16 - 1, self.height as u16 - 1),
|
uv: (self.width as u16 - 1, self.height as u16 - 1),
|
||||||
color: WHITE,
|
color: WHITE,
|
||||||
};
|
};
|
||||||
let mut mesh = Mesh::default();
|
let mut triangles = Triangles::default();
|
||||||
mesh.add_rect(top_left, bottom_right);
|
triangles.add_rect(top_left, bottom_right);
|
||||||
ui.add_paint_cmd(PaintCmd::Mesh(mesh));
|
ui.add_paint_cmd(PaintCmd::Triangles(triangles));
|
||||||
|
|
||||||
if interact.hovered {
|
if interact.hovered {
|
||||||
show_tooltip(ui.ctx(), |ui| {
|
show_tooltip(ui.ctx(), |ui| {
|
||||||
|
@ -142,9 +142,9 @@ impl Texture {
|
||||||
uv: ((u + texel_radius) as u16, (v + texel_radius) as u16),
|
uv: ((u + texel_radius) as u16, (v + texel_radius) as u16),
|
||||||
color: WHITE,
|
color: WHITE,
|
||||||
};
|
};
|
||||||
let mut mesh = Mesh::default();
|
let mut triangles = Triangles::default();
|
||||||
mesh.add_rect(top_left, bottom_right);
|
triangles.add_rect(top_left, bottom_right);
|
||||||
ui.add_paint_cmd(PaintCmd::Mesh(mesh));
|
ui.add_paint_cmd(PaintCmd::Triangles(triangles));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
font::Galley,
|
font::Galley,
|
||||||
fonts::TextStyle,
|
fonts::TextStyle,
|
||||||
math::{Pos2, Rect},
|
math::{Pos2, Rect},
|
||||||
mesher::{Mesh, Path},
|
mesher::{Path, Triangles},
|
||||||
Context, Ui,
|
Context, Ui,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,8 +174,7 @@ pub enum PaintCmd {
|
||||||
text_style: TextStyle, // TODO: Font?
|
text_style: TextStyle, // TODO: Font?
|
||||||
color: Color,
|
color: Color,
|
||||||
},
|
},
|
||||||
/// Low-level triangle mesh
|
Triangles(Triangles),
|
||||||
Mesh(Mesh),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaintCmd {
|
impl PaintCmd {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![allow(deprecated)] // legacy implement_vertex macro
|
#![allow(deprecated)] // legacy implement_vertex macro
|
||||||
|
|
||||||
use {
|
use {
|
||||||
emigui::{Mesh, PaintBatches, Rect},
|
emigui::{PaintBatches, Rect, Triangles},
|
||||||
glium::{implement_vertex, index::PrimitiveType, program, texture, uniform, Frame, Surface},
|
glium::{implement_vertex, index::PrimitiveType, program, texture, uniform, Frame, Surface},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -220,8 +220,8 @@ impl Painter {
|
||||||
|
|
||||||
let mut target = display.draw();
|
let mut target = display.draw();
|
||||||
target.clear_color(0.0, 0.0, 0.0, 0.0);
|
target.clear_color(0.0, 0.0, 0.0, 0.0);
|
||||||
for (clip_rect, mesh) in batches {
|
for (clip_rect, triangles) in batches {
|
||||||
self.paint_batch(&mut target, display, clip_rect, &mesh, texture)
|
self.paint_batch(&mut target, display, clip_rect, &triangles, texture)
|
||||||
}
|
}
|
||||||
target.finish().unwrap();
|
target.finish().unwrap();
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ impl Painter {
|
||||||
target: &mut Frame,
|
target: &mut Frame,
|
||||||
display: &glium::Display,
|
display: &glium::Display,
|
||||||
clip_rect: Rect,
|
clip_rect: Rect,
|
||||||
mesh: &Mesh,
|
triangles: &Triangles,
|
||||||
texture: &emigui::Texture,
|
texture: &emigui::Texture,
|
||||||
) {
|
) {
|
||||||
let vertex_buffer = {
|
let vertex_buffer = {
|
||||||
|
@ -244,7 +244,7 @@ impl Painter {
|
||||||
}
|
}
|
||||||
implement_vertex!(Vertex, a_pos, a_color, a_tc);
|
implement_vertex!(Vertex, a_pos, a_color, a_tc);
|
||||||
|
|
||||||
let vertices: Vec<Vertex> = mesh
|
let vertices: Vec<Vertex> = triangles
|
||||||
.vertices
|
.vertices
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| Vertex {
|
.map(|v| Vertex {
|
||||||
|
@ -257,7 +257,7 @@ impl Painter {
|
||||||
glium::VertexBuffer::new(display, &vertices).unwrap()
|
glium::VertexBuffer::new(display, &vertices).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let indices: Vec<u32> = mesh.indices.iter().map(|idx| *idx as u32).collect();
|
let indices: Vec<u32> = triangles.indices.iter().map(|idx| *idx as u32).collect();
|
||||||
|
|
||||||
let index_buffer =
|
let index_buffer =
|
||||||
glium::IndexBuffer::new(display, PrimitiveType::TrianglesList, &indices).unwrap();
|
glium::IndexBuffer::new(display, PrimitiveType::TrianglesList, &indices).unwrap();
|
||||||
|
|
|
@ -4,7 +4,7 @@ use {
|
||||||
web_sys::{WebGlBuffer, WebGlProgram, WebGlRenderingContext, WebGlShader, WebGlTexture},
|
web_sys::{WebGlBuffer, WebGlProgram, WebGlRenderingContext, WebGlShader, WebGlTexture},
|
||||||
};
|
};
|
||||||
|
|
||||||
use emigui::{vec2, Color, Mesh, PaintBatches, Pos2, Texture};
|
use emigui::{vec2, Color, PaintBatches, Pos2, Texture, Triangles};
|
||||||
|
|
||||||
type Gl = WebGlRenderingContext;
|
type Gl = WebGlRenderingContext;
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ impl Painter {
|
||||||
);
|
);
|
||||||
gl.clear(Gl::COLOR_BUFFER_BIT);
|
gl.clear(Gl::COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
for (clip_rect, mesh) in batches {
|
for (clip_rect, triangles) in batches {
|
||||||
// Avoid infinities in shader:
|
// Avoid infinities in shader:
|
||||||
let clip_min = clip_rect.min.max(Pos2::default());
|
let clip_min = clip_rect.min.max(Pos2::default());
|
||||||
let clip_max = clip_rect.max.min(Pos2::default() + screen_size_points);
|
let clip_max = clip_rect.max.min(Pos2::default() + screen_size_points);
|
||||||
|
@ -222,27 +222,27 @@ impl Painter {
|
||||||
clip_max.y,
|
clip_max.y,
|
||||||
);
|
);
|
||||||
|
|
||||||
for mesh in mesh.split_to_u16() {
|
for triangles in triangles.split_to_u16() {
|
||||||
self.paint_mesh(&mesh)?;
|
self.paint_triangles(&triangles)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_mesh(&self, mesh: &Mesh) -> Result<(), JsValue> {
|
fn paint_triangles(&self, triangles: &Triangles) -> Result<(), JsValue> {
|
||||||
let indices: Vec<u16> = mesh.indices.iter().map(|idx| *idx as u16).collect();
|
let indices: Vec<u16> = triangles.indices.iter().map(|idx| *idx as u16).collect();
|
||||||
|
|
||||||
let mut positions: Vec<f32> = Vec::with_capacity(2 * mesh.vertices.len());
|
let mut positions: Vec<f32> = Vec::with_capacity(2 * triangles.vertices.len());
|
||||||
let mut tex_coords: Vec<u16> = Vec::with_capacity(2 * mesh.vertices.len());
|
let mut tex_coords: Vec<u16> = Vec::with_capacity(2 * triangles.vertices.len());
|
||||||
for v in &mesh.vertices {
|
for v in &triangles.vertices {
|
||||||
positions.push(v.pos.x);
|
positions.push(v.pos.x);
|
||||||
positions.push(v.pos.y);
|
positions.push(v.pos.y);
|
||||||
tex_coords.push(v.uv.0);
|
tex_coords.push(v.uv.0);
|
||||||
tex_coords.push(v.uv.1);
|
tex_coords.push(v.uv.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut colors: Vec<u8> = Vec::with_capacity(4 * mesh.vertices.len());
|
let mut colors: Vec<u8> = Vec::with_capacity(4 * triangles.vertices.len());
|
||||||
for v in &mesh.vertices {
|
for v in &triangles.vertices {
|
||||||
colors.push(v.color.r);
|
colors.push(v.color.r);
|
||||||
colors.push(v.color.g);
|
colors.push(v.color.g);
|
||||||
colors.push(v.color.b);
|
colors.push(v.color.b);
|
||||||
|
|
Loading…
Reference in a new issue