2022-01-16 08:43:00 -06:00
|
|
|
Overview
|
|
|
|
|
==
|
|
|
|
|
As the popularity of the library [minifb](https://crates.io/crates/minifb) shows, it is useful to put a 2D buffer/image
|
|
|
|
|
on a window in a platform-independent way. Minifb's approach to doing window management itself, however, is problematic
|
|
|
|
|
code duplication. We already have very high quality libraries for this in the Rust ecosystem
|
|
|
|
|
(such as [winit](https://crates.io/crates/winit)), and minifb's implementation of window management is not ideal. For
|
|
|
|
|
example, it occasionally segfaults on some platforms and is missing key features such as the ability to set a window
|
|
|
|
|
icon. While it would be possible to add these features to minifb, it makes more sense to instead use the standard
|
|
|
|
|
window handling systems.
|
|
|
|
|
|
2022-12-22 18:43:54 -06:00
|
|
|
Softbuffer integrates with the [raw-window-handle](https://crates.io/crates/raw-window-handle) crate
|
2022-01-16 08:43:00 -06:00
|
|
|
to allow writing to a window in a cross-platform way while using the very high quality dedicated window management
|
|
|
|
|
libraries that are available in the Rust ecosystem.
|
|
|
|
|
|
2022-12-22 18:43:54 -06:00
|
|
|
What about [pixels](https://crates.io/crates/pixels)? Pixels accomplishes a very similar goal to Softbuffer,
|
2022-01-16 08:43:00 -06:00
|
|
|
however there are two key differences. Pixels provides some capacity for GPU-accelerated post-processing of what is
|
2022-12-22 18:43:54 -06:00
|
|
|
displayed, while Softbuffer does not. Due to not having this post-processing, Softbuffer does not rely on the GPU or
|
2022-12-20 07:07:08 -07:00
|
|
|
hardware accelerated graphics stack in any way, and is thus more portable to installations that do not have access to
|
2022-12-22 18:43:54 -06:00
|
|
|
hardware acceleration (e.g. VMs, older computers, computers with misconfigured drivers). Softbuffer should be used over
|
2022-01-16 08:43:00 -06:00
|
|
|
pixels when its GPU-accelerated post-processing effects are not needed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
License & Credits
|
|
|
|
|
==
|
|
|
|
|
|
|
|
|
|
This library is dual-licensed under MIT or Apache-2.0, just like minifb and rust. Significant portions of code were taken
|
|
|
|
|
from the minifb library to do platform-specific work.
|
|
|
|
|
|
|
|
|
|
Platform support:
|
|
|
|
|
==
|
2022-12-20 07:07:08 -07:00
|
|
|
Some, but not all, platforms supported in [raw-window-handle](https://crates.io/crates/raw-window-handle) are supported
|
2022-12-22 18:43:54 -06:00
|
|
|
by Softbuffer. Pull requests are welcome to add new platforms! **Nonetheless, all major desktop platforms that winit uses
|
2022-01-19 21:57:09 -06:00
|
|
|
on desktop are supported.**
|
2022-01-16 08:43:00 -06:00
|
|
|
|
|
|
|
|
For now, the priority for new platforms is:
|
|
|
|
|
1) to have at least one platform on each OS working (e.g. one of Win32 or WinRT, or one of Xlib, Xcb, and Wayland) and
|
|
|
|
|
2) for that one platform on each OS to be the one that winit uses.
|
|
|
|
|
|
|
|
|
|
(PRs will be accepted for any platform, even if it does not follow the above priority.)
|
|
|
|
|
|
|
|
|
|
✅: Present | ❌: Absent
|
|
|
|
|
- AndroidNdk ❌
|
2022-05-22 18:20:40 -05:00
|
|
|
- AppKit ✅ (Thanks to [Seo Sanghyeon](https://github.com/sanxiyn) and [lunixbochs](https://github.com/lunixbochs)!)
|
2022-12-07 11:27:36 -07:00
|
|
|
- Orbital ✅
|
2022-01-16 08:43:00 -06:00
|
|
|
- UiKit ❌
|
2022-01-19 21:11:20 -06:00
|
|
|
- Wayland ✅ (Wayland support in winit is immature at the moment, so it might be wise to force X11 if you're using winit)
|
2022-05-22 18:20:40 -05:00
|
|
|
- Web ✅ (Thanks to [Liamolucko](https://github.com/Liamolucko)!)
|
2022-01-16 08:43:00 -06:00
|
|
|
- Win32 ✅
|
|
|
|
|
- WinRt ❌
|
|
|
|
|
- Xcb ❌
|
|
|
|
|
- Xlib ✅
|
|
|
|
|
|
2023-02-20 10:37:25 -08:00
|
|
|
WebAssembly
|
|
|
|
|
-----------
|
|
|
|
|
|
|
|
|
|
To run an example with the web backend: `cargo run-wasm --example winit`
|
|
|
|
|
|
2022-01-16 08:43:00 -06:00
|
|
|
Example
|
|
|
|
|
==
|
2022-12-22 09:23:46 +13:00
|
|
|
```rust,no_run
|
2022-01-16 08:43:00 -06:00
|
|
|
use winit::event::{Event, WindowEvent};
|
|
|
|
|
use winit::event_loop::{ControlFlow, EventLoop};
|
|
|
|
|
use winit::window::WindowBuilder;
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let event_loop = EventLoop::new();
|
|
|
|
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
2023-01-06 13:08:17 -08:00
|
|
|
let context = unsafe { softbuffer::Context::new(&window) }.unwrap();
|
|
|
|
|
let mut surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap();
|
2022-01-16 08:43:00 -06:00
|
|
|
|
|
|
|
|
event_loop.run(move |event, _, control_flow| {
|
|
|
|
|
*control_flow = ControlFlow::Wait;
|
|
|
|
|
|
|
|
|
|
match event {
|
2022-12-20 08:43:26 -07:00
|
|
|
Event::RedrawRequested(window_id) if window_id == window.id() => {
|
2022-01-16 08:43:00 -06:00
|
|
|
let (width, height) = {
|
2022-12-20 08:43:26 -07:00
|
|
|
let size = window.inner_size();
|
2022-01-16 08:43:00 -06:00
|
|
|
(size.width, size.height)
|
|
|
|
|
};
|
2022-01-16 08:59:29 -06:00
|
|
|
let buffer = (0..((width * height) as usize))
|
|
|
|
|
.map(|index| {
|
|
|
|
|
let y = index / (width as usize);
|
|
|
|
|
let x = index % (width as usize);
|
|
|
|
|
let red = x % 255;
|
|
|
|
|
let green = y % 255;
|
|
|
|
|
let blue = (x * y) % 255;
|
2022-01-16 08:43:00 -06:00
|
|
|
|
2022-01-16 08:59:29 -06:00
|
|
|
let color = blue | (green << 8) | (red << 16);
|
2022-01-16 08:43:00 -06:00
|
|
|
|
2022-01-16 08:59:29 -06:00
|
|
|
color as u32
|
|
|
|
|
})
|
|
|
|
|
.collect::<Vec<_>>();
|
2022-01-16 08:43:00 -06:00
|
|
|
|
2023-01-06 13:08:17 -08:00
|
|
|
surface.set_buffer(&buffer, width as u16, height as u16);
|
2022-01-16 08:43:00 -06:00
|
|
|
}
|
|
|
|
|
Event::WindowEvent {
|
|
|
|
|
event: WindowEvent::CloseRequested,
|
2022-01-16 08:59:29 -06:00
|
|
|
window_id,
|
2022-12-20 08:43:26 -07:00
|
|
|
} if window_id == window.id() => {
|
2022-01-16 08:43:00 -06:00
|
|
|
*control_flow = ControlFlow::Exit;
|
2022-01-16 08:59:29 -06:00
|
|
|
}
|
2022-01-16 08:43:00 -06:00
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2022-05-22 18:20:40 -05:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Changelog
|
|
|
|
|
---------
|
|
|
|
|
|
2023-01-26 17:15:14 -05:00
|
|
|
See the [changelog](CHANGELOG.md) for a list of this package's versions and the changes made in each version.
|