nx_raster_legacy.nx
buildroot/runtime/nx_raster_legacy.nx
about
nx_raster.nx -- software 2D rasterizer (lines + triangles).
Closes the GRAPHICS-PATH gap named in docs/VULKAN_COMPARISON.md.
Vulkan / OpenGL / DirectX / Metal all do graphics; we had zero
rasterizer until this brick. Pure i64 substrate -- no FPU, no GPU
dependency -- runs on every backend including Cortex-M3 with a
framebuffer.
L2 canonical primitive composing:
nx_image.Image (L1 canonical pixel container)
nx_loop.LoopVerdict (bounded loops)
===== Algorithms ================================================
Lines: Bresenham 1965 (the canonical integer-only rasterizer).
Pure integer ops; no division beyond /2 and bit shifts.
O(max(dx, dy)) pixels visited.
Triangles: edge-function method (Pineda 1988 "A Parallel
Algorithm for Polygon Rasterization"). For each
triangle vertex pair, compute the 2D cross product
(the "edge function") at each pixel; pixel is inside
the triangle iff all three edge functions have the
same sign. Bounding-box prune to avoid testing the
whole framebuffer.
Barycentric: the three edge functions ARE the barycentric
coordinates (after normalization by triangle area).
Free interpolation of per-vertex attributes.
===== Why pure i64 ==============================================
Substrate has no FPU yet (compiler I2 parked). All rasterization
can be done in i64 with edge functions and barycentric weights
scaled to Q10. Subpixel accuracy via fixed-point coordinate input
(caller passes coords in Q4 or Q8 if needed; this v1 accepts i64
pixel-aligned coordinates).
Subpixel coords + perspective-correct attribute interpolation
queued for v2.
dependencies 4 imports · 0 importers
imports: nx_syscalls.nxnx_tier.nxnx_loop.nxnx_image.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 75 | const NX_RAST_OK: nx_int = 0 |
| 76 | const NX_RAST_ERR_BAD_IMAGE: nx_int = 1 |
| 77 | const NX_RAST_ERR_DEGENERATE: nx_int = 2 |
| 78 | const NX_RAST_N_VERDICTS: nx_int = 3 |
functions
| 80 | func nx_rast_verdict_is_valid(v: nx_int) -> nx_int called by 1: main |
| 92 | func _rast_abs(x: nx_int) -> nx_int called by 1: nx_rast_line |
| 97 | func nx_rast_line(img: *Image, x0: nx_int, y0: nx_int, |
| 141 | func _rast_edge(ax: nx_int, ay: nx_int, |
| 157 | func nx_rast_triangle(img: *Image, |
| 238 | func nx_rast_barycentric_attr(x0: nx_int, y0: nx_int, attr_a: i64, |
| 257 | func nx_rast_triangle_shaded(img: *Image, |
| 334 | func main() -> i64 |