Retrofire: 90s-inspired software rendering library with strong typing (no_std, no_deps, no_llm)

133 points Sharlinator 21 comments

Hi all,

Given that there's been a lot of discussion about AI projects for a change, I though this is a good point to finally write a post about my very much hand-written 3D renderer retrofire, which I also used as a case study in my recently-accepted M.Sc. thesis titled "Type-safe(r) Model of Geometry in 3D Graphics".

retrofire is no_std and has zero non-optional external dependencies. It also contains zero unsafe and, as mentioned, zero lines of LLM-generated or designed code. Last but not least, there are zero emojis :P

Please see the README for screenshots, can't post pictures in r/rust.

Umbrella package: https://crates.io/crates/retrofire

Git repo: https://github.com/jdahlstrom/retrofire

My thesis: https://www.utupub.fi/items/645d25b4-de42-4959-bd50-f96fb98b202a

A tiny example:


    let verts = [
        vertex(pt3(1.0, 1.0, 0.0), rgb(1.0, 0.2, 0.0)),
        vertex(pt3(-1.0, 1.0, 0.0), rgb(0.0, 0.8, 0.2)),
        vertex(pt3(0.0, -1.0, 0.0), rgb(0.4, 0.4, 1.0)),
    ];

    let shader = shader::new(
        // Vertex shader
        // Transform vertex position from model to clip space
        |v: Vertex3<Color3f>, mvp: &ProjMat3<Model>| {
            vertex(mvp.apply(&v.pos), v.attrib)
        },
        // Fragment shader
        // Just turn the float color to u8 RGBA format
        |frag: Frag<Color3f<_>>, _| {frag.var.to_color4(),
    );

    let dims = dims::VGA_640_480;

    // Render into a 2D buffer
    let mut framebuf = Buf2::<Color4>::new(dims);

    // Move the camera away a bit
    let modelview = translate((0.0, 0.0, 2.0)).to();
    // Use perspective projection
    let project = perspective(1.0, dims.aspect(), 0.1..1000.0);
    // Use the whole buffer as the viewport
    let viewport = viewport(dims.into());

    render(
        // Render a triangle with the given vertex indices
        [tri(0, 1, 2)],
        verts,
        &shader,
        &modelview.then(&project),
        viewport,
        &mut framebuf,
        &Context::default(),
    );