Learn how to spell to "tessellation"

This commit is contained in:
Emil Ernerfeldt 2020-12-29 00:51:27 +01:00
parent 19b4d87c65
commit d38b16f1ea
10 changed files with 43 additions and 43 deletions

View file

@ -135,7 +135,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* Refactored the interface for `egui::app::App`. * Refactored the interface for `egui::app::App`.
* Windows are now constrained to the screen. * Windows are now constrained to the screen.
* `Context::begin_frame()` no longer returns a `Ui`. Instead put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`. * `Context::begin_frame()` no longer returns a `Ui`. Instead put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
* `Context::end_frame()` now returns paint commands that need to be converted to triangles with `Context::tesselate()`. * `Context::end_frame()` now returns paint commands that need to be converted to triangles with `Context::tessellate()`.
* Anti-aliasing is now off by default in debug builds. * Anti-aliasing is now off by default in debug builds.
### Removed 🔥 ### Removed 🔥
@ -153,7 +153,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* Unicode characters in labels (limited by [what the default font supports](https://fonts.google.com/specimen/Comfortaa#glyphs)) * Unicode characters in labels (limited by [what the default font supports](https://fonts.google.com/specimen/Comfortaa#glyphs))
* Simple drop-down combo box menu * Simple drop-down combo box menu
* Logarithmic sliders * Logarithmic sliders
* Optimization: coarse culling in the tesselator * Optimization: coarse culling in the tessellator
* CHANGED: switch argument order of `ui.checkbox` and `ui.radio` * CHANGED: switch argument order of `ui.checkbox` and `ui.radio`
## 0.1.4 - 2020-09-08 ## 0.1.4 - 2020-09-08

View file

@ -131,7 +131,7 @@ Loop:
* Gather input (mouse, touches, keyboard, screen size, etc) and give it to Egui * Gather input (mouse, touches, keyboard, screen size, etc) and give it to Egui
* Run application code (Immediate Mode GUI) * Run application code (Immediate Mode GUI)
* Tell Egui to tesselate the frame graphics to a triangle mesh * Tell Egui to tessellate the frame graphics to a triangle mesh
* Render the triangle mesh with your favorite graphics API (see [OpenGL example](https://github.com/emilk/egui/blob/master/egui_glium/src/painter.rs)) * Render the triangle mesh with your favorite graphics API (see [OpenGL example](https://github.com/emilk/egui/blob/master/egui_glium/src/painter.rs))
## Integrations ## Integrations
@ -174,7 +174,7 @@ loop {
egui_ctx.begin_frame(raw_input); egui_ctx.begin_frame(raw_input);
my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here
let (output, paint_commands) = egui_ctx.end_frame(); let (output, paint_commands) = egui_ctx.end_frame();
let paint_jobs = egui_ctx.tesselate(paint_commands); // create triangles to paint let paint_jobs = egui_ctx.tessellate(paint_commands); // create triangles to paint
my_integration.paint(paint_jobs); my_integration.paint(paint_jobs);
my_integration.set_cursor_icon(output.cursor_icon); my_integration.set_cursor_icon(output.cursor_icon);
// Also see `egui::Output` for more // Also see `egui::Output` for more

View file

@ -38,8 +38,8 @@ pub fn criterion_benchmark(c: &mut Criterion) {
demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {}); demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {});
let (_, paint_commands) = ctx.end_frame(); let (_, paint_commands) = ctx.end_frame();
c.bench_function("tesselate", |b| { c.bench_function("tessellate", |b| {
b.iter(|| ctx.tesselate(paint_commands.clone())) b.iter(|| ctx.tessellate(paint_commands.clone()))
}); });
} }

View file

@ -17,7 +17,7 @@ struct Options {
/// The default style for new `Ui`:s. /// The default style for new `Ui`:s.
style: Arc<Style>, style: Arc<Style>,
/// Controls the tessellator. /// Controls the tessellator.
tesselation_options: paint::TesselationOptions, tessellation_options: paint::TessellationOptions,
/// Font sizes etc. /// Font sizes etc.
font_definitions: FontDefinitions, font_definitions: FontDefinitions,
} }
@ -577,7 +577,7 @@ impl Context {
/// Call at the end of each frame. /// Call at the end of each frame.
/// Returns what has happened this frame (`Output`) as well as what you need to paint. /// Returns what has happened this frame (`Output`) as well as what you need to paint.
/// You can transform the returned paint commands into triangles with a call to /// You can transform the returned paint commands into triangles with a call to
/// `Context::tesselate`. /// `Context::tessellate`.
#[must_use] #[must_use]
pub fn end_frame(&self) -> (Output, Vec<(Rect, PaintCmd)>) { pub fn end_frame(&self) -> (Output, Vec<(Rect, PaintCmd)>) {
if self.input.wants_repaint() { if self.input.wants_repaint() {
@ -601,14 +601,14 @@ impl Context {
self.graphics().drain(memory.areas.order()).collect() self.graphics().drain(memory.areas.order()).collect()
} }
/// Tesselate the given paint commands into triangle meshes. /// Tessellate the given paint commands into triangle meshes.
pub fn tesselate(&self, paint_commands: Vec<(Rect, PaintCmd)>) -> PaintJobs { pub fn tessellate(&self, paint_commands: Vec<(Rect, PaintCmd)>) -> PaintJobs {
let mut tesselation_options = self.options.lock().tesselation_options; let mut tessellation_options = self.options.lock().tessellation_options;
tesselation_options.aa_size = 1.0 / self.pixels_per_point(); tessellation_options.aa_size = 1.0 / self.pixels_per_point();
let paint_stats = PaintStats::from_paint_commands(&paint_commands); // TODO: internal allocations let paint_stats = PaintStats::from_paint_commands(&paint_commands); // TODO: internal allocations
let paint_jobs = tessellator::tessellate_paint_commands( let paint_jobs = tessellator::tessellate_paint_commands(
paint_commands, paint_commands,
tesselation_options, tessellation_options,
self.fonts(), self.fonts(),
); );
*self.paint_stats.lock() = paint_stats.with_paint_jobs(&paint_jobs); *self.paint_stats.lock() = paint_stats.with_paint_jobs(&paint_jobs);
@ -732,9 +732,9 @@ impl Context {
CollapsingHeader::new("✒ Painting") CollapsingHeader::new("✒ Painting")
.default_open(true) .default_open(true)
.show(ui, |ui| { .show(ui, |ui| {
let mut tesselation_options = self.options.lock().tesselation_options; let mut tessellation_options = self.options.lock().tessellation_options;
tesselation_options.ui(ui); tessellation_options.ui(ui);
self.options.lock().tesselation_options = tesselation_options; self.options.lock().tessellation_options = tessellation_options;
}); });
} }
@ -849,7 +849,7 @@ impl Context {
} }
} }
impl paint::TesselationOptions { impl paint::TessellationOptions {
pub fn ui(&mut self, ui: &mut Ui) { pub fn ui(&mut self, ui: &mut Ui) {
let Self { let Self {
aa_size: _, aa_size: _,

View file

@ -87,7 +87,7 @@ impl FrameHistory {
1e3 * self.mean_frame_time() 1e3 * self.mean_frame_time()
)) ))
.on_hover_text( .on_hover_text(
"Includes Egui layout and tesselation time.\n\ "Includes Egui layout and tessellation time.\n\
Does not include GPU usage, nor overhead for sending data to GPU.", Does not include GPU usage, nor overhead for sending data to GPU.",
); );
crate::demos::warn_if_debug_build(ui); crate::demos::warn_if_debug_build(ui);

View file

@ -27,7 +27,7 @@
//! egui_ctx.begin_frame(raw_input); //! egui_ctx.begin_frame(raw_input);
//! my_app.ui(&egui_ctx); // add panels, windows and widgets to `egui_ctx` here //! my_app.ui(&egui_ctx); // add panels, windows and widgets to `egui_ctx` here
//! let (output, paint_commands) = egui_ctx.end_frame(); //! let (output, paint_commands) = egui_ctx.end_frame();
//! let paint_jobs = egui_ctx.tesselate(paint_commands); // create triangles to paint //! let paint_jobs = egui_ctx.tessellate(paint_commands); // create triangles to paint
//! my_integration.paint(paint_jobs); //! my_integration.paint(paint_jobs);
//! my_integration.set_cursor_icon(output.cursor_icon); //! my_integration.set_cursor_icon(output.cursor_icon);
//! // Also see `egui::Output` for more //! // Also see `egui::Output` for more
@ -143,7 +143,7 @@ fn test_egui_e2e() {
ctx.begin_frame(raw_input.clone()); ctx.begin_frame(raw_input.clone());
demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {}); demo_windows.ui(&ctx, &Default::default(), &mut None, |_ui| {});
let (_output, paint_commands) = ctx.end_frame(); let (_output, paint_commands) = ctx.end_frame();
let paint_jobs = ctx.tesselate(paint_commands); let paint_jobs = ctx.tessellate(paint_commands);
assert!(!paint_jobs.is_empty()); assert!(!paint_jobs.is_empty());
} }
} }

View file

@ -1,4 +1,4 @@
//! 2D graphics/rendering. Fonts, textures, color, geometry, tesselation etc. //! 2D graphics/rendering. Fonts, textures, color, geometry, tessellation etc.
pub mod color; pub mod color;
pub mod command; pub mod command;
@ -16,7 +16,7 @@ pub use {
galley::*, galley::*,
stats::PaintStats, stats::PaintStats,
tessellator::{ tessellator::{
PaintJob, PaintJobs, TesselationOptions, TextureId, Triangles, Vertex, WHITE_UV, PaintJob, PaintJobs, TessellationOptions, TextureId, Triangles, Vertex, WHITE_UV,
}, },
texture_atlas::{Texture, TextureAtlas}, texture_atlas::{Texture, TextureAtlas},
}; };

View file

@ -273,7 +273,7 @@ pub struct PathPoint {
/// A connected line (without thickness or gaps) which can be tessellated /// A connected line (without thickness or gaps) which can be tessellated
/// to either to a stroke (with thickness) or a filled convex area. /// to either to a stroke (with thickness) or a filled convex area.
/// Used as a scratch-pad during tesselation. /// Used as a scratch-pad during tessellation.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
struct Path(Vec<PathPoint>); struct Path(Vec<PathPoint>);
@ -445,9 +445,9 @@ pub enum PathType {
} }
use self::PathType::{Closed, Open}; use self::PathType::{Closed, Open};
/// Tesselation quality options /// Tessellation quality options
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct TesselationOptions { pub struct TessellationOptions {
/// 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,
/// Anti-aliasing makes shapes appear smoother, but requires more triangles and is therefore slower. /// Anti-aliasing makes shapes appear smoother, but requires more triangles and is therefore slower.
@ -461,7 +461,7 @@ pub struct TesselationOptions {
pub debug_ignore_clip_rects: bool, pub debug_ignore_clip_rects: bool,
} }
impl Default for TesselationOptions { impl Default for TessellationOptions {
fn default() -> Self { fn default() -> Self {
Self { Self {
aa_size: 1.0, aa_size: 1.0,
@ -473,11 +473,11 @@ impl Default for TesselationOptions {
} }
} }
/// Tesselate the given convex area into a polygon. /// Tessellate the given convex area into a polygon.
fn fill_closed_path( fn fill_closed_path(
path: &[PathPoint], path: &[PathPoint],
color: Srgba, color: Srgba,
options: TesselationOptions, options: TessellationOptions,
out: &mut Triangles, out: &mut Triangles,
) { ) {
if color == color::TRANSPARENT { if color == color::TRANSPARENT {
@ -518,12 +518,12 @@ fn fill_closed_path(
} }
} }
/// Tesselate the given path as a stroke with thickness. /// Tessellate the given path as a stroke with thickness.
fn stroke_path( fn stroke_path(
path: &[PathPoint], path: &[PathPoint],
path_type: PathType, path_type: PathType,
stroke: Stroke, stroke: Stroke,
options: TesselationOptions, options: TessellationOptions,
out: &mut Triangles, out: &mut Triangles,
) { ) {
if stroke.width <= 0.0 || stroke.color == color::TRANSPARENT { if stroke.width <= 0.0 || stroke.color == color::TRANSPARENT {
@ -665,16 +665,16 @@ fn mul_color(color: Srgba, factor: f32) -> Srgba {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/// Tesselate a single [`PaintCmd`] into a [`Triangles`]. /// Tessellate a single [`PaintCmd`] into a [`Triangles`].
/// ///
/// * `command`: the command to tesselate /// * `command`: the command to tessellate
/// * `options`: tesselation quality /// * `options`: tessellation quality
/// * `fonts`: font source when tessellating text /// * `fonts`: font source when tessellating text
/// * `out`: where the triangles are put /// * `out`: where the triangles are put
/// * `scratchpad_path`: if you plan to run `tessellate_paint_command` /// * `scratchpad_path`: if you plan to run `tessellate_paint_command`
/// many times, pass it a reference to the same `Path` to avoid excessive allocations. /// many times, pass it a reference to the same `Path` to avoid excessive allocations.
fn tessellate_paint_command( fn tessellate_paint_command(
options: TesselationOptions, options: TessellationOptions,
fonts: &Fonts, fonts: &Fonts,
clip_rect: Rect, clip_rect: Rect,
command: PaintCmd, command: PaintCmd,
@ -774,7 +774,7 @@ fn tessellate_paint_command(
text_style, text_style,
color, color,
} => { } => {
tesselate_text( tessellate_text(
options, fonts, clip_rect, pos, &galley, text_style, color, out, options, fonts, clip_rect, pos, &galley, text_style, color, out,
); );
} }
@ -782,8 +782,8 @@ fn tessellate_paint_command(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn tesselate_text( fn tessellate_text(
options: TesselationOptions, options: TessellationOptions,
fonts: &Fonts, fonts: &Fonts,
clip_rect: Rect, clip_rect: Rect,
pos: Pos2, pos: Pos2,
@ -850,15 +850,15 @@ fn tesselate_text(
/// The given commands will be painted back-to-front (painters algorithm). /// The given commands will be painted back-to-front (painters algorithm).
/// They will be batched together by clip rectangle. /// They will be batched together by clip rectangle.
/// ///
/// * `commands`: the command to tesselate /// * `commands`: the command to tessellate
/// * `options`: tesselation quality /// * `options`: tessellation quality
/// * `fonts`: font source when tessellating text /// * `fonts`: font source when tessellating text
/// ///
/// ## Returns /// ## Returns
/// A list of clip rectangles with matching [`Triangles`]. /// A list of clip rectangles with matching [`Triangles`].
pub fn tessellate_paint_commands( pub fn tessellate_paint_commands(
commands: Vec<(Rect, PaintCmd)>, commands: Vec<(Rect, PaintCmd)>,
options: TesselationOptions, options: TessellationOptions,
fonts: &Fonts, fonts: &Fonts,
) -> Vec<(Rect, Triangles)> { ) -> Vec<(Rect, Triangles)> {
let mut scratchpad_points = Vec::new(); let mut scratchpad_points = Vec::new();
@ -915,7 +915,7 @@ pub fn tessellate_paint_commands(
for (_, triangles) in &jobs { for (_, triangles) in &jobs {
debug_assert!( debug_assert!(
triangles.is_valid(), triangles.is_valid(),
"Tesselator generated invalid Triangles" "Tessellator generated invalid Triangles"
); );
} }

View file

@ -151,7 +151,7 @@ pub fn run(mut app: Box<dyn App>) -> ! {
app.ui(&ctx, &mut integration_context); app.ui(&ctx, &mut integration_context);
let app_output = integration_context.output; let app_output = integration_context.output;
let (egui_output, paint_commands) = ctx.end_frame(); let (egui_output, paint_commands) = ctx.end_frame();
let paint_jobs = ctx.tesselate(paint_commands); let paint_jobs = ctx.tessellate(paint_commands);
let frame_time = (Instant::now() - frame_start).as_secs_f64() as f32; let frame_time = (Instant::now() - frame_start).as_secs_f64() as f32;
previous_frame_time = Some(frame_time); previous_frame_time = Some(frame_time);

View file

@ -42,7 +42,7 @@ impl WebBackend {
.expect("unmatched calls to begin_frame/end_frame"); .expect("unmatched calls to begin_frame/end_frame");
let (output, paint_commands) = self.ctx.end_frame(); let (output, paint_commands) = self.ctx.end_frame();
let paint_jobs = self.ctx.tesselate(paint_commands); let paint_jobs = self.ctx.tessellate(paint_commands);
let now = now_sec(); let now = now_sec();
self.previous_frame_time = Some((now - frame_start) as f32); self.previous_frame_time = Some((now - frame_start) as f32);