#图形 #framebuffer #绘图 #渲染 #2D 图形 #像素 #光栅化

vason

用 Rust 编写的简单 2D 光栅化器,将渲染到缓冲区

2 个版本

0.0.3 2023 年 1 月 6 日
0.0.2 2022 年 12 月 30 日
0.0.1 2022 年 12 月 30 日

#250 in 图形 API

MIT/Apache

59KB
1K SLoC

vason - 简单 2D 光栅化器

警告:此 crate 处于非常早期的阶段。任何内容都可能随时更改。自行承担风险。

此 crate 允许您将简单的 2D 形状渲染到像素缓冲区。创建缓冲区的 Canvas 后,您可以访问填充或绘制形状轮廓的方法。

此 crate 没有运行时依赖。

包含一个 ppm 模块,允许您将缓冲区保存为图像(某些主要图像查看器可以显示)。

该 crate 还与库(如 minifb)很好地协同工作,因此您甚至可以使用它进行小型游戏/演示/可视化。

当前和计划中的功能

  • 基本形状渲染
    • fill_rect、outline_rect、thick_outline_rect
    • fill_circle、outline_circle、
    • fill_ellipse、outline_ellipse、
    • line、hline、vline、thick_hline、thick_vline
  • 将缓冲区保存为原始图像格式(ppm)
  • 更多形状
    • fill_triangle、outline_triangle、thick_outline_triangle
    • thick_outline_circle
    • thick_outline_ellipse
    • thick_line
    • bezier_curve
  • 洪水填充
  • 从其他缓冲区复制区域(精灵)
  • Pen-API: "海龟几何学"
  • Descriptor-API:一个更高级的辅助 API,可以使您的代码更易读(但效率略低)。
  • alpha 合成(透明度)
  • 内置单倍间距字体渲染
  • 进一步的优化...
  • 等等...

示例

use std::fs::File;
use vason::{ppm::encode_canvas, Canvas, Color};

fn main() {
    let mut buffer = vec![0u32; 256*256];
    let mut canvas = Canvas::new(&mut buffer, 256, 256);
    canvas.clear((180, 255, 100));
    canvas.fill_rect(80, 40, 128, 192, Color::GREEN);
    canvas.fill_circle(-40, -40, 128, Color::BLUE);
    canvas.outline_circle(-40, -40, 178, Color::RED);
    canvas.line(256, 0, 0, 256, Color::MAGENTA);

    let mut f = File::create("test.ppm").expect("could not create file");
    encode_canvas(&canvas, &mut f).expect("could not write image to file");
}

您可以使用 Pen-API 简单地将图像绘制到缓冲区中,如下所示

use std::fs::File;
use vason::{ppm::encode_canvas, Canvas, Color, Pen};

fn tree(pen: &mut Pen, size: f32, depth: i32) {
    let state = pen.get_state();
    let green = ((20 - depth) * 15).clamp(0, u8::MAX as i32) as u8;
    pen.set_color((0, green, 0));

    if depth <= 0 || size < 5.0 {
        pen.forward(size).backward(size);
        return;
    }
    pen.forward(size / 3.0).turn_left(30.0);
    tree(pen, (size * 2.0) / 3.0, depth - 1);
    pen.turn_right(30.0).forward(size / 6.0).turn_right(25.0);
    tree(pen, size / 2.0, depth - 1);
    pen.turn_left(25.0).forward(size / 3.0).turn_right(25.0);
    tree(pen, size / 2.0, depth - 1);
    pen.turn_left(25.0).forward(size / 6.0).set_state(state);
}

fn sun(pen: &mut Pen, scale: f32) {
    pen.repeat(18, |pen| {
        pen.forward(0.5 * scale)
            .turn_right(150.0)
            .forward(0.6 * scale)
            .turn_right(100.0)
            .forward(0.3 * scale)
            .turn_right(90.0);
    });
}

fn main() {
    let mut buffer = vec![0u32; 1024 * 1024];
    let mut canvas = Canvas::new(&mut buffer, 1024, 1024);
    canvas.clear((15, 15, 35));
    let mut pen = canvas.pen();

    pen.set_position(512.0, 1024.0).set_direction(-90.0);
    tree(&mut pen, 650.0, 15);

    pen.set_color(Color::YELLOW).set_position(80.0, 120.0);
    sun(&mut pen, 175.0);

    let mut f = File::create("pen.ppm").expect("couldn't create file");
    encode_canvas(&canvas, &mut f).expect("couldn't write image to file");
}

此段代码生成了以下图像: 渲染图像

无运行时依赖