kitgit

tirbofish/dropbear · commit

06d302b9818e9ac281b1dbc4575b4351f8833521

dropped back down to wgpu 25 as I do not need the extra features, and it kept breaking itself on release builds. like a mf, it works hella fast i think this is worthy of a jarvis, run github actions command just because everything works as intended. anyways, still working on scripting...

Unverified

tk <4tkbytes@pm.me> · 2025-09-16 11:54

view full diff

diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml
index 9b23cc7..69967f7 100644
--- a/.github/workflows/docs.yaml
+++ b/.github/workflows/docs.yaml
@@ -1,42 +1,42 @@
-name: Generate and Publish TypeScript Docs
-
-on:
-  push:
-    branches: [ main ]
-  workflow_dispatch:
-
-permissions:
-  contents: read
-  pages: write
-
-jobs:
-  build-and-deploy:
-    runs-on: ubuntu-latest
-
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v4
-
-      - name: Setup Node.js
-        uses: actions/setup-node@v4
-        with:
-          node-version: 18
-
-      - name: Cache npm
-        uses: actions/cache@v4
-        with:
-          path: ~/.npm
-          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
-          restore-keys: |
-            ${{ runner.os }}-node-
-
-      - name: Generate TypeScript docs
-        run: |
-          chmod +x scripts/gen_docs.sh
-          ./scripts/gen_docs.sh
-
-      - name: Deploy to GitHub Pages
-        uses: peaceiris/actions-gh-pages@v3
-        with:
-          github_token: ${{ secrets.PAGES_PAT }}
-          publish_dir: ./docs
\ No newline at end of file
+# name: Generate and Publish TypeScript Docs
+
+# on:
+#   push:
+#     branches: [ main ]
+#   workflow_dispatch:
+
+# permissions:
+#   contents: read
+#   pages: write
+
+# jobs:
+#   build-and-deploy:
+#     runs-on: ubuntu-latest
+
+#     steps:
+#       - name: Checkout
+#         uses: actions/checkout@v4
+
+#       - name: Setup Node.js
+#         uses: actions/setup-node@v4
+#         with:
+#           node-version: 18
+
+#       - name: Cache npm
+#         uses: actions/cache@v4
+#         with:
+#           path: ~/.npm
+#           key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
+#           restore-keys: |
+#             ${{ runner.os }}-node-
+
+#       - name: Generate TypeScript docs
+#         run: |
+#           chmod +x scripts/gen_docs.sh
+#           ./scripts/gen_docs.sh
+
+#       - name: Deploy to GitHub Pages
+#         uses: peaceiris/actions-gh-pages@v3
+#         with:
+#           github_token: ${{ secrets.PAGES_PAT }}
+#           publish_dir: ./docs
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 1a9efc7..5061850 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,8 +22,8 @@ colored = "3.0"
 dropbear-engine = { path = "dropbear-engine" }
 egui = "0.32"
 egui-toast-fork = "0.18"
-egui_wgpu_backend = { version = "0.35", git = "https://github.com/hasenbanck/egui_wgpu_backend"}
-egui_winit_platform = { version = "0.27", git = "https://github.com/hasenbanck/egui_winit_platform" }
+egui-wgpu = { version = "0.32" }
+egui-winit = { version = "0.32" }
 egui_dnd = "0.13"
 egui_dock-fork = { version = "0.17", features = ["serde"] }
 egui_extras = { version = "0.32", features = ["all_loaders"] }
@@ -48,7 +48,7 @@ serde = { version = "1.0.219", features = ["derive"] }
 spin_sleep = "1.3"
 transform-gizmo-egui = { git = "https://github.com/4tkbytes/transform-gizmo"}
 tokio = { version = "1", features = ["full"] }
-wgpu = "26"
+wgpu = "25"
 winit = { version = "0.30", features = [] }
 zip = "5.1"
 walkdir = "2.3"
@@ -60,6 +60,7 @@ tar = "0.4"
 async-trait = "0.1"
 futures-util = "0.3"
 boa_engine = "0.20"
+backtrace = "0.3"
 
 
 gltf = "1"
diff --git a/dropbear-engine/Cargo.toml b/dropbear-engine/Cargo.toml
index bdc755b..b424f2a 100644
--- a/dropbear-engine/Cargo.toml
+++ b/dropbear-engine/Cargo.toml
@@ -14,8 +14,8 @@ app_dirs2.workspace = true
 bytemuck.workspace = true
 chrono.workspace = true
 colored.workspace = true
