#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use egui::{load::SizedTexture, TextureId, Vec2, ViewportId};
use glium::{
backend::glutin::SimpleWindowBuilder, glutin::surface::WindowSurface, texture::SrgbTexture2d,
};
use std::rc::Rc;
use winit::{
application::ApplicationHandler,
event::{StartCause, WindowEvent},
event_loop::{ActiveEventLoop, EventLoop},
window::{Window, WindowId},
};
fn main() {
let event_loop = EventLoop::new().unwrap();
let (window, display) = create_display(&event_loop);
let mut egui_glium =
egui_glium::EguiGlium::new(ViewportId::ROOT, &display, &window, &event_loop);
let png_data = include_bytes!("rust-logo-256x256.png");
let image = load_glium_image(png_data);
let image_size = egui::vec2(image.width as f32, image.height as f32);
let glium_texture = glium::texture::SrgbTexture2d::new(&display, image).unwrap();
let glium_texture = std::rc::Rc::new(glium_texture);
let texture_id = egui_glium
.painter
.register_native_texture(Rc::clone(&glium_texture), Default::default());
let button_image_size = egui::vec2(32_f32, 32_f32);
let mut app = App {
egui_glium,
_glium_texture: glium_texture,
texture_id,
image_size,
window,
display,
button_image_size,
};
let result = event_loop.run_app(&mut app);
result.unwrap()
}
struct App {
egui_glium: egui_glium::EguiGlium,
_glium_texture: Rc<SrgbTexture2d>,
texture_id: TextureId,
image_size: Vec2,
window: winit::window::Window,
display: glium::Display<WindowSurface>,
button_image_size: Vec2,
}
impl ApplicationHandler for App {
fn resumed(&mut self, _event_loop: &ActiveEventLoop) {}
fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) {
let mut redraw = || {
let mut quit = false;
self.egui_glium.run(&self.window, |egui_ctx| {
egui::SidePanel::left("my_side_panel").show(egui_ctx, |ui| {
if ui
.add(egui::Button::image_and_text(
(self.texture_id, self.button_image_size),
"Quit",
))
.clicked()
{
quit = true;
}
});
egui::Window::new("NativeTextureDisplay").show(egui_ctx, |ui| {
ui.image(SizedTexture::new(self.texture_id, self.image_size));
});
});
if quit {
event_loop.exit()
}
{
use glium::Surface as _;
let mut target = self.display.draw();
let color = egui::Rgba::from_rgb(0.1, 0.3, 0.2);
target.clear_color(color[0], color[1], color[2], color[3]);
self.egui_glium.paint(&self.display, &mut target);
target.finish().unwrap();
}
};
use winit::event::WindowEvent;
match &event {
WindowEvent::CloseRequested | WindowEvent::Destroyed => event_loop.exit(),
WindowEvent::Resized(new_size) => {
self.display.resize((*new_size).into());
}
WindowEvent::RedrawRequested => redraw(),
_ => {}
}
let event_response = self.egui_glium.on_event(&self.window, &event);
if event_response.repaint {
self.window.request_redraw();
}
}
fn new_events(&mut self, _event_loop: &ActiveEventLoop, cause: StartCause) {
if let StartCause::ResumeTimeReached { .. } = cause {
self.window.request_redraw();
}
}
}
fn create_display(
event_loop: &EventLoop<()>,
) -> (winit::window::Window, glium::Display<WindowSurface>) {
SimpleWindowBuilder::new()
.set_window_builder(Window::default_attributes().with_resizable(true))
.with_inner_size(800, 600)
.with_title("egui_glium example")
.build(event_loop)
}
fn load_glium_image(png_data: &[u8]) -> glium::texture::RawImage2d<'_, u8> {
let image = image::load_from_memory(png_data).unwrap().to_rgba8();
let image_dimensions = image.dimensions();
let pixels: Vec<_> = image
.into_vec()
.chunks_exact(4)
.map(|p| egui::Color32::from_rgba_unmultiplied(p[0], p[1], p[2], p[3]))
.flat_map(|color| color.to_array())
.collect();
glium::texture::RawImage2d::from_raw_rgba(pixels, image_dimensions)
}