code wiki / _hdl_build / nx_gfx_tex_gate.nx

nx_gfx_tex_gate.nx source

↩ module page · 96 lines · 4654 B

1import "nx_gate_gn.nx" 2import "nx_gate_base.nx" 3// nx_gfx_tex_gate.nx -- one rung UP the visual climb: PROCEDURAL SURFACE TEXTURING (flat blobs -> detailed stone). 4// Renders the SAME isometric floor two ways -- flat (gx_iso_tile) vs textured (gx_iso_tile_tex, integer-hash grain) -- 5// to two PNGs, and MEASURES the gain: "surface detail" = sum of horizontal luminance deltas over a floor strip 6// (flat gradient spans ~= 0 within a span; per-pixel grain >> 0). Honest scope: this is ONE classical rung (still 7// CPU raster, no GPU) -- it does NOT close the gap to Three.js; it makes our surfaces detailed instead of flat. 8// T1 DETAIL: textured surface detail >= 3x flat (measurable texture, not flat color). 9// T2 DETERMINISM: same textured scene twice -> identical (no float). 10// T3 RENDERED: both scenes are real content (not black). 11// expect_exit: 0 license_tier: ORIGINAL 12import "nx_gfx_iso.nx" 13import "nx_png.nx" 14import "nx_syscalls.nx" 15 16func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 17" as *u8); return ok } 18func lum(c: i64) -> i64 { return (c & 255) + ((c>>8)&255) + ((c>>16)&255) } 19 20func floor_flat(fb: *i64, W: i64, H: i64, ox: i64, oy: i64) -> i64 { 21 gx_fill(fb, W, H, gx_rgb(7, 7, 11)) 22 var ty: i64=0 23 while ty < 8 { var tx: i64=0 24 while tx < 8 { 25 let nz: i64 = ((tx*7 + ty*13) % 5 - 2)*7 26 let col: i64 = gx_rgb(92 + nz, 86 + nz, 76 + nz) 27 gx_iso_tile(fb, W, H, gx_isox(tx, ty, ox), gx_isoy(tx, ty, oy), col) 28 tx = tx + 1 29 } 30 ty = ty + 1 31 } 32 return 0 33} 34func floor_tex(fb: *i64, W: i64, H: i64, ox: i64, oy: i64) -> i64 { 35 gx_fill(fb, W, H, gx_rgb(7, 7, 11)) 36 var ty: i64=0 37 while ty < 8 { var tx: i64=0 38 while tx < 8 { 39 let nz: i64 = ((tx*7 + ty*13) % 5 - 2)*7 40 let col: i64 = gx_rgb(92 + nz, 86 + nz, 76 + nz) 41 gx_iso_tile_tex(fb, W, H, gx_isox(tx, ty, ox), gx_isoy(tx, ty, oy), col) 42 tx = tx + 1 43 } 44 ty = ty + 1 45 } 46 return 0 47} 48// surface detail = sum of |lum(x) - lum(x+1)| over a floor strip (grain -> high; flat span -> ~0) 49func detail(fb: *i64, W: i64, H: i64, y0: i64, y1: i64) -> i64 { 50 var d: i64=0; var y: i64=y0 51 while y < y1 { 52 var x: i64=40 53 while x < W-40 { let a: i64=lum(fb[y*W+x]); let b: i64=lum(fb[y*W+x+1]); var dd: i64=a-b; if dd<0{dd=0-dd} d=d+dd; x=x+1 } 54 y = y + 1 55 } 56 return d 57} 58func nonblack(fb: *i64, W: i64, H: i64, y0: i64, y1: i64) -> i64 { 59 var y: i64=y0 60 while y < y1 { var x: i64=40; while x < W-40 { if lum(fb[y*W+x]) > 60 { return 1 } x=x+1 } y=y+1 } 61 return 0 62} 63 64func main() -> i64 { 65 gw("=== nx_gfx_tex_gate: procedural surface texturing (flat -> detailed stone) -- one rung up the visual climb ===\n" as *u8) 66 let W: i64=320; let H: i64=240; let ox: i64=160; let oy: i64=34 67 let fbf: *i64 = sys_mmap(W*H*8) as *i64 68 let fbt: *i64 = sys_mmap(W*H*8) as *i64 69 floor_flat(fbf, W, H, ox, oy) 70 floor_tex(fbt, W, H, ox, oy) 71 write_png(fbf, W, H, "knowledge/nx_gfx_flat.png" as *u8) 72 write_png(fbt, W, H, "knowledge/nx_gfx_tex.png" as *u8) 73 gw(" (SEE: knowledge/nx_gfx_flat.png vs knowledge/nx_gfx_tex.png)\n" as *u8) 74 let df: i64 = detail(fbf, W, H, 60, 150) 75 let dt: i64 = detail(fbt, W, H, 60, 150) 76 var pass: i64=0; var total: i64=0 77 78 var t1: i64=0; if dt >= df*3 { t1=1 } 79 total=total+1; if t1==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 80 gw("T1 surface detail: textured=" as *u8); gn(dt); gw(" vs flat=" as *u8); gn(df); gw(" (>=3x = real grain, not flat color)\n" as *u8) 81 82 let fbt2: *i64 = sys_mmap(W*H*8) as *i64 83 floor_tex(fbt2, W, H, ox, oy) 84 var t2: i64=1; let sy: i64 = 80 85 var x: i64=60; while x < 260 { if fbt2[sy*W+x] != fbt[sy*W+x] { t2=0; x=260 } else { x=x+1 } } 86 total=total+1; if t2==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 87 gw("T2 determinism: textured scene re-renders bit-for-bit (integer hash, no float)\n" as *u8) 88 89 var t3: i64=0; if nonblack(fbt, W, H, 60, 150)==1 { if nonblack(fbf, W, H, 60, 150)==1 { t3=1 } } 90 total=total+1; if t3==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 91 gw("T3 rendered: both scenes are real content (not black)\n" as *u8) 92 93 gw("\n=== nx_gfx_tex_gate " as *u8); gn(pass); gw("/" as *u8); gn(total) 94 if pass == total { gw(" GREEN (procedural texturing adds measurable surface detail; deterministic; SEE the two PNGs)\n" as *u8); sys_exit(0); return 0 } 95 gw(" RED\n" as *u8); sys_exit(1); return 1 96}