#opengl #framebuffer #windowing #window-creation #high-speed #window

mini_gl_fb

快速简单的窗口创建、输入和高速度位图渲染

10 个版本 (breaking)

0.9.0 2021年7月17日
0.8.0 2021年2月22日
0.7.0 2019年4月22日
0.6.0 2018年8月25日
0.2.4 2018年7月27日

#85 in 渲染


用于 youxi

MIT 许可证

465KB
800

Mini GL "Framebuffer" (MGlFb)

Version Docs.rs

Mini GL Framebuffer 提供了一种从像素缓冲区向窗口绘制图形的简单方法。是其他易于使用的帧缓冲区库(如 minifbpixels)的 OpenGL 替代品。

它设计得非常简单易记,当您只想尽快将内容显示在屏幕上时。它还构建得非常灵活,易于扩展,以防您的项目变得复杂。MGlFb 暴露了其所有内部结构,您可以逐步移除它作为依赖项。

您还可以使用 MiniGlFb::glutin_breakout 来进行一些有趣的事情,例如多窗口,同时保留有用的 Framebuffer 辅助工具。有一个名为 multi_window 的示例展示了这一功能。

MGlFb 应该能在您扔给它的任何平台上运行,归功于 winitglutin 的跨平台兼容性。然而,您确实需要支持 OpenGL 的正确 GPU 驱动程序。这意味着 MGlFb 不会在某些虚拟机或没有 GPU 的服务器上工作。遗憾的是,这并不是什么可以帮助的事情,因为 MGlFb 没有OpenGL 就不能工作。

截图

以下是一些在不同平台上运行的 multi_window 示例的截图

Windows Arch Linux (X11) macOS

这是 MGlFb 可支持的高级功能的展示,但它并不代表启动所需的工作量有多么小。

用法

extern crate mini_gl_fb;

fn main() {
    let (mut event_loop, mut fb) = mini_gl_fb::gotta_go_fast("Hello world!", 800.0, 600.0);
    let buffer = vec![[128u8, 0, 0, 255]; 800 * 600];
    fb.update_buffer(&buffer);
    fb.persist(&mut event_loop);
}

fb.update_buffer 可以被多次调用,每次调用都会重新绘制屏幕。您可以自行选择计时机制,无论是简单的 sleep(ms) 还是更复杂的方法。

支持快速简单、简单的输入处理

无需麻烦即可访问鼠标位置和键输入。以下是从生命游戏示例中提取的内容

use mini_gl_fb::glutin::event_loop::EventLoop;
use mini_gl_fb::Config;

let (mut event_loop, mut fb) = mini_gl_fb::gotta_go_fast("Hello, World!", 800., 600.);
let buffer = vec![[128u8, 0, 0, 255]; 800 * 600];

// ...

fb.glutin_handle_basic_input(&mut event_loop, |fb, input| {
    let elapsed = previous.elapsed().unwrap();
    let seconds = elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 * 1e-9;

    if input.key_is_down(VirtualKeyCode::Escape) {
        return false;
    }

    if input.mouse_is_down(MouseButton::Left) {
        // Mouse was pressed
        let (x, y) = input.mouse_pos;
        cells[y * WIDTH + x] = true;
        fb.update_buffer(&cells);
        // Give the user extra time to make something pretty each time they click
        previous = SystemTime::now();
        extra_delay = (extra_delay + 0.5).min(2.0);
    }

    // Each generation should stay on screen for half a second
    if seconds > 0.5 + extra_delay {
        previous = SystemTime::now();
        calculate_neighbors(&mut cells, &mut neighbors);
        make_some_babies(&mut cells, &mut neighbors);
        fb.update_buffer(&cells);
        extra_delay = 0.0;
    } else if input.resized {
        fb.redraw();
    }

    true
});

着色器游乐场

基于ShaderToy的GLSL着色器后处理。这是一个正在进行中的作品,但已支持简单的效果。以下为默认行为,同时展示了API。

fb.use_post_process_shader("
void main_image( out vec4 r_frag_color, in vec2 v_uv ) {
    r_frag_color = texture(u_buffer, v_uv);
}
");

获取对glutin/winit的完全访问权限以自定义事件处理。

您还可以“突破”并获取底层glutin窗口的访问权限,同时仍然能够轻松设置。

let (_, fb) = mini_gl_fb::gotta_go_fast("Hello world!", 800.0, 600.0);

let GlutinBreakout {
    context,
    mut fb,
} = fb.glutin_breakout();

fb.update_buffer(/*...*/);

multi_window 示例通过手动运行winit事件循环并一次处理多个 GlutinBreakout 的事件来工作。您也可以这样做!

其他功能

  • 黑白渲染,每像素指定一个字节。
  • 硬件加速的缓冲区缩放(窗口和缓冲区可以有不同的尺寸)。
  • 提供了一行代码创建glutin上下文的功能。
  • 提供了一行代码创建VAO、VBO、四边形和空白纹理的功能。
  • 如果您不想使用glutin,您也可以提供自己的上下文!

有关更多信息,请参阅文档

计划中的功能(取决于需求)

如果您有任何建议或希望尽快看到这些功能,请随时提交问题!

  • 更多种类的简化输入处理方法

  • 增强的更全面的着色器游乐场

  • 支持直接运行ShaderToy示例(转换函数)

  • 支持更多纹理,可能为复杂的后处理序列提供实际的OpenGL帧缓冲区

  • 一个类似于HTML canvas的API,允许在您的缓冲区上绘制?

依赖项

~4.5–6MB
~124K SLoC