builtin-programs/draw/apriltags.folk

Wish the GPU compiles pipeline "apriltag" {
    {vec2 viewport mat3 surfaceToClip vec4 background
     uvec4 tagBitsVec vec2 a vec2 b vec2 c vec2 d} {
        vec2 vertices[6] = vec2[6](a, b, c, a, c, d);
        vec3 v = surfaceToClip * vec3(vertices[gl_VertexIndex], 1.0);
        return vec4(v.xy/v.z, 0.0, 1.0);

    } {fn invBilinear} {
        vec2 clipXy = (gl_FragCoord.xy / viewport) * 2.0 - 1.0;
        vec3 surfaceXy = inverse(surfaceToClip) * vec3(clipXy, 1.0);
        surfaceXy /= surfaceXy.z;

        vec2 uv = invBilinear(surfaceXy.xy, a, b, c, d);

        int x = int(uv.x * 10); int y = int(uv.y * 10);
        int bitIdx = y * 10 + x;
        uint bit = (tagBitsVec[bitIdx / 32] >> (bitIdx % 32)) & 0x1;
        return bit == 1 ? background : vec4(0, 0, 0, 1);
    }
}

When the image library is /imageLib/ & the print library is /printLib/ &\
     /p/ has canvas /writableTexture/ with /...wiOptions/ &\
     /p/ has canvas projection /surfaceToClip/ &\
     /someone/ wishes to draw an AprilTag onto /p/ with /...options/ {

    set id [dict get $options id]
    set corners [dict get $options corners]
    set layer [dict getdef $options layer 0]
    set background [dict getdef $options background [list 1 1 1 1]]

    set tagImage [$printLib tagImageForId $id]
    set tagBits [list]
    # 10x10 AprilTag -> 100 bits
    for {set y 0} {$y < 10} {incr y} {
        for {set x 0} {$x < 10} {incr x} {
            set j [expr {$y * [$imageLib Image_bytesPerRow $tagImage] + $x}]
            set bit $([$imageLib Image_data $tagImage $j] == 255)
            lappend tagBits $bit
        }
    }
    # -> 4 32-bit integers
    set tagBitsVec [list 0b[join [lreverse [lrange $tagBits 0 31]] ""] \
                        0b[join [lreverse [lrange $tagBits 32 63]] ""] \
                        0b[join [lreverse [lrange $tagBits 64 95]] ""] \
                        0b[join [lreverse [lrange $tagBits 96 127]] ""]]

    set wiResolution [list [dict get $wiOptions width] [dict get $wiOptions height]]
    Wish the GPU draws pipeline "apriltag" onto canvas $writableTexture with \
        arguments [list $wiResolution $surfaceToClip $background \
                       $tagBitsVec {*}$corners] \
        layer $layer
}