Skip to main content

egui_raylib/
lib.rs

1mod input;
2mod output;
3mod renderer;
4mod textures;
5
6use std::collections::HashMap;
7
8use egui::{ClippedPrimitive, Context, TextureId, TexturesDelta, Ui};
9use raylib::prelude::*;
10
11use crate::textures::HandleTexturesErrors;
12
13#[derive(Debug)]
14pub enum EguiRaylibError {
15    HandleTexturesErrors(HandleTexturesErrors),
16}
17
18impl From<HandleTexturesErrors> for EguiRaylibError {
19    fn from(value: HandleTexturesErrors) -> Self {
20        EguiRaylibError::HandleTexturesErrors(value)
21    }
22}
23
24pub struct EguiRaylib {
25    ctx: egui::Context,
26    textures: HashMap<TextureId, Texture2D>,
27    pixels_per_point: f32,
28    last_textures_delta: Option<TexturesDelta>,
29    last_clipped_primitives: Option<Vec<ClippedPrimitive>>,
30}
31
32impl EguiRaylib {
33    pub fn new(ctx: egui::Context, pixels_per_point: f32) -> Self {
34        Self {
35            ctx,
36            textures: HashMap::new(),
37            last_textures_delta: None,
38            last_clipped_primitives: None,
39            pixels_per_point: pixels_per_point,
40        }
41    }
42
43    pub fn ctx(&self) -> &Context {
44        &self.ctx
45    }
46
47    pub fn run(&mut self, rl: &mut RaylibHandle, run_ui: impl FnMut(&mut Ui)) {
48        let raw_input: egui::RawInput = input::gather_input(rl, self.pixels_per_point);
49
50        let full_output = self.ctx.run_ui(raw_input, run_ui);
51
52        output::handle_platform_output(rl, full_output.platform_output);
53
54        self.pixels_per_point = full_output.pixels_per_point;
55        self.last_clipped_primitives = Some(
56            self.ctx
57                .tessellate(full_output.shapes, full_output.pixels_per_point),
58        );
59
60        self.last_textures_delta = Some(full_output.textures_delta);
61    }
62
63    pub fn draw(
64        &mut self,
65        d: &mut RaylibDrawHandle,
66        thread: &RaylibThread,
67    ) -> Result<(), EguiRaylibError> {
68        if let Some(textures_delta) = &self.last_textures_delta {
69            match textures::handle_textures(&mut self.textures, d, &thread, &textures_delta) {
70                Ok(()) => self.last_textures_delta = None,
71                Err(err) => return Err(err.into()),
72            }
73        }
74
75        if let Some(clipped_primitives) = self.last_clipped_primitives.take() {
76            renderer::render(
77                d,
78                self.pixels_per_point,
79                &clipped_primitives,
80                &self.textures,
81            );
82        }
83
84        Ok(())
85    }
86}
87
88impl Default for EguiRaylib {
89    fn default() -> Self {
90        Self::new(egui::Context::default(), 1.)
91    }
92}