lots of corrections to VEFontCache, still no letters on screen

Something is either wrong with the sokol_gfx rendering setup or its a really dumb checkbox/uv value
This commit is contained in:
Edward R. Gonzalez 2024-06-14 17:00:06 -04:00
parent 3b9e08794a
commit 87bc31636e
5 changed files with 80 additions and 60 deletions

View File

@ -179,8 +179,8 @@ InitAtlasParams :: struct {
}
InitAtlasParams_Default :: InitAtlasParams {
width = 4 * Kilobyte,
height = 2 * Kilobyte,
width = 4096,
height = 2048,
glyph_padding = 1,
region_a = {
@ -265,38 +265,43 @@ init :: proc( ctx : ^Context, parser_kind : ParserKind,
draw_list.calls, error = make( Array(DrawCall), 512 )
assert(error == .None, "VEFontCache.init : Failed to allocate draw_list.calls")
init_atlas_region :: proc( region : ^AtlasRegion, params : InitAtlasParams, region_params : InitAtlasRegionParams ) {
init_atlas_region :: proc( region : ^AtlasRegion, params : InitAtlasParams, region_params : InitAtlasRegionParams, factor : Vec2i, expected_cap : u32 ) {
using region
next_idx = 0;
width = region_params.width
height = region_params.height
size = {
params.width / 4,
params.height / 2,
params.width / factor.x,
params.height / factor.y,
}
capacity = {
size.x / width,
size.y / height,
}
assert( capacity.x * capacity.y == expected_cap )
error : AllocatorError
// state.cache, error = make( HMapChained(LRU_Link), uint(capacity.x * capacity.y) )
// assert( error == .None, "VEFontCache.init_atlas_region : Failed to allocate state.cache")
LRU_init( & state, capacity.x * capacity.y )
}
init_atlas_region( & atlas.region_a, atlas_params, atlas_params.region_a )
init_atlas_region( & atlas.region_b, atlas_params, atlas_params.region_b )
init_atlas_region( & atlas.region_c, atlas_params, atlas_params.region_c )
init_atlas_region( & atlas.region_d, atlas_params, atlas_params.region_d )
init_atlas_region( & atlas.region_a, atlas_params, atlas_params.region_a, { 4, 2}, 1024 )
init_atlas_region( & atlas.region_b, atlas_params, atlas_params.region_b, { 4, 2}, 512 )
init_atlas_region( & atlas.region_c, atlas_params, atlas_params.region_c, { 4, 1}, 512 )
init_atlas_region( & atlas.region_d, atlas_params, atlas_params.region_d, { 2, 1}, 256 )
atlas.width = atlas_params.width
atlas.height = atlas_params.height
atlas.glyph_padding = atlas_params.glyph_padding
atlas.region_a.offset = {0, 0}
atlas.region_b.offset.x = 0
atlas.region_b.offset.y = atlas.region_a.size.y
atlas.region_c.offset.x = atlas.region_a.size.x
atlas.region_c.offset.y = 0
atlas.region_d.offset.x = atlas.width / 2
atlas.region_d.offset.y = 0
LRU_init( & shape_cache.state, shape_cache_params.capacity )
@ -476,7 +481,7 @@ cache_glyph :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph, scale,
f32(bounds_0.x) - 21,
f32(bounds_0.y) - 33,
}
// Note(Original Author): Figure out scaling so it fits within our box.
draw := DrawCall_Default
draw.pass = FrameBufferPass.Glyph
@ -601,7 +606,7 @@ cache_glyph_to_atlas :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph
// Draw oversized glyph to update FBO
glyph_draw_scale := over_sample * entry.size_scale
glyph_draw_translate := Vec2 { f32(bounds_0.x), f32(bounds_0.y) } * glyph_draw_scale + Vec2{ glyph_padding, glyph_padding }
glyph_draw_translate := Vec2 { f32(-bounds_0.x), f32(-bounds_0.y) } * glyph_draw_scale + Vec2{ glyph_padding, glyph_padding }
glyph_draw_translate.x = cast(f32) (i32(glyph_draw_translate.x + 0.9999999))
glyph_draw_translate.y = cast(f32) (i32(glyph_draw_translate.y + 0.9999999))
@ -613,16 +618,16 @@ cache_glyph_to_atlas :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph
// Calculate the src and destination regions
dst_position, dst_width, dst_height := atlas_bbox( atlas, region_kind, u32(atlas_index) )
dst_glyph_position := dst_position //+ { glyph_padding, glyph_padding }
dst_glyph_position := dst_position + { glyph_padding, glyph_padding }
dst_glyph_width := f32(bounds_width) * entry.size_scale
dst_glyph_height := f32(bounds_height) * entry.size_scale
// dst_glyph_position -= { glyph_padding, glyph_padding }
dst_glyph_position -= { glyph_padding, glyph_padding }
dst_glyph_width += 2 * glyph_padding
dst_glyph_height += 2 * glyph_padding
dst_size := Vec2 { dst_width, dst_height }
dst_glyph_size := Vec2 { dst_glyph_width, dst_glyph_height }
screenspace_x_form( & dst_glyph_position, & dst_glyph_size, f32(atlas.width), f32(atlas.height) )
screenspace_x_form( & dst_glyph_position, & dst_glyph_size, f32(atlas.width), f32(atlas.height) )
screenspace_x_form( & dst_position, & dst_size, f32(atlas.width), f32(atlas.height) )
src_position := Vec2 { f32(atlas.update_batch_x), 0 }
@ -652,7 +657,7 @@ cache_glyph_to_atlas :: proc( ctx : ^Context, font : FontID, glyph_index : Glyph
// Queue up a blit from glyph_update_FBO to the atlas
region = .None
start_index = u32(atlas.draw_list.indices.num)
blit_quad( & atlas.draw_list, dst_glyph_position, dst_glyph_position + dst_glyph_size, src_position, src_position + src_size )
blit_quad( & atlas.draw_list, dst_glyph_position, dst_position + dst_glyph_size, src_position, src_position + src_size )
end_index = u32(atlas.draw_list.indices.num)
append( & atlas.draw_list.calls, call )
}

View File

@ -36,7 +36,7 @@ atlas_bbox :: proc( atlas : ^Atlas, region : AtlasRegionKind, local_idx : u32 )
height = f32(atlas.region_b.height)
position.x = cast(f32) (( local_idx % atlas.region_a.capacity.x ) * atlas.region_a.width)
position.y = cast(f32) (( local_idx % atlas.region_a.capacity.x ) * atlas.region_a.height)
position.y = cast(f32) (( local_idx / atlas.region_a.capacity.x ) * atlas.region_a.height)
position.x += f32(atlas.region_a.offset.x)
position.y += f32(atlas.region_a.offset.y)
@ -46,7 +46,7 @@ atlas_bbox :: proc( atlas : ^Atlas, region : AtlasRegionKind, local_idx : u32 )
height = f32(atlas.region_b.height)
position.x = cast(f32) (( local_idx % atlas.region_b.capacity.x ) * atlas.region_b.width)
position.y = cast(f32) (( local_idx % atlas.region_b.capacity.x ) * atlas.region_b.height)
position.y = cast(f32) (( local_idx / atlas.region_b.capacity.x ) * atlas.region_b.height)
position.x += f32(atlas.region_b.offset.x)
position.y += f32(atlas.region_b.offset.y)
@ -56,7 +56,7 @@ atlas_bbox :: proc( atlas : ^Atlas, region : AtlasRegionKind, local_idx : u32 )
height = f32(atlas.region_c.height)
position.x = cast(f32) (( local_idx % atlas.region_c.capacity.x ) * atlas.region_c.width)
position.y = cast(f32) (( local_idx % atlas.region_c.capacity.x ) * atlas.region_c.height)
position.y = cast(f32) (( local_idx / atlas.region_c.capacity.x ) * atlas.region_c.height)
position.x += f32(atlas.region_c.offset.x)
position.y += f32(atlas.region_c.offset.y)
@ -66,7 +66,7 @@ atlas_bbox :: proc( atlas : ^Atlas, region : AtlasRegionKind, local_idx : u32 )
height = f32(atlas.region_d.height)
position.x = cast(f32) (( local_idx % atlas.region_d.capacity.x ) * atlas.region_d.width)
position.y = cast(f32) (( local_idx % atlas.region_d.capacity.x ) * atlas.region_d.height)
position.y = cast(f32) (( local_idx / atlas.region_d.capacity.x ) * atlas.region_d.height)
position.x += f32(atlas.region_d.offset.x)
position.y += f32(atlas.region_d.offset.y)
@ -140,7 +140,7 @@ decide_codepoint_region :: proc( ctx : ^Context, entry : ^Entry, glyph_index : G
region_kind = .A
region = & atlas.region_a
}
else if bounds_width_scaled <= atlas.region_b.width && bounds_height_scaled <= atlas.region_b.height
else if bounds_width_scaled <= atlas.region_a.width && bounds_height_scaled <= atlas.region_a.height
{
// Region B for tall glyphs. These are good for things such as european alphabets.
region_kind = .B

View File

@ -44,32 +44,33 @@ GlyphDrawBuffer :: struct {
draw_list : DrawList,
}
blit_quad :: proc( draw_list : ^DrawList, p0, p1 : Vec2, uv0, uv1 : Vec2 )
blit_quad :: proc( draw_list : ^DrawList, p0 : Vec2 = {0, 0}, p1 : Vec2 = {1, 1}, uv0 : Vec2 = {0, 0}, uv1 : Vec2 = {1, 1} )
{
// logf("Blitting: xy0: %0.2f, %0.2f xy1: %0.2f, %0.2f uv0: %0.2f, %0.2f uv1: %0.2f, %0.2f",
// p0.x, p0.y, p1.x, p1.y, uv0.x, uv0.y, uv1.x, uv1.y);
v_offset := cast(u32) draw_list.vertices.num
vertex := Vertex {
{p0.x, p0.y},
uv0.x,
uv0.y
uv0.x, uv0.y
}
append( & draw_list.vertices, vertex )
vertex = Vertex {
{p0.x, p1.y},
uv0.x,
uv1.y
uv0.x, uv1.y
}
append( & draw_list.vertices, vertex )
vertex = Vertex {
{p1.x, p0.y},
uv1.x,
uv0.y
uv1.x, uv0.y
}
append( & draw_list.vertices, vertex )
vertex = Vertex {
{p1.x, p1.y},
uv1.x,
uv1.y
uv1.x, uv1.y
}
append( & draw_list.vertices, vertex )
@ -112,6 +113,8 @@ directly_draw_massive_glyph :: proc( ctx : ^Context, entry : ^Entry, glyph : Gly
glyph_dst_height := f32(bounds_height) * entry.size_scale
glyph_width += f32(2 * ctx.atlas.glyph_padding)
glyph_height += f32(2 * ctx.atlas.glyph_padding)
glyph_dst_width += f32(2 * ctx.atlas.glyph_padding)
glyph_dst_height += f32(2 * ctx.atlas.glyph_padding)
// Figure out the destination rect.
bounds_scaled := Vec2 {
@ -150,7 +153,7 @@ directly_draw_massive_glyph :: proc( ctx : ^Context, entry : ^Entry, glyph : Gly
draw_cached_glyph :: proc( ctx : ^Context, entry : ^Entry, glyph_index : Glyph, position, scale : Vec2 ) -> b32
{
// Glyph not in current font
if glyph_index == 0 do return true
if glyph_index == 0 do return true
if parser_is_glyph_empty( & entry.parser_info, glyph_index ) do return true
bounds_0, bounds_1 := parser_get_glyph_box( & entry.parser_info, glyph_index )
@ -190,7 +193,7 @@ draw_cached_glyph :: proc( ctx : ^Context, entry : ^Entry, glyph_index : Glyph,
glyph_scale := Vec2 { glyph_width, glyph_height }
bounds_0_scaled := Vec2{ f32(bounds_0.x), f32(bounds_0.y) } * entry.size_scale - { 0.5, 0.5 }
bounds_0_scaled = {
bounds_0_scaled = {
cast(f32) cast(i32) bounds_0_scaled.x,
cast(f32) cast(i32) bounds_0_scaled.y,
}
@ -208,7 +211,7 @@ draw_cached_glyph :: proc( ctx : ^Context, entry : ^Entry, glyph_index : Glyph,
call := DrawCall_Default
{
using call
pass = .Target_Uncached
pass = .Target
colour = ctx.colour
start_index = cast(u32) ctx.draw_list.indices.num
@ -305,7 +308,6 @@ draw_text :: proc( ctx : ^Context, font : FontID, text_utf8 : string, position :
cache_glyph_to_atlas( ctx, font, glyph_index )
// lru_code := u64(glyph_index) + ( ( 0x100000000 * u64(font) ) & 0xFFFFFFFF00000000 )
lru_code := font_glyph_lru_code(font, glyph_index)
set( ctx.temp_codepoint_seen, lru_code, true )
ctx.temp_codepoint_seen_num += 1
@ -315,8 +317,7 @@ draw_text :: proc( ctx : ^Context, font : FontID, text_utf8 : string, position :
draw_text_batch( ctx, entry, shaped, batch_start_idx, i32(shaped.glyphs.num), position, scale )
reset_batch_codepoint_state( ctx )
ctx.cursor_pos.x = position.x + shaped.end_cursor_pos.x * scale.x
ctx.cursor_pos.y = position.y + shaped.end_cursor_pos.y * scale.y
ctx.cursor_pos = position + shaped.end_cursor_pos * scale
return true
}
@ -328,7 +329,6 @@ draw_text_batch :: proc( ctx : ^Context, entry : ^Entry, shaped : ^ShapedText, b
{
glyph_index := shaped.glyphs.data[ index ]
shaped_position := shaped.positions.data[index]
// glyph_translate_x := position.x + shaped_position.x * scale.x
glyph_translate := position + shaped_position * scale
glyph_cached := draw_cached_glyph( ctx, entry, glyph_index, glyph_translate, scale)
assert( glyph_cached == true )
@ -375,12 +375,12 @@ merge_draw_list :: proc( dst, src : ^DrawList )
error : AllocatorError
v_offset := cast(u32) dst.vertices.num
// for index : u32 = 0; index < cast(u32) src.vertices.num; index += 1 {
// error = append( & dst.vertices, src.vertices.data[index] )
// assert( error == .None )
// }
error = append( & dst.vertices, src.vertices )
assert( error == .None )
for index : u32 = 0; index < cast(u32) src.vertices.num; index += 1 {
error = append( & dst.vertices, src.vertices.data[index] )
assert( error == .None )
}
// error = append( & dst.vertices, src.vertices )
// assert( error == .None )
i_offset := cast(u32) dst.indices.num
for index : u32 = 0; index < cast(u32) src.indices.num; index += 1 {

View File

@ -210,10 +210,18 @@ render :: proc()
sokol_gfx.apply_pipeline( screen_pipeline )
fs_uniform := Ve_Draw_Text_Fs_Params { down_sample = 0, colour = {1, 1, 1, 1} }
sokol_gfx.apply_uniforms( ShaderStage.FS, SLOT_ve_blit_atlas_fs_params, Range { & fs_uniform, size_of(fs_uniform) })
src_rt := atlas_rt_color
src_rt := draw_call.pass == .Target_Uncached ? glyph_rt_color : atlas_rt_color
fs_uniform := Ve_Draw_Text_Fs_Params {
// down_sample = draw_call.pass == .Target_Uncached ? 1 : 0,
colour = {1, 1, 1, 1},
}
if draw_call.pass == .Target_Uncached {
fs_uniform.down_sample = 1
src_rt = glyph_rt_color
}
sokol_gfx.apply_uniforms( ShaderStage.FS, SLOT_ve_blit_atlas_fs_params, Range { & fs_uniform, size_of(fs_uniform) })
sokol_gfx.apply_bindings(Bindings {
vertex_buffers = {

View File

@ -183,6 +183,7 @@ font_provider_startup :: proc()
pixel_format = .DEPTH,
// compare = .ALWAYS,
},
cull_mode = .NONE,
// sample_count = 1,
// label =
})
@ -200,7 +201,7 @@ font_provider_startup :: proc()
num_mipmaps = 1,
usage = .IMMUTABLE,
pixel_format = .R8,
sample_count = app_env.defaults.sample_count,
sample_count = 1,
// TODO(Ed): Setup labels for debug tracing/logging
// label =
})
@ -215,7 +216,7 @@ font_provider_startup :: proc()
num_mipmaps = 1,
usage = .IMMUTABLE,
pixel_format = .DEPTH,
sample_count = app_env.defaults.sample_count,
sample_count = 1,
})
color_attach := AttachmentDesc {
@ -236,10 +237,10 @@ font_provider_startup :: proc()
glyph_action := PassAction {
colors = {
0 = {
load_action = .CLEAR,
load_action = .LOAD,
store_action = .STORE,
clear_value = {0.01,0.01,0.01,1},
// clear_value = {0.00, 0.00, 0.00, 0.00},
// clear_value = {0.01,0.01,0.01,1},
clear_value = {0.00, 0.00, 0.00, 0.00},
}
}
}
@ -298,6 +299,7 @@ font_provider_startup :: proc()
pixel_format = .DEPTH,
compare = .ALWAYS,
},
cull_mode = .NONE,
// sample_count = 1,
})
}
@ -307,13 +309,13 @@ font_provider_startup :: proc()
atlas_rt_color = sokol_gfx.make_image( ImageDesc {
type = ._2D,
render_target = true,
width = i32(ve_font_cache.atlas.buffer_width),
height = i32(ve_font_cache.atlas.buffer_height),
width = i32(ve_font_cache.atlas.width),
height = i32(ve_font_cache.atlas.height),
num_slices = 1,
num_mipmaps = 1,
usage = .IMMUTABLE,
pixel_format = .R8,
sample_count = app_env.defaults.sample_count,
sample_count = 1,
// TODO(Ed): Setup labels for debug tracing/logging
// label =
})
@ -322,13 +324,13 @@ font_provider_startup :: proc()
atlas_rt_depth = sokol_gfx.make_image( ImageDesc {
type = ._2D,
render_target = true,
width = i32(ve_font_cache.atlas.buffer_width),
height = i32(ve_font_cache.atlas.buffer_height),
width = i32(ve_font_cache.atlas.width),
height = i32(ve_font_cache.atlas.height),
num_slices = 1,
num_mipmaps = 1,
usage = .IMMUTABLE,
pixel_format = .DEPTH,
sample_count = app_env.defaults.sample_count,
sample_count = 1,
})
verify( sokol_gfx.query_image_state(atlas_rt_depth) < ResourceState.FAILED, "Failed to make atlas_rt_depth")
@ -352,7 +354,7 @@ font_provider_startup :: proc()
0 = {
load_action = .LOAD,
store_action = .STORE,
clear_value = {0,0,0,1.0},
clear_value = {0, 0, 0, 0.0},
}
}
}
@ -386,7 +388,7 @@ font_provider_startup :: proc()
}
color_target := ColorTargetState {
// pixel_format = .R8,
pixel_format = app_env.defaults.color_format,
// write_mask =
blend = BlendState {
enabled = true,
@ -408,6 +410,11 @@ font_provider_startup :: proc()
},
color_count = 1,
sample_count = 1,
depth = {
pixel_format = app_env.defaults.depth_format,
compare = .ALWAYS,
},
cull_mode = .NONE,
})
verify( sokol_gfx.query_pipeline_state(screen_pipeline) < ResourceState.FAILED, "Failed to make screen_pipeline" )
}
@ -417,9 +424,9 @@ font_provider_startup :: proc()
screen_action := PassAction {
colors = {
0 = {
load_action = .CLEAR,
load_action = .LOAD,
store_action = .STORE,
clear_value = {1.0,0.0,0.0,1.0},
clear_value = {0.0,0.0,0.0,0.0},
}
}
}