-egui_wgpu_backend.workspace = true
-egui_winit_platform.workspace = true
+egui-wgpu.workspace = true
+egui-winit.workspace = true
 egui.workspace = true
 env_logger.workspace = true
 futures.workspace = true
@@ -36,6 +36,7 @@ gltf.workspace = true
 rayon.workspace = true
 tokio.workspace = true
 async-trait.workspace = true
+backtrace.workspace = true
 
 [target.'cfg(not(target_os = "android"))'.dependencies]
 rfd.workspace = true
diff --git a/dropbear-engine/src/egui_renderer.rs b/dropbear-engine/src/egui_renderer.rs
index df7b8b3..f0bc2a1 100644
--- a/dropbear-engine/src/egui_renderer.rs
+++ b/dropbear-engine/src/egui_renderer.rs
@@ -1,60 +1,68 @@
-use egui::{Context, FontDefinitions};
-use egui_wgpu_backend::{RenderPass, ScreenDescriptor, wgpu};
-use egui_winit_platform::{Platform, PlatformDescriptor};
-use wgpu::{CommandEncoder, Device, Queue, TextureFormat, TextureView};
+use egui::Context;
+use egui_wgpu::wgpu::{CommandEncoder, Device, Queue, StoreOp, TextureFormat, TextureView};
+use egui_wgpu::{Renderer, ScreenDescriptor, wgpu};
+use egui_winit::State;
 use winit::event::WindowEvent;
 use winit::window::Window;
 
 pub struct EguiRenderer {
-    state: Platform,
-    renderer: RenderPass,
+    state: State,
+    renderer: Renderer,
     frame_started: bool,
 }
 
 impl EguiRenderer {
-    pub fn context(&mut self) -> Context {
-        self.state.context()
+    pub fn context(&self) -> &Context {
+        self.state.egui_ctx()
     }
 
-    pub fn renderer(&mut self) -> &mut RenderPass {
+    pub fn renderer(&mut self) -> &mut Renderer {
         &mut self.renderer
     }
 
     pub fn new(
         device: &Device,
         output_color_format: TextureFormat,
+        output_depth_format: Option<TextureFormat>,
         msaa_samples: u32,
         window: &Window,
     ) -> EguiRenderer {
-        let size = window.inner_size();
-
-        let platform = Platform::new(PlatformDescriptor {
-            physical_width: size.width as u32,
-            physical_height: size.height as u32,
-            scale_factor: window.scale_factor(),
-            font_definitions: FontDefinitions::default(),
-            style: Default::default(),
-        });
-
-        let egui_renderer = RenderPass::new(device, output_color_format, msaa_samples);
+        let egui_context = Context::default();
+
+        let egui_state = egui_winit::State::new(
+            egui_context,
+            egui::viewport::ViewportId::ROOT,
+            &window,
+            Some(window.scale_factor() as f32),
+            None,
+            Some(2 * 1024), // default dimension is 2048
+        );
+        let egui_renderer = Renderer::new(
+            device,
+            output_color_format,
+            output_depth_format,
+            msaa_samples,
+            true,
+        );
 
         EguiRenderer {
-            state: platform,
+            state: egui_state,
             renderer: egui_renderer,
             frame_started: false,
         }
     }
 
-    pub fn handle_input(&mut self, event: &WindowEvent) {
-        let _ = self.state.handle_event(event);
+    pub fn handle_input(&mut self, window: &Window, event: &WindowEvent) {
+        let _ = self.state.on_window_event(window, event);
     }
 
     pub fn ppp(&mut self, v: f32) {
         self.context().set_pixels_per_point(v);
     }
 
-    pub fn begin_frame(&mut self) {
-        self.state.begin_pass();
+    pub fn begin_frame(&mut self, window: &Window) {
+        let raw_input = self.state.take_egui_input(window);
+        self.state.egui_ctx().begin_pass(raw_input);
         self.frame_started = true;
     }
 
@@ -68,37 +76,46 @@ impl EguiRenderer {
         screen_descriptor: ScreenDescriptor,
     ) {
         if !self.frame_started {
-            return;
+            panic!("begin_frame must be called before end_frame_and_draw can be called!");
         }
 
-        let full_output = self.state.end_pass(Some(window));
-        let paint_jobs = self
-            .state
-            .context()
-            .tessellate(full_output.shapes, self.state.context().pixels_per_point());
-        let textures_delta: egui::TexturesDelta = full_output.textures_delta;
+        self.ppp(screen_descriptor.pixels_per_point);
 
-        self.renderer
-            .add_textures(device, queue, &textures_delta)
-            .expect("add texture ok");
-        self.renderer
-            .update_buffers(device, queue, &paint_jobs, &screen_descriptor);
+        let full_output = self.state.egui_ctx().end_pass();
 
-        self.renderer
-            .execute(
-                encoder,
-                window_surface_view,
-                &paint_jobs,
-                &screen_descriptor,
-                Some(wgpu::Color::BLACK),
-            )
-            .expect("egui execute ok");
+        self.state
+            .handle_platform_output(window, full_output.platform_output);
 
-        // self.ppp(window.scale_factor() as f32);
+        let tris = self
+            .state
+            .egui_ctx()
+            .tessellate(full_output.shapes, self.state.egui_ctx().pixels_per_point());
+        for (id, image_delta) in &full_output.textures_delta.set {
+            self.renderer
+                .update_texture(device, queue, *id, image_delta);
+        }
+        self.renderer
+            .update_buffers(device, queue, encoder, &tris, &screen_descriptor);
+        let rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
+            color_attachments: &[Some(wgpu::RenderPassColorAttachment {
+                view: window_surface_view,
+                resolve_target: None,
+                ops: egui_wgpu::wgpu::Operations {
+                    load: egui_wgpu::wgpu::LoadOp::Load,
+                    store: StoreOp::Store,
+                },
+            })],
+            depth_stencil_attachment: None,
+            timestamp_writes: None,
+            label: Some("egui main render pass"),
+            occlusion_query_set: None,
+        });
 
         self.renderer
-            .remove_textures(textures_delta)
-            .expect("remove texture ok");
+            .render(&mut rpass.forget_lifetime(), &tris, &screen_descriptor);
+        for x in &full_output.textures_delta.free {
+            self.renderer.free_texture(x)
+        }
 
         self.frame_started = false;
     }
diff --git a/dropbear-engine/src/graphics.rs b/dropbear-engine/src/graphics.rs
index 60197a2..625258a 100644
--- a/dropbear-engine/src/graphics.rs
+++ b/dropbear-engine/src/graphics.rs
@@ -44,7 +44,7 @@ pub struct FrameGraphicsContext<'a> {
 
 impl SharedGraphicsContext {
     pub fn get_egui_context(&self) -> Context {
-        self.egui_renderer.lock().context()
+        self.egui_renderer.lock().context().clone()
     }
 
     pub fn create_uniform<T>(&self, uniform: T, label: Option<&str>) -> Buffer
@@ -191,7 +191,6 @@ impl<'a> RenderContext<'a> {
                         load: wgpu::LoadOp::Clear(color),
                         store: wgpu::StoreOp::Store,
                     },
-                    depth_slice: None,
                 })],
                 depth_stencil_attachment: Some(RenderPassDepthStencilAttachment {
                     view: &self.frame.depth_texture.view,
diff --git a/dropbear-engine/src/lib.rs b/dropbear-engine/src/lib.rs
index 3c60f2b..a560004 100644
--- a/dropbear-engine/src/lib.rs
+++ b/dropbear-engine/src/lib.rs
@@ -17,7 +17,7 @@ use app_dirs2::{AppDataType, AppInfo};
 use chrono::Local;
 use colored::Colorize;
 use egui::TextureId;
-use egui_wgpu_backend::ScreenDescriptor;
+use egui_wgpu::ScreenDescriptor;
 use env_logger::Builder;
 use futures::executor::block_on;
 use gilrs::{Gilrs, GilrsBuilder};
@@ -173,9 +173,9 @@ Hardware:
                 label: Some("texture_bind_group_layout"),
             });
 
-        let mut egui_renderer = Arc::new(Mutex::new(EguiRenderer::new(&device, config.format, 1, &window)));
+        let mut egui_renderer = Arc::new(Mutex::new(EguiRenderer::new(&device, config.format, None, 1, &window)));
 
-        let texture_id = Arc::get_mut(&mut egui_renderer).unwrap().lock().renderer().egui_texture_from_wgpu_texture(
+        let texture_id = Arc::get_mut(&mut egui_renderer).unwrap().lock().renderer().register_native_texture(
             &device,
             &viewport_texture.view,
             wgpu::FilterMode::Linear,
@@ -212,15 +212,15 @@ Hardware:
             Texture::create_depth_texture(&self.config, &self.device, Some("depth texture"));
         self.viewport_texture =
             Texture::create_viewport_texture(&self.config, &self.device, Some("viewport texture"));
-        self.texture_id = Arc::get_mut(&mut self
+        Arc::get_mut(&mut self
             .egui_renderer).unwrap().lock()
             .renderer()
-            .egui_texture_from_wgpu_texture(
+            .update_egui_texture_from_wgpu_texture(
                 &self.device,
                 &self.viewport_texture.view,
                 wgpu::FilterMode::Linear,
-            )
-            .into();
+                *self.texture_id
+            );
     }
 
     /// Asynchronously renders the scene and the egui renderer. I don't know what else to say.
@@ -261,12 +261,9 @@ Hardware:
             },
         };
 
-        let size = self.window.inner_size();
-
         let screen_descriptor = ScreenDescriptor {
-            physical_width: size.width,
-            physical_height: size.height,
-            scale_factor: self.window.scale_factor() as f32,
+            size_in_pixels: [self.config.width, self.config.height],
+            pixels_per_point: self.window.scale_factor() as f32,
         };
 
         let view = output
@@ -280,10 +277,10 @@ Hardware:
 
         let viewport_view = { &self.viewport_texture.view.clone() };
 
-        self.egui_renderer.lock().begin_frame();
+        self.egui_renderer.lock().begin_frame(&self.window);
 
         let mut graphics = graphics::RenderContext::from_state(self, viewport_view, &mut encoder);
-        
+
         scene_manager
             .update(previous_dt, &mut graphics, event_loop)
             .await;
@@ -562,7 +559,7 @@ impl ApplicationHandler for App {
             None => return,
         };
 
-        state.egui_renderer.lock().handle_input(&event);
+        state.egui_renderer.lock().handle_input(&state.window, &event);
 
         match event {
             WindowEvent::CloseRequested => {
diff --git a/dropbear-engine/src/panic.rs b/dropbear-engine/src/panic.rs
index 8d2dfdf..620da7e 100644
--- a/dropbear-engine/src/panic.rs
+++ b/dropbear-engine/src/panic.rs
@@ -44,5 +44,7 @@ pub fn set_hook() {
                 .set_level(MessageLevel::Error)
                 .show();
         }
+
+        log::error!("Additional crash info (backtrace): \n{:#?}", backtrace::Backtrace::new().frames());
     }));
 }
