Skip to content

Commit

Permalink
rough sdl2 backend
Browse files Browse the repository at this point in the history
  • Loading branch information
tedsteen committed Sep 8, 2023
1 parent 2338a85 commit 57e8645
Show file tree
Hide file tree
Showing 9 changed files with 787 additions and 6 deletions.
34 changes: 34 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 18 additions & 5 deletions crates/egui_glow/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ clipboard = ["egui-winit?/clipboard"]

## For the `winit` integration:
## enable opening links in a browser when an egui hyperlink is clicked.
links = ["egui-winit?/links"]
links = ["egui-winit?/links", "webbrowser"]

## Enable profiling with the [`puffin`](https://docs.rs/puffin) crate.
puffin = ["dep:puffin", "egui-winit?/puffin", "egui/puffin"]

## Enable [`winit`](https://docs.rs/winit) integration.
winit = ["egui-winit"]

## Enable [`sdl2`](https://docs.rs/sdl2) integration.
sdl2 = ["dep:sdl2"]

[dependencies]
egui = { version = "0.22.0", path = "../egui", default-features = false, features = [
Expand All @@ -61,6 +63,11 @@ document-features = { version = "0.2", optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
egui-winit = { version = "0.22.0", path = "../egui-winit", optional = true, default-features = false }
puffin = { version = "0.16", optional = true }
sdl2 = { git = "https://github.com/Rust-SDL2/rust-sdl2.git", features = [
"bundled",
"static-link",
], optional = true }
webbrowser = { version = "0.8.3", optional = true }

# Web:
[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand All @@ -69,11 +76,17 @@ wasm-bindgen = { version = "0.2" }


[dev-dependencies]
glutin = "0.30" # examples/pure_glow
raw-window-handle = "0.5.0"
# examples/pure_glow_winit
glutin = "0.30"
glutin-winit = "0.3.0"

raw-window-handle = "0.5.0"
# examples/pure_glow_sdl2
env_logger = "0.10"

[[example]]
name = "pure_glow"
name = "pure_glow_winit"
required-features = ["winit", "egui/default_fonts"]

[[example]]
name = "pure_glow_sdl2"
required-features = ["sdl2", "egui/default_fonts"]
97 changes: 97 additions & 0 deletions crates/egui_glow/examples/pure_glow_sdl2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//! Example how to use pure `egui_glow` with `sdl2`.
#![allow(unsafe_code)]

fn main() {
env_logger::init();
let sdl = sdl2::init().unwrap();
let video = sdl.video().unwrap();
let gl_attr = video.gl_attr();
gl_attr.set_context_profile(sdl2::video::GLProfile::Core);
gl_attr.set_context_version(3, 0);
let window = video
.window("Hello egui sdl2!", 1024, 769)
.opengl()
.resizable()
.allow_highdpi()
.build()
.unwrap();
let gl_context = window.gl_create_context().unwrap();
window
.subsystem()
.gl_set_swap_interval(sdl2::video::SwapInterval::LateSwapTearing)
.or_else(|_| {
window
.subsystem()
.gl_set_swap_interval(sdl2::video::SwapInterval::VSync)
})
.expect("Could not gl_set_swap_interval(...)");

let (gl, window, mut events_loop, _gl_context) = {
let gl = unsafe {
glow::Context::from_loader_function(|s| video.gl_get_proc_address(s) as *const _)
};
let event_loop = sdl.event_pump().unwrap();
(gl, window, event_loop, gl_context)
};
let gl = std::sync::Arc::new(gl);
let mut egui_glow = egui_glow::sdl2::EguiGlow::new(&window, gl.clone(), None);

let clipboard = &mut sdl.video().unwrap().clipboard();

let mut clear_colour: [f32; 3] = [0.1, 0.1, 0.1];
let mut name = "Ted";
let mut age = 41;

'mainloop: loop {
let mut quit_clicked: bool = false;
egui_glow.run(&window, clipboard, |egui_ctx| {
egui::SidePanel::left("my_left_side_panel").show(egui_ctx, |ui| {
ui.heading("Hello World!");
if ui.button("Quit").clicked() {
quit_clicked = true;
}
ui.color_edit_button_rgb(&mut clear_colour);
ui.hyperlink_to("here", "http://www.google.com");
});
egui::SidePanel::right("my_right_side_panel").show(egui_ctx, |ui| {
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 '{name}', age {age}"));
});
});

if quit_clicked {
break 'mainloop;
}

unsafe {
use glow::HasContext as _;
gl.clear_color(clear_colour[0], clear_colour[1], clear_colour[2], 1.0);
gl.clear(glow::COLOR_BUFFER_BIT);
}

// draw things behind egui here

egui_glow.paint(&window);

// draw things on top of egui here
window.gl_swap_window();

for event in events_loop.poll_iter() {
//repaint_after = std::time::Duration::from_secs(0);
egui_glow.on_event(&event, &window);

if let sdl2::event::Event::Quit { .. } = event {
break 'mainloop;
}
}
}
}
126 changes: 126 additions & 0 deletions crates/egui_glow/examples/pure_glow_sdl2_resize_fix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//! Example how to use pure `egui_glow` with `sdl2`.
#![allow(unsafe_code)]

fn main() {
env_logger::init();
let sdl = sdl2::init().unwrap();
let video = sdl.video().unwrap();
let gl_attr = video.gl_attr();
gl_attr.set_context_profile(sdl2::video::GLProfile::Core);
gl_attr.set_context_version(3, 0);
let window = video
.window("Hello egui sdl2!", 1024, 769)
.opengl()
.resizable()
.allow_highdpi()
.build()
.unwrap();
let gl_context = window.gl_create_context().unwrap();
window
.subsystem()
.gl_set_swap_interval(sdl2::video::SwapInterval::LateSwapTearing)
.or_else(|_| {
window
.subsystem()
.gl_set_swap_interval(sdl2::video::SwapInterval::VSync)
})
.expect("Could not gl_set_swap_interval(...)");

let (gl, window, mut events_loop, _gl_context) = {
let gl = unsafe {
glow::Context::from_loader_function(|s| video.gl_get_proc_address(s) as *const _)
};
let event_loop = sdl.event_pump().unwrap();
(gl, window, event_loop, gl_context)
};
let gl = std::sync::Arc::new(gl);
let mut egui_glow = egui_glow::sdl2::EguiGlow::new(&window, gl.clone(), None);

let clipboard = &mut sdl.video().unwrap().clipboard();

let mut clear_colour: [f32; 3] = [0.1, 0.1, 0.1];
let mut name = "Ted";
let mut age = 41;

let handle_events = std::sync::Arc::new(std::sync::Mutex::new(
|event: Option<sdl2::event::Event>| {
let mut quit_clicked: bool = false;
egui_glow.run(&window, clipboard, |egui_ctx| {
egui::SidePanel::left("my_left_side_panel").show(egui_ctx, |ui| {
ui.heading("Hello World!");
if ui.button("Quit").clicked() {
quit_clicked = true;
}
ui.color_edit_button_rgb(&mut clear_colour);
ui.hyperlink_to("here", "http://www.google.com");
});
egui::SidePanel::right("my_right_side_panel").show(egui_ctx, |ui| {
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 '{name}', age {age}"));
});
});

if quit_clicked {
return false;
}

unsafe {
use glow::HasContext as _;
gl.clear_color(clear_colour[0], clear_colour[1], clear_colour[2], 1.0);
gl.clear(glow::COLOR_BUFFER_BIT);
}

// draw things behind egui here

egui_glow.paint(&window);

// draw things on top of egui here
window.gl_swap_window();

if let Some(event) = event {
//repaint_after = std::time::Duration::from_secs(0);
egui_glow.on_event(&event, &window);

if let sdl2::event::Event::Quit { .. } = event {
return false;
}
}
return true;
},
));

let try_handle = |event: Option<sdl2::event::Event>| -> bool {
if let Ok(handle) = &mut handle_events.try_lock() {
handle(event)
} else {
true
}
};

//Note: this is a workaround for https://stackoverflow.com/a/40693139
let _event_watch = sdl.event().unwrap().add_event_watch(|event| {
use sdl2::event::{Event, WindowEvent};
if let Event::Window {
win_event: WindowEvent::Resized(..) | WindowEvent::SizeChanged(..),
..
} = event
{
try_handle(Some(event));
};
});

'mainloop: loop {
if !try_handle(events_loop.wait_event_timeout(5)) {
break 'mainloop;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ fn main() {
let (gl_window, gl) = create_display(&event_loop);
let gl = std::sync::Arc::new(gl);

let mut egui_glow = egui_glow::EguiGlow::new(&event_loop, gl.clone(), None);
let mut egui_glow = egui_glow::winit::EguiGlow::new(&event_loop, gl.clone(), None);

event_loop.run(move |event, _, control_flow| {
let mut redraw = || {
Expand Down
5 changes: 5 additions & 0 deletions crates/egui_glow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ pub mod winit;
#[cfg(all(not(target_arch = "wasm32"), feature = "winit"))]
pub use winit::*;

#[cfg(feature = "sdl2")]
pub mod sdl2;
#[cfg(feature = "sdl2")]
pub use crate::sdl2::*;

/// Check for OpenGL error and report it using `log::error`.
///
/// Only active in debug builds!
Expand Down
Loading

0 comments on commit 57e8645

Please sign in to comment.