render3d: HUD text, panels and images share a draw - the font stays bound and each vertex says what it reads
A panel and its label alternated the white and font textures, and every switch closed the overlay's draw range: 77-91 ranges a frame in town. The font atlas is now bound beside the image texture for the whole flush, and v carries 4 x the vertex's mode (0 image, 1 font, 2 flat colour) on top of its real coordinate, so only a different image texture or a clip rectangle closes a range. Town: 24 ranges. OpenGL frames byte-identical at all five viewpoints; MoltenVK with validation adds no message. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
cdfffa62bb
commit
eb1cd3e01a
4 changed files with 33 additions and 21 deletions
|
|
@ -17,6 +17,8 @@ var ov_vbo: int = 0
|
|||
var ov_buf: pointer = null
|
||||
var ov_n: int = 0
|
||||
var ov_tex: int = 0
|
||||
var ov_mode: int = 2 # what the next quads read: 0 the image texture, 1 the font, 2 a flat colour
|
||||
var ov_voff: int = 0 # float bits: 4 x ov_mode, added to v (overlay.frag)
|
||||
var ov_white: int = 0
|
||||
var ov_font: int = 0
|
||||
var ov_font_adv: words = null # float bits, em units, one per glyph in the atlas
|
||||
|
|
@ -165,6 +167,7 @@ function ov_begin() -> void {
|
|||
u_f2(gpu_uniform(ov_prog, "u_screen"), fi(gl_w), fi(gl_h))
|
||||
ov_n = 0; ov_nr = 0; ov_range_start = 0
|
||||
ov_tex = ov_white
|
||||
ov_mode = 2; ov_voff = fi(8)
|
||||
ov_clip_w = 0
|
||||
ov_open = true
|
||||
}
|
||||
|
|
@ -198,18 +201,15 @@ function ov_flush() -> void {
|
|||
gpu_use_program(ov_prog)
|
||||
gpu_mesh_bind(ov_mesh)
|
||||
gpu_buffer_upload(ov_vbo, gl_bytes_of(ov_n * 6 * OV_FLOATS), ov_buf, GPU_STREAM)
|
||||
var font = ov_font
|
||||
if font == 0 { font = ov_white }
|
||||
r3d_bind_2d(ov_prog, "u_font", 1, font)
|
||||
var last = -1
|
||||
var clipped = false
|
||||
for i in 0 .. ov_nr {
|
||||
let o = i * OV_RANGE_W
|
||||
let t = ov_ranges[o]
|
||||
if t != last {
|
||||
r3d_bind_2d(ov_prog, "u_tex", 0, t)
|
||||
var is_font = F_ZERO
|
||||
if t == ov_font { is_font = F_ONE }
|
||||
u_f(gpu_uniform(ov_prog, "u_is_font"), is_font)
|
||||
last = t
|
||||
}
|
||||
if t != last { r3d_bind_2d(ov_prog, "u_tex", 0, t); last = t }
|
||||
if ov_ranges[o + 5] > 0 {
|
||||
clipped = true
|
||||
gpu_scissor(ov_ranges[o + 3], ov_ranges[o + 4], ov_ranges[o + 5], ov_ranges[o + 6])
|
||||
|
|
@ -227,7 +227,13 @@ function ov_end() -> void {
|
|||
gpu_depth_test(true)
|
||||
ov_open = false
|
||||
}
|
||||
# Text and flat panels never end a draw: the font atlas stays bound beside the image texture and each
|
||||
# vertex says which it reads (ov_voff). Only a different image texture closes the range. A panel and
|
||||
# its label used to alternate the white and font textures, and the HUD was 77-91 draws a frame.
|
||||
function ov_use_tex(t: int) -> void {
|
||||
if t != 0 and t == ov_font { ov_mode = 1; ov_voff = fi(4); return }
|
||||
if t == ov_white { ov_mode = 2; ov_voff = fi(8); return }
|
||||
ov_mode = 0; ov_voff = F_ZERO
|
||||
if t != ov_tex { ov_close_range(); ov_tex = t }
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +241,7 @@ function ov_use_tex(t: int) -> void {
|
|||
function ov_vert(k: int, x: int, y: int, u: int, v: int, r: int, g: int, b: int, a: int) -> void {
|
||||
let o = k * OV_FLOATS
|
||||
gl_put_bits(ov_buf, o, x); gl_put_bits(ov_buf, o + 1, y)
|
||||
gl_put_bits(ov_buf, o + 2, u); gl_put_bits(ov_buf, o + 3, v)
|
||||
gl_put_bits(ov_buf, o + 2, u); gl_put_bits(ov_buf, o + 3, f_add(v, ov_voff))
|
||||
gl_put_bits(ov_buf, o + 4, r); gl_put_bits(ov_buf, o + 5, g); gl_put_bits(ov_buf, o + 6, b); gl_put_bits(ov_buf, o + 7, a)
|
||||
}
|
||||
# a textured quad, float-bit pixel corners and uvs
|
||||
|
|
|
|||
|
|
@ -1,14 +1,20 @@
|
|||
// 2D overlay: a texture times a colour; the font atlas is white glyphs on alpha
|
||||
// 2D overlay: an image texture, the font atlas (white glyphs on alpha) 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;
|
||||
in vec4 v_col;
|
||||
uniform sampler2D u_tex;
|
||||
uniform float u_is_font;
|
||||
uniform sampler2D u_font;
|
||||
out vec4 o_color;
|
||||
void main() {
|
||||
vec4 t = texture(u_tex, v_uv);
|
||||
if (u_is_font > 0.5) {
|
||||
o_color = vec4(v_col.rgb, v_col.a * t.a);
|
||||
float mode = floor((v_uv.y + 0.5) * 0.25);
|
||||
vec2 uv = vec2(v_uv.x, v_uv.y - 4.0 * mode);
|
||||
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);
|
||||
} else {
|
||||
vec4 t = texture(u_tex, uv);
|
||||
o_color = vec4(v_col.rgb * t.rgb, v_col.a * t.a);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1771,7 +1771,7 @@ U 1b654972 vert u_screen 0 vec2 1 0
|
|||
I 1b654972 a_pos 0 vec2
|
||||
I 1b654972 a_uv 1 vec2
|
||||
I 1b654972 a_col 2 vec4
|
||||
B 1b654972 frag 1 768
|
||||
B 1b654972 frag 0 764
|
||||
U 1b654972 frag u_cascade_vp 0 mat4 5 64
|
||||
U 1b654972 frag u_cascade_split 320 float 5 16
|
||||
U 1b654972 frag u_cascade_range 400 float 5 16
|
||||
|
|
@ -1800,14 +1800,14 @@ U 1b654972 frag u_ts_on 748 float 1 0
|
|||
U 1b654972 frag u_force_cascade 752 int 1 0
|
||||
U 1b654972 frag u_cloud_shadow 756 float 1 0
|
||||
U 1b654972 frag u_time 760 float 1 0
|
||||
U 1b654972 frag u_is_font 764 float 1 0
|
||||
T 1b654972 u_brdf 2
|
||||
T 1b654972 u_irradiance 3
|
||||
T 1b654972 u_prefilter 4
|
||||
T 1b654972 u_shadow 5
|
||||
T 1b654972 u_tershadow 6
|
||||
T 1b654972 u_tex 7
|
||||
T 1b654972 u_ts_height 8
|
||||
T 1b654972 u_font 3
|
||||
T 1b654972 u_irradiance 4
|
||||
T 1b654972 u_prefilter 5
|
||||
T 1b654972 u_shadow 6
|
||||
T 1b654972 u_tershadow 7
|
||||
T 1b654972 u_tex 8
|
||||
T 1b654972 u_ts_height 9
|
||||
P 1fde9cd2 skin.vert model.frag
|
||||
B 1fde9cd2 vert 0 3344
|
||||
U 1fde9cd2 vert u_model 0 mat4 1 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue