From 26be0ace1d3ab7296c5aa1ae248f4d246add2775 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 26 Jan 2022 17:25:59 +0100 Subject: [PATCH] Tidy up README.md --- README.md | 104 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 593226694..a4e8d166d 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) [![Discord](https://img.shields.io/discord/900275882684477440?label=egui%20discord)](https://discord.gg/JFcEma9bJq) +👉 [Click to run the web demo](https://emilk.github.io/egui/index.html) 👈 egui is a simple, fast, and highly portable immediate mode GUI library for Rust. egui runs on the web, natively, and [in your favorite game engine](#integrations) (or will soon). @@ -18,18 +19,35 @@ egui can be used anywhere you can draw textured triangles, which means you can e Sections: +* [Example](#example) * [Quick start](#quick-start) * [Demo](#demo) * [Goals](#goals) * [Who is egui for?](#who-is-egui-for) * [State / features](#state) -* [How it works](#how-it-works) * [Integrations](#integrations) * [Why immediate mode](#why-immediate-mode) * [FAQ](#faq) * [Other](#other) * [Credits](#credits) +## Example + +``` rust +ui.heading("My egui Application"); +ui.horizontal(|ui| { + ui.label("Your name: "); + ui.text_edit_singleline(&mut name); +}); +ui.add(egui::Slider::new(&mut age, 0..=120).text("age")); +if ui.button("Click each year").clicked() { + age += 1; +} +ui.label(format!("Hello '{}', age {}", name, age)); +``` + + + ## Quick start If you just want to write a GUI application in Rust (for the web or for native), go to and follow the instructions there! The official docs are at . For inspiration, check out the [the egui web demo](https://emilk.github.io/egui/index.html) and follow the links in it to its source code. There is also an excellent tutorial video at . @@ -54,23 +72,6 @@ On Fedora Rawhide you need to run: **NOTE**: This is just for the demo app - egui itself is completely platform agnostic! -### Example - -``` rust -ui.heading("My egui Application"); -ui.horizontal(|ui| { - ui.label("Your name: "); - ui.text_edit_singleline(&mut name); -}); -ui.add(egui::Slider::new(&mut age, 0..=120).text("age")); -if ui.button("Click each year").clicked() { - age += 1; -} -ui.label(format!("Hello '{}', age {}", name, age)); -``` - - - ## Goals * The easiest to use GUI library @@ -145,72 +146,74 @@ Light Theme: -## How it works - -Loop: - -* Gather input (mouse, touches, keyboard, screen size, etc) and give it to egui -* Run application code (Immediate Mode GUI) -* 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)) or use `eframe`, the egui framework crate. - ## Integrations egui is build to be easy to integrate into any existing game engine or platform you are working on. egui itself doesn't know or care on what OS it is running or how to render things to the screen - that is the job of the egui integration. -The integration needs to do two things: -* **IO**: Supply egui with input (mouse position, keyboard presses, …) and handle egui output (cursor changes, copy-paste integration, …). -* **Painting**: Render the textured triangles that egui outputs. +An integration needs to do the following each frame: -### Official +* **Input**: Gather input (mouse, touches, keyboard, screen size, etc) and give it to egui +* Run the application code +* **Output**: Handle egui output (cursor changes, paste, texture allocations, …) +* **Painting**: Render the triangle mesh egui produces (see [OpenGL example](https://github.com/emilk/egui/blob/master/egui_glium/src/painter.rs)) -There are three official egui integrations made for apps: +### Official integrations + +If you making an app, your best bet is using [`eframe`](https://github.com/emilk/egui/tree/master/eframe), the official egui framework. It lets you write apps that works on both the web and native. `eframe` is just a thin wrapper over `egui_web` and `egui_glium` (see below). + +These are the official egui integrations: -* [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web) for making a web app. Compiles to WASM, renders with WebGL. [Click to run the egui demo](https://emilk.github.io/egui/index.html). * [`egui_glium`](https://github.com/emilk/egui/tree/master/egui_glium) for compiling native apps with [Glium](https://github.com/glium/glium). * [`egui_glow`](https://github.com/emilk/egui/tree/master/egui_glow) for compiling native apps with [Glow](https://github.com/grovesNL/glow). +* [`egui_web`](https://github.com/emilk/egui/tree/master/egui_web) for making a web app. Compiles to WASM, renders with WebGL. [Click to run the egui demo](https://emilk.github.io/egui/index.html). * [`egui-winit`](https://github.com/emilk/egui/tree/master/egui-winit) for integrating with [`winit`](https://github.com/rust-windowing/winit). `egui-winit` is used by `egui_glium` and `egui_glow`. -If you making an app, consider using [`eframe`](https://github.com/emilk/egui/tree/master/eframe), a framework which allows you to write code that works on both the web (`egui_web`) and native (using `egui_glium`). - -### 3rd party +### 3rd party integrations * [`amethyst_egui`](https://github.com/jgraef/amethyst_egui) for [the Amethyst game engine](https://amethyst.rs/). * [`bevy_egui`](https://github.com/mvlabat/bevy_egui) for [the Bevy game engine](https://bevyengine.org/). * [`egui_glfw_gl`](https://github.com/cohaereo/egui_glfw_gl) for [GLFW](https://crates.io/crates/glfw). -* [`egui-miniquad`](https://github.com/not-fl3/egui-miniquad) for [Miniquad](https://github.com/not-fl3/miniquad). -* [`egui-macroquad`](https://github.com/optozorax/egui-macroquad) for [macroquad](https://github.com/not-fl3/macroquad). * [`egui_sdl2_gl`](https://crates.io/crates/egui_sdl2_gl) for [SDL2](https://crates.io/crates/sdl2). * [`egui_vulkano`](https://github.com/derivator/egui_vulkano) for [Vulkano](https://github.com/vulkano-rs/vulkano). -* [`egui-winit-ash-integration`](https://github.com/MatchaChoco010/egui-winit-ash-integration) for [winit](https://github.com/rust-windowing/winit) and [ash](https://github.com/MaikKlein/ash). +* [`egui_wgpu_backend`](https://crates.io/crates/egui_wgpu_backend) for [`wgpu`](https://crates.io/crates/wgpu) (WebGPU API). * [`egui_winit_vulkano`](https://github.com/hakolao/egui_winit_vulkano) for [Vulkano](https://github.com/vulkano-rs/vulkano). +* [`egui-macroquad`](https://github.com/optozorax/egui-macroquad) for [macroquad](https://github.com/not-fl3/macroquad). +* [`egui-miniquad`](https://github.com/not-fl3/egui-miniquad) for [Miniquad](https://github.com/not-fl3/miniquad). +* [`egui-tetra`](https://crates.io/crates/egui-tetra) for [Tetra](https://crates.io/crates/tetra), a 2D game framework. +* [`egui-winit-ash-integration`](https://github.com/MatchaChoco010/egui-winit-ash-integration) for [winit](https://github.com/rust-windowing/winit) and [ash](https://github.com/MaikKlein/ash). * [`fltk-egui`](https://crates.io/crates/fltk-egui) for [fltk-rs](https://github.com/fltk-rs/fltk-rs). * [`ggez-egui`](https://github.com/NemuiSen/ggez-egui) for the [ggez](https://ggez.rs/) game framework. * [`godot-egui`](https://github.com/setzer22/godot-egui) for [`godot-rust`](https://github.com/godot-rust/godot-rust). * [`nannou_egui`](https://github.com/AlexEne/nannou_egui) for [nannou](https://nannou.cc). -* [`egui-tetra`](https://crates.io/crates/egui-tetra) for [Tetra](https://crates.io/crates/tetra), a 2D game framework. -* [`egui_wgpu_backend`](https://crates.io/crates/egui_wgpu_backend) for [`wgpu`](https://crates.io/crates/wgpu) (WebGPU API). -Missing an integration for the thing you're working on? Create one, it is easy! +Missing an integration for the thing you're working on? Create one, it's easy! ### Writing your own egui integration -You need to collect [`egui::RawInput`](https://docs.rs/egui/latest/egui/struct.RawInput.html), paint [`egui::ClippedMesh`](https://docs.rs/epaint/):es and handle [`egui::Output`](https://docs.rs/egui/latest/egui/struct.Output.html). The basic structure is this: +You need to collect [`egui::RawInput`](https://docs.rs/egui/latest/egui/struct.RawInput.html), paint [`egui::ClippedMesh`](https://docs.rs/epaint/latest/epaint/struct.ClippedMesh.html):es and handle [`egui::Output`](https://docs.rs/egui/latest/egui/struct.Output.html). The basic structure is this: ``` rust let mut egui_ctx = egui::CtxRef::default(); // Game loop: loop { + // Gather input (mouse, touches, keyboard, screen size, etc): let raw_input: egui::RawInput = my_integration.gather_input(); let (output, shapes) = egui_ctx.run(raw_input, |egui_ctx| { my_app.ui(egui_ctx); // add panels, windows and widgets to `egui_ctx` here }); - let clipped_meshes = egui_ctx.tessellate(shapes); // create triangles to paint + let clipped_meshes = egui_ctx.tessellate(shapes); // creates triangles to paint + + my_integration.set_egui_textures(&output.textures_delta.set); my_integration.paint(clipped_meshes); + my_integration.free_egui_textures(&output.textures_delta.free); + my_integration.set_cursor_icon(output.cursor_icon); - // Also see `egui::Output` for more + if !output.copied_text.is_empty() { + my_integration.set_clipboard_text(output.copied_text); + } + // See `egui::Output` for more } ``` @@ -231,11 +234,12 @@ For a reference OpenGL backend, see [the `egui_glium` painter](https://github.co * egui uses premultiplied alpha, so make sure your blending function is `(ONE, ONE_MINUS_SRC_ALPHA)`. * Make sure your texture sampler is clamped (`GL_CLAMP_TO_EDGE`). -* Use an sRGBA-aware texture if available (e.g. `GL_SRGB8_ALPHA8`). - * Otherwise: remember to decode gamma in the fragment shader. -* Decode the gamma of the incoming vertex colors in your vertex shader. -* Turn on sRGBA/linear framebuffer if available (`GL_FRAMEBUFFER_SRGB`). - * Otherwise: gamma-encode the colors before you write them again. +* egui prefers linear color spaces for all blending so: + * Use an sRGBA-aware texture if available (e.g. `GL_SRGB8_ALPHA8`). + * Otherwise: remember to decode gamma in the fragment shader. + * Decode the gamma of the incoming vertex colors in your vertex shader. + * Turn on sRGBA/linear framebuffer if available (`GL_FRAMEBUFFER_SRGB`). + * Otherwise: gamma-encode the colors before you write them again. ## Why immediate mode