code wiki / _hdl_build / nx_shade_gate.nx

nx_shade_gate.nx source

↩ module page · 78 lines · 4015 B

1// nx_shade_gate.nx -- proves P1 texture/gouraud. Renders a 96x48 image: LEFT = gouraud triangle with 2// red/green/blue vertices (smooth RGB gradient); RIGHT = a triangle textured with an 8x8 yellow/purple 3// checkerboard. Asserts: each gouraud vertex region is the right hue, the interior is a true blend, and 4// the textured region contains BOTH checker colors. Writes knowledge/nx_shade.png for eyeball verify. 5// license_tier: ORIGINAL expect_exit: 0 6import "nx_syscalls.nx" 7import "nx_shade.nx" 8import "nx_png.nx" 9 10func vw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 11func vn(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(1,bb,k); return 0 } 12func px(fb: *i64, w: i64, x: i64, y: i64) -> i64 { return fb[y*w + x] } 13 14func main() -> i64 { 15 let w: i64 = 96 16 let h: i64 = 48 17 let fb: *i64 = sys_mmap(8 * 96 * 48) as *i64 18 sh_clear(fb, w, h, sh_rgb(20, 20, 30)) // dark slate background 19 20 let RED: i64 = sh_rgb(255,0,0) 21 let GRN: i64 = sh_rgb(0,255,0) 22 let BLU: i64 = sh_rgb(0,0,255) 23 // LEFT: gouraud triangle A(6,6)=red B(44,6)=green C(24,42)=blue 24 sh_tri_gouraud(fb, w, h, 6,6,RED, 44,6,GRN, 24,42,BLU) 25 26 // 8x8 checkerboard texture: yellow / purple 27 let YEL: i64 = sh_rgb(230,210,40) 28 let PUR: i64 = sh_rgb(120,40,160) 29 let tex: *i64 = sys_mmap(8 * 64) as *i64 30 var ti: i64 = 0 31 while ti < 64 { 32 let u: i64 = ti % 8 33 let v: i64 = ti / 8 34 if ((u + v) & 1) == 0 { tex[ti] = YEL } else { tex[ti] = PUR } 35 ti = ti + 1 36 } 37 // RIGHT: textured triangle (52,6)uv(0,0) (92,6)uv(7,0) (72,42)uv(3,7) 38 sh_tri_textured(fb, w, h, tex, 8, 52,6,0,0, 92,6,7,0, 72,42,3,7) 39 40 write_png(fb, w, h, "knowledge/nx_shade.png" as *u8) 41 42 var pass: i64 = 0 43 var total: i64 = 0 44 45 // gouraud hue checks (sample points proven inside the triangle) 46 let pa: i64 = px(fb,w, 9,9) // near red vertex 47 total=total+1; if sh_r(pa) > sh_g(pa) { if sh_r(pa) > sh_b(pa) { pass=pass+1 } else { vw("S1 FAIL not red\n") } } else { vw("S1 FAIL not red\n") } 48 let pb: i64 = px(fb,w, 40,9) // near green vertex 49 total=total+1; if sh_g(pb) > sh_r(pb) { if sh_g(pb) > sh_b(pb) { pass=pass+1 } else { vw("S2 FAIL not green\n") } } else { vw("S2 FAIL not green\n") } 50 let pc: i64 = px(fb,w, 24,38) // near blue vertex 51 total=total+1; if sh_b(pc) > sh_r(pc) { if sh_b(pc) > sh_g(pc) { pass=pass+1 } else { vw("S3 FAIL not blue\n") } } else { vw("S3 FAIL not blue\n") } 52 let pm: i64 = px(fb,w, 24,18) // interior = blend 53 total=total+1; if sh_r(pm)>0 { if sh_g(pm)>0 { if sh_b(pm)>0 { pass=pass+1 } else { vw("S4 FAIL no blend\n") } } else { vw("S4 FAIL no blend\n") } } else { vw("S4 FAIL no blend\n") } 54 55 // texture: both checker colors present in the right half 56 var nyel: i64 = 0 57 var npur: i64 = 0 58 var y: i64 = 0 59 while y < h { 60 var x: i64 = 50 61 while x < w { 62 let c: i64 = px(fb,w,x,y) 63 if c == YEL { nyel = nyel + 1 } 64 if c == PUR { npur = npur + 1 } 65 x = x + 1 66 } 67 y = y + 1 68 } 69 total=total+1; if nyel > 0 { if npur > 0 { pass=pass+1 } else { vw("S5 FAIL purple absent\n") } } else { vw("S5 FAIL yellow absent\n") } 70 71 vw("=== SHADE render -> knowledge/nx_shade.png (96x48) ===\n") 72 vw(" gouraud A(9,9)=("); vn(sh_r(pa)); vw(","); vn(sh_g(pa)); vw(","); vn(sh_b(pa)); vw(") blend(24,18)=("); vn(sh_r(pm)); vw(","); vn(sh_g(pm)); vw(","); vn(sh_b(pm)); vw(")\n") 73 vw(" texture checker: yellow_px="); vn(nyel); vw(" purple_px="); vn(npur); vw("\n") 74 vw("SHADE "); vn(pass); vw("/"); vn(total); vw("\n") 75 if pass == total { vw("SHADE ALL-PASS (RGB gouraud gradient + textured checkerboard; PNG written)\n"); sys_exit(0) } 76 sys_exit(1) 77 return 1 78}