vason

Crates.iovason
lib.rsvason
version0.0.3
sourcesrc
created_at2022-12-30 16:07:10.793742
updated_at2023-01-06 00:10:35.261285
descriptionBasic 2D rasterizer written in rust that renders to a buffer.
homepagehttps://github.com/vismate/vason/
repositoryhttps://github.com/vismate/vason/
max_upload_size
id747930
size95,300
vismate (vismate)

documentation

README

vason - simple 2D rasterizer

WARNING: This crate is in very early stages. Anything can change anytime. Use at your own risk.

This crate enables you to render simple 2D shapes to a buffer of pixels. After creating a Canvas from a buffer, you have access to methods to fill in, or draw the outline of shapes.

This crate has no runtime dependencies.

A ppm module is included that lets you save your buffer as an image (that can be displayed by some major image viewers).

The crate also works well together with libraries such as minifb, thus you can even use it for small games / demos / visualizations.

Current and planned features:

  • basic shape rendering:

    • fill_rect, outline_rect, thick_outline_rect
    • fill_circle, outline_circle,
    • fill_ellipse, outline_ellipse,
    • line, hline, vline, thick_hline, thick_vline
  • Save buffer to a primitive image format (ppm)

  • more shapes:

    • fill_triangle, outline_triangle, thick_outline_triangle
    • thick_outline_circle
    • thick_outline_ellipse
    • thick_line
    • bezier_curve
  • flood fill

  • copy regions over from other buffer (sprites)

  • Pen-API: "Turtle Geometry"

  • Descriptor-API: A higher level helper API that can make your code more readable (but a tad less efficient).

  • alpha compositing (transparency)

  • built-in monospaced font rendering

  • further optimizations...

  • and more...

Example

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");
}

You may use the Pen-API to easily draw to the buffer images such as this:

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");
}

This piece of code produces the following image: rendered image

Commit count: 82

cargo fmt