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}