diff --git a/packages/ludic.render3d/overlay.ludic b/packages/ludic.render3d/overlay.ludic index f9c4ec1d..31e35b65 100644 --- a/packages/ludic.render3d/overlay.ludic +++ b/packages/ludic.render3d/overlay.ludic @@ -67,6 +67,29 @@ function overlay_init(render3d_st: mut Render3dState, font_dir: string) -> bool return true } +# The atlas is white glyphs on alpha, and the overlay reads only the coverage: it is kept as one +# byte a texel (R8). As RGBA a 3072 x 2688 atlas was 44 MB with its mips, the most of any UI texture. +@alloc_ok("loading a font: a load, not a frame") +function ov_font_tex(render3d_st: mut Render3dState, path: string) -> int { + let px = png_decode(render3d_st, path) + if px == null { return 0 } + if render3d_st.tex_channels != 4 or render3d_st.tex_depth != 8 { + let id0 = tex_upload(render3d_st, px, false, true) + free(px) + tex_note_size(render3d_st, id0) + return id0 + } + let n = render3d_st.tex_w * render3d_st.tex_h + let a = bytes(n) + for i in 0 .. n { a[i] = px[i * 4 + 3] } + free(px) + render3d_st.tex_channels = 1 + let id = tex_upload(render3d_st, a, false, true) + free(a) + tex_note_size(render3d_st, id) + return id +} + # Load (or swap to) the font atlas in `font_dir`: font.png and font.json. A game calls it # again to change fonts at run time - a language whose script the default atlas does not # carry brings its own. Returns false, and keeps the font it had, if there is none there. @@ -74,7 +97,7 @@ function overlay_init(render3d_st: mut Render3dState, font_dir: string) -> bool function overlay_font(render3d_st: mut Render3dState, font_dir: string) -> bool { let meta = Fs.read_text(font_dir + "/font.json") if meta == null { return false } - let tex = tex_load_ex(render3d_st, font_dir + "/font.png", false, 0) + let tex = ov_font_tex(render3d_st, font_dir + "/font.png") if tex == 0 { return false } let j = Json.parse(meta) render3d_st.ov_font_cols = jint(j, "cols", 16); render3d_st.ov_font_rows = jint(j, "rows", 6) diff --git a/packages/ludic.render3d/shaders/overlay.frag b/packages/ludic.render3d/shaders/overlay.frag index 1b3d08f9..0d3a9c30 100644 --- a/packages/ludic.render3d/shaders/overlay.frag +++ b/packages/ludic.render3d/shaders/overlay.frag @@ -1,4 +1,4 @@ -// 2D overlay: an image texture, the font atlas (white glyphs on alpha) or a flat colour, times a +// 2D overlay: an image texture, the font atlas (glyph coverage, R8) or a flat colour, times a // colour. Which one is the vertex's own: v carries 4 x the mode (0 image, 1 font, 2 flat) on top of // its real coordinate, so text, panels and an image's quads share a draw (overlay.ludic, ov_use_tex). in vec2 v_uv; @@ -27,7 +27,7 @@ void main() { if (mode > 1.5) { o_color = v_col; } else if (mode > 0.5) { - o_color = vec4(v_col.rgb, v_col.a * texture(u_font, uv).a); + o_color = vec4(v_col.rgb, v_col.a * texture(u_font, uv).r); // the atlas is its coverage alone (R8) } else { vec4 t = texture(u_tex, uv); o_color = vec4(v_col.rgb * t.rgb, v_col.a * t.a); diff --git a/packages/ludic.render3d/shaders/spv/1b654972.frag.spv b/packages/ludic.render3d/shaders/spv/1b654972.frag.spv index 2c38afa0..46c181f1 100644 Binary files a/packages/ludic.render3d/shaders/spv/1b654972.frag.spv and b/packages/ludic.render3d/shaders/spv/1b654972.frag.spv differ diff --git a/packages/ludic.render3d/shaders/spv/e86f78e8.frag.spv b/packages/ludic.render3d/shaders/spv/e86f78e8.frag.spv index eedac340..5cc0f51d 100644 Binary files a/packages/ludic.render3d/shaders/spv/e86f78e8.frag.spv and b/packages/ludic.render3d/shaders/spv/e86f78e8.frag.spv differ