nx_render_pass.nx
buildroot/runtime/nx_render_pass.nx
about
nx_render_pass.nx -- L4 mesh-render composer (vertex + zbuf + texture).
Closes the GRAPHICS COMPOSITION gap. Today's substrate had:
L1 containers : nx_image.Image + nx_image.ImageS64
L2 transforms : nx_raster (Bresenham + Pineda) +
nx_zbuf (depth-tested triangle) +
nx_tex_sample (UV bilinear + nearest) +
nx_vertex_pipeline (world -> screen)
L3 algorithms : the building blocks above
L4 composer : MISSING
This brick is the L4 composer. Caller passes a mesh (indices +
vertices), a texture, an MVP matrix, and a framebuffer + depth
buffer. We:
1. Run vertex_pipeline_transform to project world vertices to
screen space.
2. For each triangle (i, j, k) in indices: pull the three
transformed vertices, sample texture at their UVs, call
nx_zbuf_triangle with the depth-tested color write.
Pure i64 substrate. No FPU, no GPU, no driver. Runs on every
backend including Cortex-M3 with a framebuffer.
===== Mesh format ===============================================
verts: 4 i64 per vertex: (x_q14, y_q14, z_q14, packed_color)
uvs: 2 i64 per vertex: (u_q10, v_q10) -- texture coords
indices: 3 nx_int per triangle: (i0, i1, i2) -- mesh-flat layout
All Q-format choices match nx_vertex_pipeline + nx_tex_sample
conventions so the buffers compose directly.
===== Vertex coloring (v1) ======================================
v1 samples the texture at each VERTEX'S UV and lets nx_zbuf_triangle
barycentric-interpolate the per-vertex sampled colors across
pixels. This is the "Gouraud shading" approach -- fast, correct
for diffuse Lambertian surfaces, but lacks per-pixel texture
dependencies 7 imports · 0 importers
imports: nx_syscalls.nxnx_tier.nxnx_loop.nxnx_image.nxnx_zbuf.nxnx_tex_sample.nxnx_vertex_pipeline.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
| 68 | const NX_RP_VTX_STRIDE: nx_int = 4 // 4 i64 per transformed vertex |
| 69 | const NX_RP_UV_STRIDE: nx_int = 2 // 2 i64 per UV pair |
| 73 | const NX_RP_OK: nx_int = 0 |
| 74 | const NX_RP_ERR_BAD_DIMS: nx_int = 1 |
| 75 | const NX_RP_ERR_BAD_INDEX: nx_int = 2 |
| 76 | const NX_RP_N_VERDICTS: nx_int = 3 |
functions
| 78 | func nx_rp_verdict_is_valid(v: nx_int) -> nx_int called by 1: main |
| 98 | func nx_render_pass(verts: *i64, uvs: *i64, indices: *i64, n_verts: nx_int, |
| 181 | func nx_render_pass_clear_and_draw( |
| 225 | func main() -> i64 |