code wiki / _hdl_build / nx_textured_tri_gate.nx

nx_textured_tri_gate.nx source

↩ module page · 103 lines · 4955 B

1// nx_textured_tri_gate.nx -- proves real TEXTURE MAPPING: a checkerboard texture rasterized ONTO a triangle 2// (barycentric UV interpolation + per-fragment bilinear sample). Neg-control: a FLAT texture yields uniform fill 3// (proves the pattern comes from the texture, sampled per-fragment, not a constant). Emits a viewable PPM. 4// license_tier: ORIGINAL expect_exit: 0 5import "nx_syscalls.nx" 6import "nx_textured_tri.nx" 7 8func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 9func pn(v: i64) -> i64 { let b: *u8=sys_mmap(32) as *u8; var x: i64=v; var ng: i64=0; if x<0{ng=1;x=0-x} var i: i64=31; if x==0{b[i]=48 as u8;i=i-1} while x>0{b[i]=(48+x%10) as u8;x=x/10;i=i-1} if ng==1{b[i]=45 as u8;i=i-1} sys_write(1,(b as i64+i+1) as *u8,31-i); return 0 } 10 11func main() -> i64 { 12 hw("=== nx_textured_tri_gate -- real texture mapping (checkerboard ONTO a triangle) ===\n" as *u8) 13 var fails: i64 = 0 14 15 // 8x8 checkerboard texture (1-channel): (x+y) even -> 220 bright, odd -> 30 dark 16 let tex: *Image = nx_image_alloc(8, 8, 1) 17 let tp: *u8 = tex.pixels 18 var yy: i64 = 0 19 while yy < 8 { 20 var xx: i64 = 0 21 while xx < 8 { 22 var val: i64 = 30 23 if (xx + yy) % 2 == 0 { val = 220 } 24 tp[yy*8 + xx] = val as u8 25 xx = xx + 1 26 } 27 yy = yy + 1 28 } 29 30 // 48x48 RGB framebuffer cleared to background blue (10,10,40) 31 let fb: *Image = nx_image_alloc(48, 48, 3) 32 let fp: *u8 = fb.pixels 33 var i: i64 = 0 34 while i < 48*48 { fp[i*3] = 10 as u8; fp[i*3+1] = 10 as u8; fp[i*3+2] = 40 as u8; i = i + 1 } 35 36 // render the textured triangle: (4,4)uv(0,0) (43,4)uv(1,0) (4,43)uv(0,1) [Q10: 1.0 = 1023] 37 txtri_render(fb, tex, 4, 4, 0, 0, 43, 4, 1023, 0, 4, 43, 0, 1023) 38 39 // classify: a textured pixel is grayscale (r==b); background is (10,10,40) so r!=b 40 var bright: i64 = 0; var dark: i64 = 0; var bg: i64 = 0 41 i = 0 42 while i < 48*48 { 43 let r: i64 = fp[i*3] as i64 44 let b: i64 = fp[i*3+2] as i64 45 if r == b { 46 if r >= 150 { bright = bright + 1 } 47 if r <= 90 { dark = dark + 1 } 48 } else { bg = bg + 1 } 49 i = i + 1 50 } 51 hw(" checkerboard: bright="); pn(bright); hw(" dark="); pn(dark); hw(" bg="); pn(bg); hw("\n" as *u8) 52 53 var t1: i64 = 0 54 if bright > 0 { t1 = 1 } 55 if t1 == 1 { hw("T1 PASS bright texels rendered onto the surface\n" as *u8) } else { fails=fails+1; hw("T1 FAIL no bright texels\n" as *u8) } 56 var t2: i64 = 0 57 if dark > 0 { t2 = 1 } 58 if t2 == 1 { hw("T2 PASS dark texels rendered -> the texture VARIES across the surface (checkerboard applied)\n" as *u8) } else { fails=fails+1; hw("T2 FAIL no dark texels\n" as *u8) } 59 var t3: i64 = 0 60 if bg > 0 { t3 = 1 } 61 if t3 == 1 { hw("T3 PASS background survives outside the triangle (real coverage, not full-frame fill)\n" as *u8) } else { fails=fails+1; hw("T3 FAIL triangle covered everything\n" as *u8) } 62 63 // T4 NEG CONTROL: FLAT texture (all 128) -> uniform fill, NO bright/dark split (pattern comes from the texture) 64 let flat: *Image = nx_image_alloc(8, 8, 1) 65 let flp: *u8 = flat.pixels 66 i = 0 67 while i < 64 { flp[i] = 128 as u8; i = i + 1 } 68 let fb2: *Image = nx_image_alloc(48, 48, 3) 69 let fp2: *u8 = fb2.pixels 70 i = 0 71 while i < 48*48 { fp2[i*3] = 10 as u8; fp2[i*3+1] = 10 as u8; fp2[i*3+2] = 40 as u8; i = i + 1 } 72 txtri_render(fb2, flat, 4, 4, 0, 0, 43, 4, 1023, 0, 4, 43, 0, 1023) 73 var fbright: i64 = 0; var fdark: i64 = 0 74 i = 0 75 while i < 48*48 { 76 let r: i64 = fp2[i*3] as i64 77 let b: i64 = fp2[i*3+2] as i64 78 if r == b { 79 if r >= 150 { fbright = fbright + 1 } 80 if r <= 90 { fdark = fdark + 1 } 81 } 82 i = i + 1 83 } 84 hw(" flat-texture neg-control: bright="); pn(fbright); hw(" dark="); pn(fdark); hw(" (expect 0/0)\n" as *u8) 85 var t4: i64 = 0 86 if fbright == 0 { if fdark == 0 { t4 = 1 } } 87 if t4 == 1 { hw("T4 PASS neg-control: a FLAT texture yields uniform fill -> the pattern is SAMPLED from the texture per-fragment\n" as *u8) } else { fails=fails+1; hw("T4 FAIL flat texture produced variation\n" as *u8) } 88 89 // T5 ARTIFACT: write the checkerboard render as a viewable binary PPM (P6) 90 let hdr: *u8 = "P6\n48 48\n255\n" as *u8 91 var hn: i64 = 0 92 while hdr[hn] != (0 as u8) { hn = hn + 1 } 93 let fd: i64 = sys_openat_wr("knowledge/nx_textured_tri.ppm\x00" as *u8, 0x1a4) 94 sys_write(fd, hdr, hn) 95 sys_write(fd, fp, 48*48*3) 96 sys_close(fd) 97 hw("T5 artifact -> knowledge/nx_textured_tri.ppm ("); pn(hn + 48*48*3); hw(" bytes, viewable P6)\n" as *u8) 98 99 if fails == 0 { hw("NX-TEXTURED-TRI GREEN -- real texture mapping: image sampled onto a rasterized triangle, neg-control bites\n" as *u8); sys_exit(0); return 0 } 100 hw("NX-TEXTURED-TRI RED fails="); pn(fails); hw("\n" as *u8) 101 sys_exit(1) 102 return 1 103}