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}