5个版本
0.0.6 | 2023年5月8日 |
---|---|
0.0.5 | 2023年5月7日 |
#90 in 渲染
每月55次下载
82KB
1.5K SLoC
minigw
一个方便的Rust库,用于创建跨平台窗口并显示像素缓冲区。它还使得获取键盘和鼠标输入变得容易。内置了完整的imgui渲染支持。
用法
将此添加到您的 Cargo.toml
[dependencies]
minigw = "0.0.6"
此示例展示了如何创建窗口以及如何每帧绘制渐变。
extern crate minigw;
fn main() {
minigw::new::<u8, _>("Example", 1280, 720,
move |input, render_texture, imgui| {
let mut render_texture = render_texture.as_mut();
// Draw a red and green gradient.
for x in 0..render_texture.width() {
for y in 0..render_texture.height() {
let uv = (x as f32 / render_texture.width() as f32, y as f32 / render_texture.height() as f32);
render_texture.set_pixel(x, y, &[(uv.0 * 255.99) as u8, (uv.1 * 255.99) as u8, 0]);
}
}
});
}
计划中的功能
- 伽玛校正
- 窗口图标
- 帧缓冲区缩放
- f32 (HDR) 颜色转换
- 可调节的色彩分级
- 专用渲染线程
许可证
本项目采用MIT许可证(LICENSE-MIT 或 https://opensource.org/licenses/MIT)。
示例
输入处理 & ImGui
可以通过查询输入结构的当前状态来处理输入。此示例将在每次按下空格键时切换光标状态(解锁和锁定)。可以通过直接访问 imgui::Ui
结构来绘制调试UI。
extern crate minigw;
use minigw::imgui;
fn main() {
minigw::new::<u8, _>("Example", 1280, 720,
move |input, render_texture, imgui| {
// ...
// Toggle the cursor mode between FREE and LOCKED.
let mut input_mut = input.as_mut();
if input_mut.key_down(minigw::VirtualKeyCode::Space) {
input_mut.toggle_cursor_mode();
}
imgui.window("Example window")
.size([400.0, 700.0], imgui::Condition::FirstUseEver)
.build(|| {
let mut x = 0.0;
imgui.slider("Slider", 0.0, 1.0, &mut x);
});
});
}
帧缓冲区类型
在创建新窗口时可以定义帧缓冲区类型。出于性能考虑,u8
最好,但其他支持的类型还有:i8
、u16
、i16
、u32
、i32
和 f32
。下面是一个使用 f32
帧缓冲区的相同渐变示例。
extern crate minigw;
fn main() {
minigw::new::<f32, _>("Example", 1280, 720,
move |input, render_texture, imgui| {
// ...
// ...
render_texture.set_pixel(x, y, &[uv.0, uv.1, 0]);
});
}
窗口 & 帧缓冲区缩放
可以启用和禁用窗口的缩放。帧缓冲区的rendertexture可以:与窗口一起缩放、以一定比例缩放窗口或与窗口不一起缩放。下面的示例展示了如何在这些模式之间切换。
extern crate minigw;
fn main() {
let mut mode = 0;
minigw::new::<u8, _>("Example", 1280, 720,
move |window, input, render_texture, _imgui| {
let window_mut = window.as_mut();
let input_mut = input.as_mut();
let mut render_texture = render_texture.as_mut();
// Draw checkerboard pattern.
for x in 0..render_texture.get_width() {
for y in 0..render_texture.get_height() {
if (x / 60 + y / 60) % 2 == 0 {
render_texture.set_pixel(x, y, &[255, 255, 255]);
} else {
render_texture.set_pixel(x, y, &[0, 0, 0]);
}
}
}
// Toggle window resizability.
if input_mut.key_down(minigw::VirtualKeyCode::Space) {
window_mut.set_resizable(!window_mut.is_resizable());
}
// Loop over all RenderTextureResizing modes.
if input_mut.key_down(minigw::VirtualKeyCode::M) {
mode = (mode + 1) % 3;
let rtm = match mode {
0 => minigw::RenderTextureResizing::Resizable,
1 => minigw::RenderTextureResizing::ResizableScaled(0.3),
_ => minigw::RenderTextureResizing::NonResizable
};
render_texture.set_resizing_mode(rtm);
}
});
}
添加窗口和任务栏图标
添加窗口图标需要一个像素数据的 Vec<u8>
。为了获取这些数据,这个示例使用了 stb_image crate,但您也可以使用最适合您需求的任何图像库。
extern crate minigw;
extern crate stb_image;
fn load_img(path: &str) -> (Vec<u8>, u32, u32) {
let cpath = std::ffi::CString::new(path.as_bytes()).unwrap();
unsafe {
let mut width = 0;
let mut height = 0;
let mut channels = 0;
let data = stb_image::stb_image::bindgen::stbi_load(
cpath.as_ptr(),
&mut width,
&mut height,
&mut channels,
4
);
assert!(!data.is_null(), "Failed to read image file at \"{:?}\"", path);
let data: Vec<u8> = std::slice::from_raw_parts(data, (width * height * 4) as usize).to_vec();
(data, width as u32, height as u32)
}
}
fn main() {
let mut once = true;
minigw::new::<u8, _>("Example", 1280, 720,
move |window, _input, _render_texture, _imgui| {
if once {
once = false;
let (rgba, width, height) = load_img("assets/rust.png");
let icon = minigw::window::Icon::from_rgba(rgba, width, height).unwrap();
window.as_mut().set_icon(Some(icon));
}
});
}
依赖关系
~16–28MB
~423K SLoC