diff --git a/eucalyptus-core/src/input.rs b/eucalyptus-core/src/input.rs
index 130c946..018bd0c 100644
--- a/eucalyptus-core/src/input.rs
+++ b/eucalyptus-core/src/input.rs
@@ -3,9 +3,8 @@ use std::{
     time::{Duration, Instant},
 };
 
-use winit::{event::MouseButton, keyboard::KeyCode, platform::scancode::PhysicalKeyExtScancode};
+use winit::{event::MouseButton, keyboard::KeyCode};
 
-use crate::scripting::{DropbearScriptingAPIContext};
 
 #[derive(Clone)]
 pub struct InputState {
diff --git a/eucalyptus-editor/src/menu.rs b/eucalyptus-editor/src/menu.rs
index f378490..c914c24 100644
--- a/eucalyptus-editor/src/menu.rs
+++ b/eucalyptus-editor/src/menu.rs
@@ -160,7 +160,7 @@ impl Scene for MainMenu {
             graphics.shared.window.inner_size().height as f32 - 100.0,
         );
         let egui_ctx = graphics.shared.get_egui_context();
-
+        let mut local_open_project = false;
         egui::CentralPanel::default()
                 .frame(Frame::new())
                 .show(&egui_ctx, |ui| {
@@ -184,37 +184,7 @@ impl Scene for MainMenu {
                             .add_sized(button_size, egui::Button::new("Open Project"))
                             .clicked()
                         {
-                            log::debug!("Opening project");
-                            self.is_in_file_dialogue = true;
-                            if let Some(path) = rfd::FileDialog::new()
-                                .add_filter("Eucalyptus Configuration Files", &["eucp"])
-                                .pick_file()
-                            {
-                                match ProjectConfig::read_from(&path) {
-                                    Ok(config) => {
-                                        log::info!("Loaded project!");
-                                        let mut global = PROJECT.write();
-                                        *global = config;
-                                        // println!("Loaded config info: {:#?}", global);
-                                        self.scene_command =
-                                            SceneCommand::SwitchScene(String::from("editor"));
-                                    }
-                                    Err(e) => if e.to_string().contains("missing field") {
-                                        self.toast.add(egui_toast_fork::Toast {
-                                            kind: egui_toast_fork::ToastKind::Error,
-                                            text: format!("Your project version is not up to date with the current project version").into(),
-                                            options: ToastOptions::default()
-                                                .duration_in_seconds(10.0)
-                                                .show_progress(true),
-                                            ..Default::default()
-                                        });
-                                        log::error!("Failed to load project: {}", e);
-                                    }
-                                };
-                            } else {
-                                log::warn!("File dialog returned \"None\"");
-                            }
-                            self.is_in_file_dialogue = false;
+                            local_open_project = true;
                         }
                         ui.add_space(20.0);
 
@@ -236,7 +206,42 @@ impl Scene for MainMenu {
                     });
                 });
 
+        if local_open_project {
+            log::debug!("Opening project");
+            self.is_in_file_dialogue = true;
+            if let Some(path) = rfd::AsyncFileDialog::new()
+                .add_filter("Eucalyptus Configuration Files", &["eucp"])
+                .pick_file().await
+            {
+                match ProjectConfig::read_from(&path.into()) {
+                    Ok(config) => {
+                        log::info!("Loaded project!");
+                        let mut global = PROJECT.write();
+                        *global = config;
+                        // println!("Loaded config info: {:#?}", global);
+                        self.scene_command =
+                            SceneCommand::SwitchScene(String::from("editor"));
+                    }
+                    Err(e) => if e.to_string().contains("missing field") {
+                        self.toast.add(egui_toast_fork::Toast {
+                            kind: egui_toast_fork::ToastKind::Error,
+                            text: format!("Your project version is not up to date with the current project version").into(),
+                            options: ToastOptions::default()
+                                .duration_in_seconds(10.0)
+                                .show_progress(true),
+                            ..Default::default()
+                        });
+                        log::error!("Failed to load project: {}", e);
+                    }
+                };
+            } else {
+                log::warn!("File dialog returned \"None\"");
+            }
+            self.is_in_file_dialogue = false;
+        }
+
         let mut show_new_project = self.show_new_project;
+        let mut local_select_project = false;
         egui::Window::new("Create new project")
             .open(&mut show_new_project)
             .resizable(true)
@@ -260,16 +265,7 @@ impl Scene for MainMenu {
 
                     ui.add_space(5.0);
                     if ui.button("Choose Location").clicked() {
-                        self.is_in_file_dialogue = true;
-                        if let Some(path) = rfd::FileDialog::new()
-                            .set_title("Save Project")
-                            .set_file_name(&self.project_name)
-                            .pick_folder()
-                        {
-                            self.project_path = Some(path);
-                            log::debug!("Project will be saved at: {:?}", self.project_path);
-                        }
-                        self.is_in_file_dialogue = false;
+                        local_select_project = true;
                     }
 
                     let can_create = self.project_path.is_some() && !self.project_name.is_empty();
@@ -285,6 +281,19 @@ impl Scene for MainMenu {
             });
         self.show_new_project = show_new_project;
 
+        if local_select_project {
+            self.is_in_file_dialogue = true;
+            if let Some(path) = rfd::AsyncFileDialog::new()
+                .set_title("Save Project")
+                .set_file_name(&self.project_name)
+                .pick_folder().await
+            {
+                self.project_path = Some(path.into());
+                log::debug!("Project will be saved at: {:?}", self.project_path);
+            }
+            self.is_in_file_dialogue = false;
+        }
+
         if let Some(rx) = self.progress_rx.as_mut() {
             while let Ok(progress) = rx.try_recv() {
                 match progress {
diff --git a/redback-runtime b/redback-runtime
index ba32a23..5cb98c0 160000
--- a/redback-runtime
+++ b/redback-runtime
@@ -1 +1 @@
-Subproject commit ba32a2319d7b302c0d294311a9ad3135e9eb8503
+Subproject commit 5cb98c0d508c7f8fd7d6a268d101d6e0fde0f41f