#framebuffer #graphics #cross-platform #mouse-input #window #game

minigw

一个方便的Rust库,用于创建跨平台窗口并显示像素缓冲区

5个版本

0.0.6 2023年5月8日
0.0.5 2023年5月7日

#90 in 渲染

Download history 2/week @ 2024-03-11 24/week @ 2024-04-01

每月55次下载

MIT许可证

82KB
1.5K SLoC

minigw

minigw crate minimum rustc 1.0 minigw documentation

一个方便的Rust库,用于创建跨平台窗口并显示像素缓冲区。它还使得获取键盘和鼠标输入变得容易。内置了完整的imgui渲染支持。

Example

用法

将此添加到您的 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-MIThttps://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 最好,但其他支持的类型还有:i8u16i16u32i32f32。下面是一个使用 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