Fix egui_glow when targeting wasm32-unknown-unknown
(#1303)
* Gate winit/glow and epi correctly * Add check to CI * Fix epi cfg
This commit is contained in:
parent
e3d1fa22d1
commit
37c9f116bf
3 changed files with 121 additions and 102 deletions
14
.github/workflows/rust.yml
vendored
14
.github/workflows/rust.yml
vendored
|
@ -56,6 +56,20 @@ jobs:
|
|||
command: check
|
||||
args: -p egui_demo_app --lib --target wasm32-unknown-unknown
|
||||
|
||||
check_wasm_eframe_with_features:
|
||||
name: cargo check wasm eframe
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: 1.56.0
|
||||
override: true
|
||||
- run: rustup target add wasm32-unknown-unknown
|
||||
- name: check
|
||||
run: cargo check -p eframe --lib --no-default-features --features egui_glow,persistence --target wasm32-unknown-unknown
|
||||
|
||||
check_web_all_features:
|
||||
name: cargo check web --all-features
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
@ -88,114 +88,27 @@
|
|||
#![allow(clippy::manual_range_contains)]
|
||||
|
||||
pub mod painter;
|
||||
#[cfg(feature = "winit")]
|
||||
use egui_winit::winit;
|
||||
pub use glow;
|
||||
pub use painter::Painter;
|
||||
#[cfg(feature = "winit")]
|
||||
mod epi_backend;
|
||||
mod misc_util;
|
||||
mod post_process;
|
||||
mod shader_version;
|
||||
mod vao_emulate;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(feature = "egui_winit")]
|
||||
pub use egui_winit;
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "winit"))]
|
||||
pub mod winit;
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "winit"))]
|
||||
pub use winit::*;
|
||||
|
||||
#[cfg(all(feature = "epi", feature = "winit"))]
|
||||
#[cfg(all(
|
||||
not(target_arch = "wasm32"),
|
||||
feature = "persistence",
|
||||
feature = "winit"
|
||||
))]
|
||||
mod epi_backend;
|
||||
#[cfg(all(
|
||||
not(target_arch = "wasm32"),
|
||||
feature = "persistence",
|
||||
feature = "winit"
|
||||
))]
|
||||
pub use epi_backend::{run, NativeOptions};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Use [`egui`] from a [`glow`] app.
|
||||
#[cfg(feature = "winit")]
|
||||
pub struct EguiGlow {
|
||||
pub egui_ctx: egui::Context,
|
||||
pub egui_winit: egui_winit::State,
|
||||
pub painter: crate::Painter,
|
||||
|
||||
shapes: Vec<egui::epaint::ClippedShape>,
|
||||
textures_delta: egui::TexturesDelta,
|
||||
}
|
||||
|
||||
#[cfg(feature = "winit")]
|
||||
impl EguiGlow {
|
||||
pub fn new(window: &winit::window::Window, gl: &glow::Context) -> Self {
|
||||
let painter = crate::Painter::new(gl, None, "")
|
||||
.map_err(|error| {
|
||||
tracing::error!("error occurred in initializing painter:\n{}", error);
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Self {
|
||||
egui_ctx: Default::default(),
|
||||
egui_winit: egui_winit::State::new(painter.max_texture_side(), window),
|
||||
painter,
|
||||
shapes: Default::default(),
|
||||
textures_delta: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if egui wants exclusive use of this event
|
||||
/// (e.g. a mouse click on an egui window, or entering text into a text field).
|
||||
/// For instance, if you use egui for a game, you want to first call this
|
||||
/// and only when this returns `false` pass on the events to your game.
|
||||
///
|
||||
/// Note that egui uses `tab` to move focus between elements, so this will always return `true` for tabs.
|
||||
pub fn on_event(&mut self, event: &winit::event::WindowEvent<'_>) -> bool {
|
||||
self.egui_winit.on_event(&self.egui_ctx, event)
|
||||
}
|
||||
|
||||
/// Returns `true` if egui requests a repaint.
|
||||
///
|
||||
/// Call [`Self::paint`] later to paint.
|
||||
pub fn run(
|
||||
&mut self,
|
||||
window: &winit::window::Window,
|
||||
run_ui: impl FnMut(&egui::Context),
|
||||
) -> bool {
|
||||
let raw_input = self.egui_winit.take_egui_input(window);
|
||||
let egui::FullOutput {
|
||||
platform_output,
|
||||
needs_repaint,
|
||||
textures_delta,
|
||||
shapes,
|
||||
} = self.egui_ctx.run(raw_input, run_ui);
|
||||
|
||||
self.egui_winit
|
||||
.handle_platform_output(window, &self.egui_ctx, platform_output);
|
||||
|
||||
self.shapes = shapes;
|
||||
self.textures_delta.append(textures_delta);
|
||||
needs_repaint
|
||||
}
|
||||
|
||||
/// Paint the results of the last call to [`Self::run`].
|
||||
pub fn paint(&mut self, window: &winit::window::Window, gl: &glow::Context) {
|
||||
let shapes = std::mem::take(&mut self.shapes);
|
||||
let mut textures_delta = std::mem::take(&mut self.textures_delta);
|
||||
|
||||
for (id, image_delta) in textures_delta.set {
|
||||
self.painter.set_texture(gl, id, &image_delta);
|
||||
}
|
||||
|
||||
let clipped_meshes = self.egui_ctx.tessellate(shapes);
|
||||
let dimensions: [u32; 2] = window.inner_size().into();
|
||||
self.painter.paint_meshes(
|
||||
gl,
|
||||
dimensions,
|
||||
self.egui_ctx.pixels_per_point(),
|
||||
clipped_meshes,
|
||||
);
|
||||
|
||||
for id in textures_delta.free.drain(..) {
|
||||
self.painter.free_texture(gl, id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Call to release the allocated graphics resources.
|
||||
pub fn destroy(&mut self, gl: &glow::Context) {
|
||||
self.painter.destroy(gl);
|
||||
}
|
||||
}
|
||||
|
|
92
egui_glow/src/winit.rs
Normal file
92
egui_glow/src/winit.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
pub use egui_winit;
|
||||
use egui_winit::winit;
|
||||
|
||||
/// Use [`egui`] from a [`glow`] app.
|
||||
pub struct EguiGlow {
|
||||
pub egui_ctx: egui::Context,
|
||||
pub egui_winit: egui_winit::State,
|
||||
pub painter: crate::Painter,
|
||||
|
||||
shapes: Vec<egui::epaint::ClippedShape>,
|
||||
textures_delta: egui::TexturesDelta,
|
||||
}
|
||||
|
||||
impl EguiGlow {
|
||||
pub fn new(window: &winit::window::Window, gl: &glow::Context) -> Self {
|
||||
let painter = crate::Painter::new(gl, None, "")
|
||||
.map_err(|error| {
|
||||
tracing::error!("error occurred in initializing painter:\n{}", error);
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Self {
|
||||
egui_ctx: Default::default(),
|
||||
egui_winit: egui_winit::State::new(painter.max_texture_side(), window),
|
||||
painter,
|
||||
shapes: Default::default(),
|
||||
textures_delta: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if egui wants exclusive use of this event
|
||||
/// (e.g. a mouse click on an egui window, or entering text into a text field).
|
||||
/// For instance, if you use egui for a game, you want to first call this
|
||||
/// and only when this returns `false` pass on the events to your game.
|
||||
///
|
||||
/// Note that egui uses `tab` to move focus between elements, so this will always return `true` for tabs.
|
||||
pub fn on_event(&mut self, event: &winit::event::WindowEvent<'_>) -> bool {
|
||||
self.egui_winit.on_event(&self.egui_ctx, event)
|
||||
}
|
||||
|
||||
/// Returns `true` if egui requests a repaint.
|
||||
///
|
||||
/// Call [`Self::paint`] later to paint.
|
||||
pub fn run(
|
||||
&mut self,
|
||||
window: &winit::window::Window,
|
||||
run_ui: impl FnMut(&egui::Context),
|
||||
) -> bool {
|
||||
let raw_input = self.egui_winit.take_egui_input(window);
|
||||
let egui::FullOutput {
|
||||
platform_output,
|
||||
needs_repaint,
|
||||
textures_delta,
|
||||
shapes,
|
||||
} = self.egui_ctx.run(raw_input, run_ui);
|
||||
|
||||
self.egui_winit
|
||||
.handle_platform_output(window, &self.egui_ctx, platform_output);
|
||||
|
||||
self.shapes = shapes;
|
||||
self.textures_delta.append(textures_delta);
|
||||
needs_repaint
|
||||
}
|
||||
|
||||
/// Paint the results of the last call to [`Self::run`].
|
||||
pub fn paint(&mut self, window: &winit::window::Window, gl: &glow::Context) {
|
||||
let shapes = std::mem::take(&mut self.shapes);
|
||||
let mut textures_delta = std::mem::take(&mut self.textures_delta);
|
||||
|
||||
for (id, image_delta) in textures_delta.set {
|
||||
self.painter.set_texture(gl, id, &image_delta);
|
||||
}
|
||||
|
||||
let clipped_meshes = self.egui_ctx.tessellate(shapes);
|
||||
let dimensions: [u32; 2] = window.inner_size().into();
|
||||
self.painter.paint_meshes(
|
||||
gl,
|
||||
dimensions,
|
||||
self.egui_ctx.pixels_per_point(),
|
||||
clipped_meshes,
|
||||
);
|
||||
|
||||
for id in textures_delta.free.drain(..) {
|
||||
self.painter.free_texture(gl, id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Call to release the allocated graphics resources.
|
||||
pub fn destroy(&mut self, gl: &glow::Context) {
|
||||
self.painter.destroy(gl);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue