render3d: terrain tiles for a map with no photograph (Lamar)

The tiles' photograph side is 0 when the map has none: no photograph or coarse photograph sections, no
decode, ter_o answers 0, and no coarse photograph texture - as such a map has always drawn. The cut and
terrain_tiles_bake no longer require one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-29 17:40:39 +03:00
parent 199109f1ae
commit f02eab5c51
4 changed files with 30 additions and 14 deletions

View file

@ -74,6 +74,7 @@ function tt_decode(render3d_st: mut Render3dState, t: int, s: int) -> void {
render3d_st.tt_nm[s * n2 + i] = gvk_half(float_bits(lt_oct_dec(e, false))) | (gvk_half(float_bits(lt_oct_dec(e, true))) << 16)
}
let side = render3d_st.tt_oside
if side == 0 { return }
let o2 = side * side
file_seek(f, render3d_st.tt_ooff + t * o2 * 3, 0)
file_read(f, data_of(sc), o2 * 3)
@ -100,21 +101,31 @@ function ltt2_gpu_coarse(render3d_st: mut Render3dState) -> void {
let nm = tex_target(render3d_st, c, c, GL_RG16F, GL_RG, GL_FLOAT, GL_LINEAR)
gpu_tex_fill(render3d_st, nm, GL_RG16F, c, c, GL_RG, GL_FLOAT, data_of(xz))
free(xz)
file_seek(f, render3d_st.tt_cooff, 0)
file_read(f, data_of(raw), c * c * 3)
# no photograph (side 0): none on the GPU either, as a map without one has always had
var o = 0
if render3d_st.tt_oside > 0 { o = ltt2_gpu_coarse_ortho(render3d_st, raw) }
free(raw)
if render3d_st.ter_height_tex != 0 { gpu_tex_free(render3d_st, render3d_st.ter_height_tex) }
if render3d_st.ter_normal_tex != 0 { gpu_tex_free(render3d_st, render3d_st.ter_normal_tex) }
if render3d_st.ter_ortho_tex != 0 { gpu_tex_free(render3d_st, render3d_st.ter_ortho_tex) }
render3d_st.ter_height_tex = h; render3d_st.ter_normal_tex = nm
if o != 0 { render3d_st.ter_ortho_tex = o }
render3d_st.gvk_tag = was
tp_pool(render3d_st)
}
# the coarse photograph from the file into an sRGB texture with mips (raw: c * c * 3 bytes of scratch)
function ltt2_gpu_coarse_ortho(render3d_st: mut Render3dState, raw: []byte) -> int {
let c = TT_COARSE
file_seek(render3d_st.tt_file, render3d_st.tt_cooff, 0)
file_read(render3d_st.tt_file, data_of(raw), c * c * 3)
let o = tex_target(render3d_st, c, c, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR)
gpu_tex_fill(render3d_st, o, GL_SRGB8_ALPHA8, c, c, GL_RGB, GL_UNSIGNED_BYTE, data_of(raw))
free(raw)
gpu_tex_bind(render3d_st, GPU_TEX2D, o)
gpu_tex_param(render3d_st, GPU_TEX2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
gpu_tex_mips(render3d_st, GPU_TEX2D)
gpu_tex_paramf(render3d_st, GPU_TEX2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, render3d_st.tex_anisotropy)
if render3d_st.ter_height_tex != 0 { gpu_tex_free(render3d_st, render3d_st.ter_height_tex) }
if render3d_st.ter_normal_tex != 0 { gpu_tex_free(render3d_st, render3d_st.ter_normal_tex) }
if render3d_st.ter_ortho_tex != 0 { gpu_tex_free(render3d_st, render3d_st.ter_ortho_tex) }
render3d_st.ter_height_tex = h; render3d_st.ter_normal_tex = nm; render3d_st.ter_ortho_tex = o
render3d_st.gvk_tag = was
tp_pool(render3d_st)
return o
}
# ---- the bake -------------------------------------------------------------------------------
@ -123,7 +134,7 @@ function ltt2_gpu_coarse(render3d_st: mut Render3dState) -> void {
# The whole copy is left holding the quantized values, as everything will read them.
@alloc_ok("a bake: once, at build time")
export function terrain_tiles_bake(render3d_st: mut Render3dState, path: string, key: string, version: int, inputs_hash: long) -> bool {
if render3d_st.ter_heights == null or render3d_st.ter_ortho_px == null or render3d_st.ter_normal_tex == 0 { return false }
if render3d_st.ter_heights == null or render3d_st.ter_normal_tex == 0 { return false }
Fs.mkdir(Path.dir(path))
let f = file_open(path, "wb")
if f == null { return false }

View file

@ -12,7 +12,9 @@ const LT_HEAD: int = 128 # 32 words
@alloc_ok("a map being made or baked: the tiles written once")
function ltt2_write(render3d_st: mut Render3dState, f: pointer, base: int) -> int {
let n = TERRAIN_RES / TT_TEX
let side = render3d_st.ter_ortho_w / n
# a map with no photograph (Lamar's ground is painted by its materials) has no photograph sections
var side = 0
if render3d_st.ter_ortho_px != null { side = render3d_st.ter_ortho_w / n }
let head = words(32)
for k in 0 .. 32 { head[k] = 0 }
file_write(f, data_of(head), LT_HEAD)
@ -20,11 +22,13 @@ function ltt2_write(render3d_st: mut Render3dState, f: pointer, base: int) -> in
head[8] = at; at += ltt2_write_heights(render3d_st, f, n)
let nrm = ltt2_normals_back(render3d_st)
head[10] = at; at += ltt2_write_normals(f, nrm, n)
head[11] = at; at += ltt2_write_ortho(render3d_st, f, n, side)
head[11] = at
if side > 0 { at += ltt2_write_ortho(render3d_st, f, n, side) }
head[12] = at; at += ltt2_write_coarse_h(render3d_st, f)
head[13] = at; at += ltt2_write_coarse_n(f, nrm)
free(nrm)
head[14] = at; at += ltt2_write_coarse_o(render3d_st, f)
head[14] = at
if side > 0 { at += ltt2_write_coarse_o(render3d_st, f) }
head[0] = LT_MAGIC; head[1] = LT_VERSION; head[2] = TT_TEX; head[3] = n; head[4] = side
head[5] = TERRAIN_RES; head[6] = render3d_st.ter_ortho_w; head[7] = TT_COARSE; head[15] = at
file_seek(f, base, 0)

View file

@ -28,6 +28,7 @@ function ter_h(render3d_st: mut Render3dState, tx: int, tz: int) -> float {
# the photograph's texel (px, pz) as 0xRRGGBB
function ter_o(render3d_st: mut Render3dState, px: int, pz: int) -> int {
let side = render3d_st.tt_oside
if side == 0 { return 0 }
let s = tt_slot(render3d_st, (pz / side) * render3d_st.tt_n + (px / side))
if s < 0 { return 0 }
return render3d_st.tt_o[s * side * side + (pz % side) * side + (px % side)]

View file

@ -9,7 +9,7 @@ const TT_HEAD: int = 64 # bytes: 16 words
@alloc_ok("a map being made: its tiles' file and their pools, once, not a frame")
function terrain_tiles_cut(render3d_st: mut Render3dState) -> void {
if render3d_st.tt_baked or render3d_st.tt_dir == "" or render3d_st.ter_heights == null or render3d_st.ter_ortho_px == null { return }
if render3d_st.tt_baked or render3d_st.tt_dir == "" or render3d_st.ter_heights == null { return }
let t0 = gl_now_us()
tt_close(render3d_st)
let path = `{render3d_st.tt_dir}/{render3d_st.tt_key}.tiles`