15 个版本
0.4.5 | 2024年6月24日 |
---|---|
0.4.3 | 2024年5月19日 |
0.4.1 | 2024年1月11日 |
0.4.0 | 2023年11月14日 |
0.1.0 | 2022年1月20日 |
#5 in GUI
105,001 每月下载量
在 128 个包(31 个直接使用) 中使用
150KB
3K SLoC
概述
正如库 minifb 的流行所显示,将 2D 缓冲区/图像以平台无关的方式放置在窗口中是有用的。然而,minifb 自己处理窗口管理的方法存在代码重复的问题。Rust 生态系统(如 winit)中已经有了非常高质量的库,而 minifb 的窗口管理实现并不理想。例如,它在某些平台上偶尔会发生段错误,并且缺少设置窗口图标等关键功能。虽然可以向 minifb 添加这些功能,但使用标准的窗口处理系统更有意义。
Softbuffer 集成了 raw-window-handle 包,允许以跨平台的方式向窗口写入,同时使用 Rust 生态系统中可用的非常高质量的专用窗口管理库。
关于 pixels 呢?Pixels 与 Softbuffer 实现了非常相似的目标,但存在两个关键区别。Pixels 提供了对显示内容的 GPU 加速后处理的容量,而 Softbuffer 则没有。由于没有这种后处理,Softbuffer 不依赖于 GPU 或硬件加速的图形堆栈,因此更适合在没有硬件加速的安装环境中使用(例如 VM、旧电脑、配置错误的驱动程序的电脑)。当不需要 GPU 加速的后处理效果时,应使用 Softbuffer 而不是 pixels。
许可证 & 致谢
本库采用 MIT 或 Apache-2.0 许可证双授权,与 minifb 和 rust 相同。代码中有很大一部分来自 minifb 库,用于执行特定平台的工作。
平台支持
Softbuffer 支持部分但在 raw-window-handle 中并非所有平台。欢迎提交拉取请求添加新平台!不过,所有 winit 在桌面使用的桌面主要平台都得到了支持。
目前,新平台的支持优先级是
- 在每个操作系统上至少有一个平台能够工作(例如 Win32 或 WinRT 中的一个,或者 Xlib、Xcb 和 Wayland 中的一个),并且
- 每个操作系统上的这个平台应该是 winit 使用的平台。
(即使它不符合上述优先级,也会接受任何平台的拉取请求。)
平台 | |
---|---|
Android NDK | ❌ |
AppKit | ✅ |
Orbital | ✅ |
UIKit | ❌ |
Wayland | ✅ |
Web | ✅ |
Win32 | ✅ |
WinRT | ❌ |
XCB | ✅ |
Xlib | ✅ |
✅: 存在
❔: 不成熟
❌: 不存在
WebAssembly
要运行使用 Web 后端的示例: cargo run-wasm --example winit
示例
use std::num::NonZeroU32;
use std::rc::Rc;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::Window;
include!("../examples/utils/winit_app.rs");
fn main() {
let event_loop = EventLoop::new().unwrap();
let mut app = winit_app::WinitAppBuilder::with_init(|elwt| {
let window = {
let window = elwt.create_window(Window::default_attributes());
Rc::new(window.unwrap())
};
let context = softbuffer::Context::new(window.clone()).unwrap();
let surface = softbuffer::Surface::new(&context, window.clone()).unwrap();
(window, surface)
}).with_event_handler(|state, event, elwt| {
let (window, surface) = state;
elwt.set_control_flow(ControlFlow::Wait);
match event {
Event::WindowEvent { window_id, event: WindowEvent::RedrawRequested } if window_id == window.id() => {
let (width, height) = {
let size = window.inner_size();
(size.width, size.height)
};
surface
.resize(
NonZeroU32::new(width).unwrap(),
NonZeroU32::new(height).unwrap(),
)
.unwrap();
let mut buffer = surface.buffer_mut().unwrap();
for index in 0..(width * height) {
let y = index / width;
let x = index % width;
let red = x % 255;
let green = y % 255;
let blue = (x * y) % 255;
buffer[index as usize] = blue | (green << 8) | (red << 16);
}
buffer.present().unwrap();
}
Event::WindowEvent {
event: WindowEvent::CloseRequested,
window_id,
} if window_id == window.id() => {
elwt.exit();
}
_ => {}
}
});
event_loop.run_app(&mut app).unwrap();
}
变更日志
请参阅 变更日志,了解此包的各个版本及其每个版本中的更改。
依赖项
~0.1–18MB
~212K SLoC