code wiki / (root) / nx_textured_tri.nx

nx_textured_tri.nx source

↩ module page · 62 lines · 2543 B

1// nx_textured_tri.nx -- TEXTURED TRIANGLE rasterizer: barycentric edge-function fill + per-fragment UV 2// interpolation + nx_tex_sample (bilinear). This closes the "texture mapping" residual = an image mapped ONTO 3// a rasterized surface (real texture MAPPING, not just a standalone sampler). Pure integer, deterministic. 4// license_tier: ORIGINAL 5import "nx_syscalls.nx" 6import "nx_tex_sample.nx" 7 8// edge function (b-a) x (p-a): >0 when p is left of edge a->b (CCW) 9func tt_edge(ax: i64, ay: i64, bx: i64, by: i64, px: i64, py: i64) -> i64 { 10 return (bx - ax) * (py - ay) - (by - ay) * (px - ax) 11} 12 13// Rasterize a textured triangle into fb (RGB Image). UVs in Q10. A grayscale texel -> gray RGB pixel. 14func txtri_render(fb: *Image, tex: *Image, x0: i64, y0: i64, u0: i64, v0: i64, x1: i64, y1: i64, u1: i64, v1: i64, x2: i64, y2: i64, u2: i64, v2: i64) -> i64 { 15 var area: i64 = tt_edge(x0, y0, x1, y1, x2, y2) 16 if area == 0 { return 0 } 17 var sgn: i64 = 1 18 if area < 0 { sgn = 0 - 1; area = 0 - area } 19 // bounding box, clamped to the framebuffer 20 var minx: i64 = x0 21 if x1 < minx { minx = x1 } 22 if x2 < minx { minx = x2 } 23 var maxx: i64 = x0 24 if x1 > maxx { maxx = x1 } 25 if x2 > maxx { maxx = x2 } 26 var miny: i64 = y0 27 if y1 < miny { miny = y1 } 28 if y2 < miny { miny = y2 } 29 var maxy: i64 = y0 30 if y1 > maxy { maxy = y1 } 31 if y2 > maxy { maxy = y2 } 32 if minx < 0 { minx = 0 } 33 if miny < 0 { miny = 0 } 34 if maxx >= fb.width { maxx = fb.width - 1 } 35 if maxy >= fb.height { maxy = fb.height - 1 } 36 let px: *u8 = fb.pixels 37 var py: i64 = miny 38 while py <= maxy { 39 var pxi: i64 = minx 40 while pxi <= maxx { 41 let w0: i64 = tt_edge(x1, y1, x2, y2, pxi, py) * sgn 42 let w1: i64 = tt_edge(x2, y2, x0, y0, pxi, py) * sgn 43 let w2: i64 = tt_edge(x0, y0, x1, y1, pxi, py) * sgn 44 if w0 >= 0 { 45 if w1 >= 0 { 46 if w2 >= 0 { 47 let u: i64 = (w0 * u0 + w1 * u1 + w2 * u2) / area 48 let v: i64 = (w0 * v0 + w1 * v1 + w2 * v2) / area 49 let g: i64 = nx_txs_sample_bilinear(tex, u, v, NX_TXS_WRAP_CLAMP) 50 let off: i64 = py * fb.stride + pxi * 3 51 px[off] = g as u8 52 px[off + 1] = g as u8 53 px[off + 2] = g as u8 54 } 55 } 56 } 57 pxi = pxi + 1 58 } 59 py = py + 1 60 } 61 return 0 62}