Got text rendering to work with sokol_gfx (learngl text rendering article #1)
Need to todo the altas article next then the optimizing vod
This commit is contained in:
@ -231,7 +231,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
load_action = .CLEAR,
|
||||
clear_value = { 1, 0, 0, 1 }
|
||||
}
|
||||
vertices := [?]f32 {
|
||||
triangle_vertices := [?]f32 {
|
||||
// positions // colors
|
||||
0.0, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0,
|
||||
0.5, -0.5, 0.5, 0.0, 1.0, 0.0, 1.0,
|
||||
@ -244,8 +244,8 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
using debug.gfx_tri_demo_state
|
||||
bindings.vertex_buffers[0] = sokol_gfx.make_buffer( sokol_gfx.Buffer_Desc {
|
||||
data = {
|
||||
ptr = & vertices,
|
||||
size = size_of(vertices)
|
||||
ptr = & triangle_vertices,
|
||||
size = size_of(triangle_vertices)
|
||||
}
|
||||
})
|
||||
pipeline = sokol_gfx.make_pipeline( sokol_gfx.Pipeline_Desc {
|
||||
@ -261,11 +261,16 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
load_action = .CLEAR,
|
||||
clear_value = { 0, 0, 0, 1 }
|
||||
}
|
||||
|
||||
render_data.pass_actions.bg_clear_black.colors[0] = sokol_gfx.Color_Attachment_Action {
|
||||
load_action = .CLEAR,
|
||||
clear_value = { 0, 0, 0, 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Basic Font Setup
|
||||
if false
|
||||
if true
|
||||
{
|
||||
font_provider_startup()
|
||||
// path_rec_mono_semicasual_reg := strings.concatenate( { Path_Assets, "RecMonoSemicasual-Regular-1.084.ttf" })
|
||||
@ -281,7 +286,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
}
|
||||
|
||||
// Setup the screen ui state
|
||||
if true
|
||||
if false
|
||||
{
|
||||
ui_startup( & screen_ui.base, cache_allocator = persistent_slab_allocator() )
|
||||
ui_floating_startup( & screen_ui.floating, persistent_slab_allocator(), 1 * Kilobyte, 1 * Kilobyte, "screen ui floating manager" )
|
||||
@ -296,7 +301,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
|
||||
// Demo project setup
|
||||
// TODO(Ed): This will eventually have to occur when the user either creates or loads a workspace. I don't know
|
||||
if true
|
||||
if false
|
||||
{
|
||||
using project
|
||||
path = str_intern("./")
|
||||
@ -416,7 +421,7 @@ reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem,
|
||||
|
||||
slab_reload( persistent_slab, persistent_allocator() )
|
||||
|
||||
// hmap_chained_reload( font_provider_data.font_cache, persistent_allocator())
|
||||
hmap_chained_reload( font_provider_data.font_cache, persistent_allocator())
|
||||
|
||||
slab_reload( string_cache.slab, persistent_allocator() )
|
||||
hamp_zpl_reload( & string_cache.table, persistent_slab_allocator())
|
||||
@ -424,7 +429,7 @@ reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem,
|
||||
slab_reload( frame_slab, frame_allocator())
|
||||
slab_reload( transient_slab, transient_allocator())
|
||||
|
||||
ui_reload( & get_state().project.workspace.ui, cache_allocator = persistent_slab_allocator() )
|
||||
// ui_reload( & get_state().project.workspace.ui, cache_allocator = persistent_slab_allocator() )
|
||||
|
||||
log("Module reloaded")
|
||||
}
|
||||
@ -483,10 +488,23 @@ tick_work_frame :: #force_inline proc( host_delta_time_ms : f64 ) -> b32
|
||||
debug.draw_UI_padding_bounds = false
|
||||
debug.draw_ui_content_bounds = false
|
||||
|
||||
config.engine_refresh_hz = 10000
|
||||
|
||||
// config.color_theme = App_Thm_Light
|
||||
// config.color_theme = App_Thm_Dusk
|
||||
config.color_theme = App_Thm_Dark
|
||||
|
||||
sokol_width := sokol_app.widthf()
|
||||
sokol_height := sokol_app.heightf()
|
||||
|
||||
window := & state.app_window
|
||||
// if int(window.extent.x) != int(sokol_width) || int(window.extent.y) != int(sokol_height) {
|
||||
window.resized = true
|
||||
window.extent.x = sokol_width * 0.5
|
||||
window.extent.y = sokol_height * 0.5
|
||||
// log("sokol_app: Event-based frame callback triggered (detected a resize")
|
||||
// }
|
||||
|
||||
should_close |= update( host_delta_time_ms )
|
||||
render()
|
||||
|
||||
|
@ -25,12 +25,12 @@ sokol_app_frame_callback :: proc "c" () {
|
||||
sokol_height := sokol_app.heightf()
|
||||
|
||||
window := & state.app_window
|
||||
if int(window.extent.x) != int(sokol_width) || int(window.extent.y) != int(sokol_height) {
|
||||
// if int(window.extent.x) != int(sokol_width) || int(window.extent.y) != int(sokol_height) {
|
||||
window.resized = true
|
||||
window.extent.x = sokol_width * 0.5
|
||||
window.extent.y = sokol_height * 0.5
|
||||
log("sokol_app: Event-based frame callback triggered (detected a resize")
|
||||
}
|
||||
// log("sokol_app: Event-based frame callback triggered (detected a resize")
|
||||
// }
|
||||
|
||||
// sokol_app is the only good reference for a frame-time at this point.
|
||||
sokol_delta_ms := sokol_app.frame_delta()
|
||||
|
@ -3,15 +3,39 @@ package sectr
|
||||
import sokol_gfx "thirdparty:sokol/gfx"
|
||||
import sokol_glue "thirdparty:sokol/glue"
|
||||
|
||||
PassActions :: struct {
|
||||
bg_clear_black : sokol_gfx.Pass_Action,
|
||||
|
||||
}
|
||||
|
||||
RenderState :: struct {
|
||||
pass_actions : PassActions,
|
||||
}
|
||||
|
||||
ortho :: proc(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32) -> [4][4]f32 {
|
||||
result: [4][4]f32
|
||||
result[0][0] = 2.0 / (right - left)
|
||||
result[1][1] = 2.0 / (top - bottom)
|
||||
result[2][2] = -2.0 / (far - near)
|
||||
result[3][0] = -(right + left) / (right - left)
|
||||
result[3][1] = -(top + bottom) / (top - bottom)
|
||||
result[3][2] = -(far + near) / (far - near)
|
||||
result[3][3] = 1.0
|
||||
return result
|
||||
}
|
||||
|
||||
render :: proc()
|
||||
{
|
||||
state := get_state(); using state
|
||||
using render_data
|
||||
|
||||
do_nothing : bool
|
||||
do_nothing = false
|
||||
|
||||
// apply_bindings :: sokol_gfx.apply_bindings
|
||||
|
||||
// Clear Demo
|
||||
if true
|
||||
if false
|
||||
{
|
||||
green_value := debug.gfx_clear_demo_pass_action.colors[0].clear_value.g + 0.01
|
||||
debug.gfx_clear_demo_pass_action.colors[0].clear_value.g = green_value > 1.0 ? 0.0 : green_value
|
||||
@ -38,11 +62,93 @@ render :: proc()
|
||||
sokol_gfx.commit()
|
||||
}
|
||||
|
||||
// learnopengl.com/In-Practice/Text-Rendering
|
||||
if true
|
||||
{
|
||||
using font_provider_data
|
||||
|
||||
// green_value := debug.gfx_clear_demo_pass_action.colors[0].clear_value.g + 0.01
|
||||
// debug.gfx_clear_demo_pass_action.colors[0].clear_value.g = green_value > 1.0 ? 0.0 : green_value
|
||||
// sokol_gfx.begin_pass( sokol_gfx.Pass {
|
||||
// action = debug.gfx_clear_demo_pass_action,
|
||||
// swapchain = sokol_glue.swapchain()
|
||||
// })
|
||||
sokol_gfx.begin_pass(sokol_gfx.Pass { action = pass_actions.bg_clear_black, swapchain = sokol_glue.swapchain() })
|
||||
sokol_gfx.apply_pipeline( gfx_pipeline )
|
||||
// sokol_gfx.update_buffer( gfx_vbuffer, sokol_gfx.Range{ , Font_Provider_Ggfx_Buffer_Size } )
|
||||
|
||||
projection := ortho( 0, app_window.extent.x * 2, 0, app_window.extent.y * 2, -1, 1 )
|
||||
sokol_gfx.apply_uniforms( sokol_gfx.Shader_Stage.VS, SLOT_vs_params, sokol_gfx.Range{ & projection[0][0] , size_of(projection) })
|
||||
|
||||
text_test_str := str_fmt("frametime: %v", frametime_avg_ms)
|
||||
def := hmap_chained_get( font_cache, default_font.key )
|
||||
|
||||
x : f32 = 0.0
|
||||
y : f32 = 25.0
|
||||
scale : f32 = 1.0
|
||||
next := 0
|
||||
for codepoint, byte_offset in text_test_str
|
||||
{
|
||||
using def
|
||||
glyph := & glyphs[ int(codepoint) ]
|
||||
|
||||
if glyph.size.x == 0 do continue
|
||||
// logf("Drawing glyph: %v", codepoint)
|
||||
|
||||
bearing : Vec2 = { f32(glyph.bearing.x), f32(glyph.bearing.y) }
|
||||
size : Vec2 = { f32(glyph.size.x), f32(glyph.size.y) }
|
||||
|
||||
pos := vec2(
|
||||
x + bearing.x * scale,
|
||||
y - (size.y - bearing.y) * scale
|
||||
)
|
||||
|
||||
width := size.x * scale
|
||||
height := size.y * scale
|
||||
|
||||
vertices : [6][4]f32 = {
|
||||
{ pos.x, pos.y + height, 0.0, 0.0 },
|
||||
{ pos.x, pos.y, 0.0, 1.0 },
|
||||
{ pos.x + width, pos.y, 1.0, 1.0 },
|
||||
|
||||
{ pos.x, pos.y + height, 0.0, 0.0 },
|
||||
{ pos.x + width, pos.y, 1.0, 1.0 },
|
||||
{ pos.x + width, pos.y + height, 1.0, 0.0 }
|
||||
}
|
||||
|
||||
color : [3]f32 = { 0 = 255, 1 = 255, 2 = 255 }
|
||||
fs_uniform := Fs_Params {
|
||||
glyph_color = color
|
||||
}
|
||||
|
||||
vbuf_offset := sokol_gfx.append_buffer( gfx_vbuffer, { & vertices[0][0], size_of(vertices) })
|
||||
// vbuf_offset : i32 = 0
|
||||
|
||||
// bindings := glyph.bindings
|
||||
bindings := sokol_gfx.Bindings {
|
||||
vertex_buffers = { 0 = gfx_vbuffer, },
|
||||
vertex_buffer_offsets = { 0 = vbuf_offset },
|
||||
fs = {
|
||||
images = { 0 = glyph.texture },
|
||||
samplers = { 0 = gfx_sampler }
|
||||
},
|
||||
}
|
||||
sokol_gfx.apply_uniforms( sokol_gfx.Shader_Stage.FS, SLOT_fs_params, sokol_gfx.Range{ & fs_uniform, size_of(fs_uniform) })
|
||||
sokol_gfx.apply_bindings( bindings )
|
||||
|
||||
sokol_gfx.draw( 0, 6, 1 )
|
||||
next += 6
|
||||
|
||||
x += f32(glyph.advance >> 6) * scale
|
||||
}
|
||||
|
||||
sokol_gfx.end_pass()
|
||||
sokol_gfx.commit()
|
||||
}
|
||||
|
||||
// Batching Enqueue Boxes
|
||||
// Mixed with the batching enqueue for text
|
||||
|
||||
|
||||
//Begin
|
||||
// Flush boxs
|
||||
// flush text
|
||||
|
@ -198,9 +198,10 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
|
||||
// TODO(Ed): We need input buffer so that we can consume input actions based on the UI with priority
|
||||
|
||||
ui_screen_tick()
|
||||
// ui_screen_tick()
|
||||
|
||||
//region WorkspaceImgui Tick
|
||||
if false
|
||||
{
|
||||
profile("Workspace Imgui")
|
||||
|
||||
|
Reference in New Issue
Block a user