Mostly cleanup
Text is athe biggest bottleneck right now. Raylib as a renderer fails for this prototype in that front. I'll eventually need to look into other solutions such as SDL2 + something that renders UI boxes & text very fast...
This commit is contained in:
@ -64,48 +64,25 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
alignment := uint(mem.DEFAULT_ALIGNMENT)
|
||||
|
||||
policy_ptr := & default_slab_policy
|
||||
if false
|
||||
{
|
||||
push( policy_ptr, SlabSizeClass { 16 * Megabyte, 4 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 32 * Megabyte, 16 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 32 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 64 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 128 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 256 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 512 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 1 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 2 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 4 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 8 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 16 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 32 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 256 * Megabyte, 64 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 256 * Megabyte, 128 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 512 * Megabyte, 256 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 512 * Megabyte, 512 * Megabyte, alignment })
|
||||
}
|
||||
else
|
||||
{
|
||||
push( policy_ptr, SlabSizeClass { 128 * Kilobyte, 1 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 256 * Kilobyte, 2 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 512 * Kilobyte, 4 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 1 * Megabyte, 16 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 1 * Megabyte, 32 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 1 * Megabyte, 64 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 128 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 256 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 512 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 1 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 2 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 4 * Megabyte, 4 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 8 * Megabyte, 8 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 16 * Megabyte, 16 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 32 * Megabyte, 32 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 64 * Megabyte, alignment })
|
||||
// push( policy_ptr, SlabSizeClass { 128 * Megabyte, 128 * Megabyte, alignment })
|
||||
// push( policy_ptr, SlabSizeClass { 256 * Megabyte, 256 * Megabyte, alignment })
|
||||
// push( policy_ptr, SlabSizeClass { 512 * Megabyte, 512 * Megabyte, alignment })
|
||||
}
|
||||
push( policy_ptr, SlabSizeClass { 128 * Kilobyte, 1 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 256 * Kilobyte, 2 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 512 * Kilobyte, 4 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 1 * Megabyte, 16 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 1 * Megabyte, 32 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 1 * Megabyte, 64 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 128 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 256 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 512 * Kilobyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 1 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 2 * Megabyte, 2 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 4 * Megabyte, 4 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 8 * Megabyte, 8 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 16 * Megabyte, 16 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 32 * Megabyte, 32 * Megabyte, alignment })
|
||||
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 64 * Megabyte, alignment })
|
||||
// push( policy_ptr, SlabSizeClass { 128 * Megabyte, 128 * Megabyte, alignment })
|
||||
// push( policy_ptr, SlabSizeClass { 256 * Megabyte, 256 * Megabyte, alignment })
|
||||
// push( policy_ptr, SlabSizeClass { 512 * Megabyte, 512 * Megabyte, alignment })
|
||||
|
||||
alloc_error : AllocatorError
|
||||
persistent_slab, alloc_error = slab_init( policy_ptr, allocator = persistent_allocator(), dbg_name = Persistent_Slab_DBG_Name )
|
||||
@ -238,7 +215,9 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
verify( alloc_error == .None, "Faield to parse due to allocation failure" )
|
||||
|
||||
// Render texture test
|
||||
debug.viewport_rt = rl.LoadRenderTexture( 1280, 720 )
|
||||
// debug.viewport_rt = rl.LoadRenderTexture( 1280, 720 )
|
||||
|
||||
// debug.proto_text_shader = rl.LoadShader( "C:/projects/SectrPrototype/code/shaders/text_shader.vs", "C:/projects/SectrPrototype/code/shaders/text_shader.fs" )
|
||||
}
|
||||
|
||||
startup_ms := duration_ms( time.tick_lap_time( & startup_tick))
|
||||
@ -340,9 +319,9 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32
|
||||
|
||||
rl.PollInputEvents()
|
||||
|
||||
debug.draw_ui_box_bounds_points = true
|
||||
debug.draw_UI_padding_bounds = true
|
||||
debug.draw_ui_content_bounds = true
|
||||
debug.draw_ui_box_bounds_points = false
|
||||
debug.draw_UI_padding_bounds = false
|
||||
debug.draw_ui_content_bounds = false
|
||||
|
||||
should_close = update( host_delta_time )
|
||||
render()
|
||||
@ -353,8 +332,8 @@ tick :: proc( host_delta_time : f64, host_delta_ns : Duration ) -> b32
|
||||
// Timing
|
||||
{
|
||||
// profile("Client tick timing processing")
|
||||
config.engine_refresh_hz = uint(monitor_refresh_hz)
|
||||
// config.engine_refresh_hz = 1
|
||||
// config.engine_refresh_hz = uint(monitor_refresh_hz)
|
||||
config.engine_refresh_hz = 120
|
||||
frametime_target_ms = 1.0 / f64(config.engine_refresh_hz) * S_To_MS
|
||||
sub_ms_granularity_required := frametime_target_ms <= Frametime_High_Perf_Threshold_MS
|
||||
|
||||
|
@ -36,4 +36,6 @@ DebugData :: struct {
|
||||
// Test 3d Viewport
|
||||
cam_vp : rl.Camera3D,
|
||||
viewport_rt : rl.RenderTexture,
|
||||
}
|
||||
|
||||
proto_text_shader : rl.Shader
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ str_cache_init :: proc( /*allocator : Allocator*/ ) -> ( cache : StringCache ) {
|
||||
cache.slab, alloc_error = slab_init( & policy, allocator = persistent_allocator(), dbg_name = dbg_name )
|
||||
verify(alloc_error == .None, "Failed to initialize the string cache" )
|
||||
|
||||
cache.table, alloc_error = zpl_hmap_init_reserve( StrRunesPair, persistent_allocator(), 1 * Megabyte, dbg_name )
|
||||
cache.table, alloc_error = zpl_hmap_init_reserve( StrRunesPair, persistent_allocator(), 4 * Megabyte, dbg_name )
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -89,9 +89,9 @@ PWS_ParseError :: struct {
|
||||
}
|
||||
|
||||
PWS_ParseError_Max :: 32
|
||||
PWS_TokenArray_ReserveSize :: 8
|
||||
PWS_NodeArray_ReserveSize :: 8
|
||||
PWS_LineArray_ReserveSize :: 8
|
||||
PWS_TokenArray_ReserveSize :: 64 * Kilobyte
|
||||
PWS_NodeArray_ReserveSize :: 64 * Kilobyte
|
||||
PWS_LineArray_ReserveSize :: 64 * Kilobyte
|
||||
|
||||
// TODO(Ed) : The ast arrays should be handled by a slab allocator dedicated to PWS_ASTs
|
||||
// This can grow in undeterministic ways, persistent will get very polluted otherwise.
|
||||
|
@ -1,6 +1,7 @@
|
||||
package sectr
|
||||
|
||||
import "core:math"
|
||||
import "core:strings"
|
||||
import "core:unicode/utf8"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
@ -85,7 +86,7 @@ ws_view_draw_text_string :: proc( content : string, pos : Vec2, size : f32, colo
|
||||
zoom_adjust := px_size * project.workspace.cam.zoom
|
||||
|
||||
rl_font := to_rl_Font(font, zoom_adjust )
|
||||
rl.SetTextureFilter(rl_font.texture, rl.TextureFilter.ANISOTROPIC_4X)
|
||||
rl.SetTextureFilter(rl_font.texture, rl.TextureFilter.POINT)
|
||||
rl.DrawTextCodepoints( rl_font,
|
||||
raw_data(runes), cast(i32) len(runes),
|
||||
position = transmute(rl.Vector2) pos,
|
||||
@ -95,33 +96,56 @@ ws_view_draw_text_string :: proc( content : string, pos : Vec2, size : f32, colo
|
||||
rl.SetTextureFilter(rl_font.texture, rl.TextureFilter.POINT)
|
||||
}
|
||||
|
||||
ws_view_draw_text_StrRunesPair :: proc( content : StrRunesPair, pos : Vec2, size : f32, color : rl.Color = rl.WHITE, font : FontID = Font_Default )
|
||||
when true
|
||||
{
|
||||
// profile(#procedure)
|
||||
state := get_state(); using state
|
||||
ws_view_draw_text_StrRunesPair :: proc( content : StrRunesPair, pos : Vec2, size : f32, color : rl.Color = rl.WHITE, font : FontID = Font_Default )
|
||||
{
|
||||
profile(#procedure)
|
||||
state := get_state(); using state
|
||||
|
||||
if len( content.str ) == 0 {
|
||||
return
|
||||
if len( content.str ) == 0 {
|
||||
return
|
||||
}
|
||||
font := font
|
||||
if font.key == Font_Default.key {
|
||||
font = default_font
|
||||
}
|
||||
pos := ws_view_to_render_pos(pos)
|
||||
|
||||
px_size := size
|
||||
zoom_adjust := px_size * project.workspace.cam.zoom
|
||||
rl_font := to_rl_Font(font, zoom_adjust )
|
||||
runes := content.runes
|
||||
|
||||
profile_begin("raylib draw codepoints related")
|
||||
// rl.DrawTextCodepoints( rl_font,
|
||||
// raw_data(runes), cast(i32) len(runes),
|
||||
// position = transmute(rl.Vector2) pos,
|
||||
// fontSize = px_size,
|
||||
// spacing = 0.0,
|
||||
// tint = color );
|
||||
rl.DrawTextEx(rl_font,
|
||||
strings.clone_to_cstring(content.str),
|
||||
position = transmute(rl.Vector2) pos,
|
||||
fontSize = px_size,
|
||||
spacing = 0.0,
|
||||
tint = color
|
||||
)
|
||||
profile_end()
|
||||
}
|
||||
font := font
|
||||
if font.key == Font_Default.key {
|
||||
font = default_font
|
||||
}
|
||||
else
|
||||
{
|
||||
ws_view_draw_text_StrRunesPair :: proc( content : StrRunesPair, pos : Vec2, size : f32, color : rl.Color = rl.WHITE, font : FontID = Font_Default )
|
||||
{
|
||||
profile(#procedure)
|
||||
state := get_state(); using state
|
||||
|
||||
// We need an alternative way to draw text to the screen (the above is way to expensive)
|
||||
// Possibly need to watch handmade hero...
|
||||
|
||||
|
||||
}
|
||||
pos := ws_view_to_render_pos(pos)
|
||||
|
||||
px_size := size
|
||||
zoom_adjust := px_size * project.workspace.cam.zoom
|
||||
rl_font := to_rl_Font(font, zoom_adjust )
|
||||
runes := content.runes
|
||||
|
||||
rl.SetTextureFilter(rl_font.texture, rl.TextureFilter.ANISOTROPIC_4X)
|
||||
rl.DrawTextCodepoints( rl_font,
|
||||
raw_data(runes), cast(i32) len(runes),
|
||||
position = transmute(rl.Vector2) pos,
|
||||
fontSize = px_size,
|
||||
spacing = 0.0,
|
||||
tint = color );
|
||||
rl.SetTextureFilter(rl_font.texture, rl.TextureFilter.POINT)
|
||||
}
|
||||
|
||||
// Raylib's equivalent doesn't take a length for the string (making it a pain in the ass)
|
||||
|
2
code/tick_new_render.odin
Normal file
2
code/tick_new_render.odin
Normal file
@ -0,0 +1,2 @@
|
||||
package sectr
|
||||
|
@ -4,7 +4,7 @@ import "core:fmt"
|
||||
|
||||
import rl "vendor:raylib"
|
||||
|
||||
draw_rectangle :: #force_inline proc "contextless" ( rect : rl.Rectangle, box : ^UI_Box ) {
|
||||
draw_rectangle :: #force_inline proc "contextless" ( rect : rl.Rectangle, box : ^UI_RenderBoxInfo ) {
|
||||
using box
|
||||
if style.corner_radii[0] > 0 {
|
||||
rl.DrawRectangleRounded( rect, style.corner_radii[0], 9, style.bg_color )
|
||||
@ -14,7 +14,7 @@ draw_rectangle :: #force_inline proc "contextless" ( rect : rl.Rectangle, box :
|
||||
}
|
||||
}
|
||||
|
||||
draw_rectangle_lines :: #force_inline proc "contextless" ( rect : rl.Rectangle, box : ^UI_Box, color : Color, thickness : f32 ) {
|
||||
draw_rectangle_lines :: #force_inline proc "contextless" ( rect : rl.Rectangle, box : ^UI_RenderBoxInfo, color : Color, thickness : f32 ) {
|
||||
using box
|
||||
if style.corner_radii[0] > 0 {
|
||||
rl.DrawRectangleRoundedLines( rect, style.corner_radii[0], 9, thickness, color )
|
||||
@ -78,8 +78,8 @@ render_mode_2d_workspace :: proc()
|
||||
vp_half_size := viewport_size * 0.5
|
||||
viewport_box := range2( -vp_half_size, vp_half_size )
|
||||
viewport_render := range2(
|
||||
world_to_screen_pos( viewport_box.min),
|
||||
world_to_screen_pos( viewport_box.max),
|
||||
ws_view_to_render_pos( viewport_box.min),
|
||||
ws_view_to_render_pos( viewport_box.max),
|
||||
)
|
||||
viewport_rect := range2_to_rl_rect( viewport_render )
|
||||
rl.DrawTextureRec( debug.viewport_rt.texture, viewport_rect, -vp_half_size, Color_White )
|
||||
@ -93,8 +93,8 @@ render_mode_2d_workspace :: proc()
|
||||
when false
|
||||
{
|
||||
render_view := Range2 { pts = {
|
||||
world_to_screen_pos( view_bounds.min),
|
||||
world_to_screen_pos( view_bounds.max),
|
||||
ws_view_to_render_pos( view_bounds.min),
|
||||
ws_view_to_render_pos( view_bounds.max),
|
||||
}}
|
||||
view_rect := rl.Rectangle {
|
||||
render_view.min.x,
|
||||
@ -116,32 +116,17 @@ render_mode_2d_workspace :: proc()
|
||||
state.ui_context = ui
|
||||
|
||||
current := root.first
|
||||
for ; current != nil; current = ui_box_tranverse_next( current )
|
||||
for & current in array_to_slice_num(ui.render_queue)
|
||||
{
|
||||
// profile("Box")
|
||||
parent := current.parent
|
||||
|
||||
layout := current.layout
|
||||
profile("Box")
|
||||
style := current.style
|
||||
computed := & current.computed
|
||||
|
||||
computed_size := computed.bounds.p1 - computed.bounds.p0
|
||||
computed := current.computed
|
||||
|
||||
if ! intersects_range2( view_bounds, computed.bounds ) {
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO(Ed) : Render Borders
|
||||
|
||||
// profile_begin("Calculating Raylib rectangles")
|
||||
// render_anchors := range2(
|
||||
// ws_view_to_render_pos(computed.anchors.min),
|
||||
// ws_view_to_render_pos(computed.anchors.max),
|
||||
// )
|
||||
// render_margins := range2(
|
||||
// ws_view_to_render_pos(computed.margins.min),
|
||||
// ws_view_to_render_pos(computed.margins.max),
|
||||
// )
|
||||
profile_begin("render space calc")
|
||||
render_bounds := range2(
|
||||
ws_view_to_render_pos(computed.bounds.min),
|
||||
ws_view_to_render_pos(computed.bounds.max),
|
||||
@ -160,34 +145,31 @@ render_mode_2d_workspace :: proc()
|
||||
rect_bounds := range2_to_rl_rect( render_bounds )
|
||||
rect_padding := range2_to_rl_rect( render_padding )
|
||||
rect_content := range2_to_rl_rect( render_content )
|
||||
// profile_end()
|
||||
profile_end()
|
||||
|
||||
// profile_begin("rl.DrawRectangleRounded( rect_bounds, style.layout.corner_radii[0], 9, style.bg_color )")
|
||||
profile_begin("raylib drawing")
|
||||
if style.bg_color.a != 0
|
||||
{
|
||||
draw_rectangle( rect_bounds, current )
|
||||
draw_rectangle( rect_bounds, & current )
|
||||
}
|
||||
if layout.border_width > 0 {
|
||||
draw_rectangle_lines( rect_bounds, current, style.border_color, layout.border_width )
|
||||
if current.border_width > 0 {
|
||||
draw_rectangle_lines( rect_bounds, & current, style.border_color, current.border_width )
|
||||
}
|
||||
// profile_end()
|
||||
|
||||
line_thickness := 1 * cam_zoom_ratio
|
||||
|
||||
// profile_begin("rl.DrawRectangleRoundedLines: padding & content")
|
||||
if debug.draw_UI_padding_bounds && equal_range2(computed.content, computed.padding) {
|
||||
draw_rectangle_lines( rect_padding, current, Color_Debug_UI_Padding_Bounds, line_thickness )
|
||||
draw_rectangle_lines( rect_padding, & current, Color_Debug_UI_Padding_Bounds, line_thickness )
|
||||
}
|
||||
else if debug.draw_ui_content_bounds {
|
||||
draw_rectangle_lines( rect_content, current, Color_Debug_UI_Content_Bounds, line_thickness )
|
||||
draw_rectangle_lines( rect_content, & current, Color_Debug_UI_Content_Bounds, line_thickness )
|
||||
}
|
||||
// profile_end()
|
||||
|
||||
point_radius := 3 * cam_zoom_ratio
|
||||
|
||||
// profile_begin("circles")
|
||||
if debug.draw_ui_box_bounds_points
|
||||
{
|
||||
computed_size := computed.bounds.p1 - computed.bounds.p0
|
||||
// center := Vec2 {
|
||||
// render_bounds.p0.x + computed_size.x * 0.5,
|
||||
// render_bounds.p0.y - computed_size.y * 0.5,
|
||||
@ -199,8 +181,10 @@ render_mode_2d_workspace :: proc()
|
||||
}
|
||||
// profile_end()
|
||||
|
||||
profile_end()
|
||||
|
||||
if len(current.text.str) > 0 {
|
||||
ws_view_draw_text( current.text, ws_view_to_render_pos(computed.text_pos * {1, -1}), layout.font_size, style.text_color )
|
||||
ws_view_draw_text( current.text, ws_view_to_render_pos(computed.text_pos * {1, -1}), current.font_size, style.text_color )
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -314,6 +298,18 @@ render_mode_screenspace :: proc ()
|
||||
// debug_text("View Bounds (World): %v", view.pts )
|
||||
|
||||
debug.draw_debug_text_y = 14
|
||||
|
||||
// Define the triangle vertices and colors
|
||||
vertices := []f32{
|
||||
// Positions // Colors (RGBA)
|
||||
-0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, // Vertex 1: Red
|
||||
0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, // Vertex 2: Green
|
||||
0.0, 0.5, 0.0, 0.0, 0.0, 1.0, 1.0 // Vertex 3: Blue
|
||||
}
|
||||
|
||||
// Begin using the shader to draw
|
||||
// rl.BeginShaderMode(debug.proto_text_shader)
|
||||
// rl.EndShaderMode()
|
||||
}
|
||||
|
||||
// A non-zoomable static-view for ui
|
||||
@ -336,28 +332,14 @@ render_screen_ui :: proc()
|
||||
break Render_App_UI
|
||||
}
|
||||
|
||||
// Sort roots children by top-level order
|
||||
|
||||
current := root.first
|
||||
for ; current != nil; current = ui_box_tranverse_next( current )
|
||||
for & current in array_to_slice_num(ui.render_queue)
|
||||
{
|
||||
// profile("Box")
|
||||
parent := current.parent
|
||||
|
||||
style := current.style
|
||||
layout := current.layout
|
||||
computed := & current.computed
|
||||
|
||||
computed_size := computed.bounds.p1 - computed.bounds.p0
|
||||
|
||||
// render_anchors := range2(
|
||||
// screen_to_render_pos(computed.anchors.min),
|
||||
// screen_to_render_pos(computed.anchors.max),
|
||||
// )
|
||||
// render_margins := range2(
|
||||
// screen_to_render_pos(computed.margins.min),
|
||||
// screen_to_render_pos(computed.margins.max),
|
||||
// )
|
||||
render_bounds := range2(
|
||||
screen_to_render_pos(computed.bounds.min),
|
||||
screen_to_render_pos(computed.bounds.max),
|
||||
@ -370,8 +352,6 @@ render_screen_ui :: proc()
|
||||
screen_to_render_pos(computed.content.min),
|
||||
screen_to_render_pos(computed.content.max),
|
||||
)
|
||||
// rect_anchors := range2_to_rl_rect( render_anchors )
|
||||
// rect_margins := range2_to_rl_rect( render_margins )
|
||||
rect_bounds := range2_to_rl_rect( render_bounds )
|
||||
rect_padding := range2_to_rl_rect( render_padding )
|
||||
rect_content := range2_to_rl_rect( render_content )
|
||||
@ -380,10 +360,10 @@ render_screen_ui :: proc()
|
||||
// profile_begin("rl.DrawRectangleRounded( rect_bounds, style.layout.corner_radii[0], 9, style.bg_color )")
|
||||
if style.bg_color.a != 0
|
||||
{
|
||||
draw_rectangle( rect_bounds, current )
|
||||
draw_rectangle( rect_bounds, & current )
|
||||
}
|
||||
if layout.border_width > 0 {
|
||||
draw_rectangle_lines( rect_bounds, current, style.border_color, layout.border_width )
|
||||
if current.border_width > 0 {
|
||||
draw_rectangle_lines( rect_bounds, & current, style.border_color, current.border_width )
|
||||
}
|
||||
// profile_end()
|
||||
|
||||
@ -391,10 +371,10 @@ render_screen_ui :: proc()
|
||||
|
||||
// profile_begin("rl.DrawRectangleRoundedLines: padding & content")
|
||||
if debug.draw_UI_padding_bounds && equal_range2(computed.content, computed.padding) {
|
||||
draw_rectangle_lines( rect_padding, current, Color_Debug_UI_Padding_Bounds, line_thickness )
|
||||
draw_rectangle_lines( rect_padding, & current, Color_Debug_UI_Padding_Bounds, line_thickness )
|
||||
}
|
||||
else if debug.draw_ui_content_bounds {
|
||||
draw_rectangle_lines( rect_content, current, Color_Debug_UI_Content_Bounds, line_thickness )
|
||||
draw_rectangle_lines( rect_content, & current, Color_Debug_UI_Content_Bounds, line_thickness )
|
||||
}
|
||||
// profile_end()
|
||||
|
||||
@ -415,7 +395,7 @@ render_screen_ui :: proc()
|
||||
// profile_end()
|
||||
|
||||
if len(current.text.str) > 0 && style.font.key != 0 {
|
||||
draw_text_screenspace( current.text, screen_to_render_pos(computed.text_pos), layout.font_size, style.text_color )
|
||||
draw_text_screenspace( current.text, screen_to_render_pos(computed.text_pos), current.font_size, style.text_color )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +200,6 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
ui_screen_tick()
|
||||
|
||||
//region WorkspaceImgui Tick
|
||||
if false
|
||||
{
|
||||
profile("Workspace Imgui")
|
||||
|
||||
@ -241,7 +240,7 @@ update :: proc( delta_time : f64 ) -> b32
|
||||
// test_draggable()
|
||||
// test_text_box()
|
||||
// test_parenting( & default_layout, & frame_style_default )
|
||||
// test_whitespace_ast( & default_layout, & frame_style_default )
|
||||
test_whitespace_ast( & default_layout, & frame_style_default )
|
||||
}
|
||||
//endregion Workspace Imgui Tick
|
||||
|
||||
|
@ -88,7 +88,7 @@ UI_Layout :: struct {
|
||||
alignment : Vec2,
|
||||
text_alignment : Vec2,
|
||||
|
||||
font_size : f32,
|
||||
font_size : UI_Scalar,
|
||||
|
||||
margins : UI_LayoutSide,
|
||||
padding : UI_LayoutSide,
|
||||
@ -104,8 +104,6 @@ UI_Layout :: struct {
|
||||
// (We can union either varient and just know based on checking if its the screenspace UI)
|
||||
// If the box is a child of the root parent, its automatically in world space and thus will use the tile_pos.
|
||||
// tile_pos : WS_Pos,
|
||||
|
||||
transition_time : f32,
|
||||
}
|
||||
|
||||
UI_LayoutCombo :: struct #raw_union {
|
||||
|
@ -4,15 +4,11 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
|
||||
ancestors_layout_required : b32 = false,
|
||||
root_layout_required : b32 = false )
|
||||
{
|
||||
profile("Layout Box")
|
||||
// profile("Layout Box")
|
||||
state := get_state()
|
||||
ui := state.ui_context
|
||||
|
||||
parent := box.parent
|
||||
// TODO(Ed): Add support to premmtively compute ancestor's layouts
|
||||
// if parent != ui.root && ! parent.computed.fresh {
|
||||
// ui_box_compute_layout( parent )
|
||||
// }
|
||||
|
||||
style := box.style
|
||||
layout := & box.layout
|
||||
@ -22,14 +18,14 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
|
||||
// The parent's unadjusted content bounds however are enforced for position,
|
||||
// they cannot be ignored. The user may bypass them by doing the
|
||||
// relative offset math vs world/screen space if they desire.
|
||||
fixed_pos_x : f32 = cast(f32) int(.Fixed_Position_X in layout.flags)
|
||||
fixed_pos_y : f32 = cast(f32) int(.Fixed_Position_Y in layout.flags)
|
||||
fixed_width : f32 = cast(f32) int(.Fixed_Width in layout.flags)
|
||||
fixed_height : f32 = cast(f32) int(.Fixed_Height in layout.flags)
|
||||
// fixed_pos_x : f32 = cast(f32) int(.Fixed_Position_X in layout.flags)
|
||||
// fixed_pos_y : f32 = cast(f32) int(.Fixed_Position_Y in layout.flags)
|
||||
// fixed_width : f32 = cast(f32) int(.Fixed_Width in layout.flags)
|
||||
// fixed_height : f32 = cast(f32) int(.Fixed_Height in layout.flags)
|
||||
|
||||
size_to_text : bool = .Size_To_Text in layout.flags
|
||||
|
||||
computed := & box.computed
|
||||
computed := & box.computed
|
||||
|
||||
parent_content := parent.computed.content
|
||||
parent_content_size := parent_content.max - parent_content.min
|
||||
@ -148,9 +144,7 @@ ui_box_compute_layout :: proc( box : ^UI_Box,
|
||||
bounds.max - { layout.padding.right, layout.padding.top } - border_offset,
|
||||
)
|
||||
|
||||
// computed.anchors = anchored_bounds
|
||||
// computed.margins = margined_bounds
|
||||
computed.bounds = bounds
|
||||
computed.bounds = bounds
|
||||
computed.padding = padding_bounds
|
||||
computed.content = content_bounds
|
||||
|
||||
@ -197,7 +191,15 @@ ui_compute_layout :: proc( ui : ^UI_State )
|
||||
|
||||
for current := root.first; current != nil; current = ui_box_tranverse_next( current )
|
||||
{
|
||||
if current.computed.fresh do continue
|
||||
ui_box_compute_layout( current )
|
||||
if ! current.computed.fresh {
|
||||
ui_box_compute_layout( current )
|
||||
}
|
||||
array_append( & ui.render_queue, UI_RenderBoxInfo {
|
||||
current.computed,
|
||||
current.style,
|
||||
current.text,
|
||||
current.layout.font_size,
|
||||
current.layout.border_width,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,12 @@ UI_Signal :: struct {
|
||||
keyboard_clicked : b8,
|
||||
|
||||
active : b8,
|
||||
was_active : b8,
|
||||
hot : b8,
|
||||
disabled : b8,
|
||||
|
||||
was_active : b8,
|
||||
was_hot : b8,
|
||||
was_disabled : b8,
|
||||
|
||||
pressed : b8,
|
||||
released : b8,
|
||||
@ -205,7 +210,6 @@ ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas
|
||||
if is_hot
|
||||
{
|
||||
if ! was_hot {
|
||||
box.prev_style = box.style
|
||||
box.style_delta = 0
|
||||
}
|
||||
box.layout = ui_layout_peek().hot
|
||||
@ -214,7 +218,6 @@ ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas
|
||||
if is_active
|
||||
{
|
||||
if ! was_active {
|
||||
box.prev_style = box.style
|
||||
box.style_delta = 0
|
||||
}
|
||||
box.layout = ui_layout_peek().active
|
||||
@ -223,7 +226,6 @@ ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas
|
||||
if is_disabled
|
||||
{
|
||||
if ! was_disabled {
|
||||
box.prev_style = box.style
|
||||
box.style_delta = 0
|
||||
}
|
||||
box.layout = ui_layout_peek().disabled
|
||||
@ -232,7 +234,6 @@ ui_signal_from_box :: proc ( box : ^ UI_Box, update_style := true, update_deltas
|
||||
|
||||
if ! is_disabled && ! is_active && ! is_hot {
|
||||
if was_disabled || was_active || was_hot {
|
||||
box.prev_style = box.style
|
||||
box.style_delta = 0
|
||||
}
|
||||
else {
|
||||
|
@ -37,10 +37,6 @@ UI_Style :: struct {
|
||||
|
||||
// TODO(Ed) : Support setting the cursor state
|
||||
cursor : UI_Cursor,
|
||||
|
||||
// Used with style, prev_style, and style_delta to produce a simple interpolated animation
|
||||
// Applied in the layout pass & the rendering pass for their associated fields.
|
||||
transition_time : f32,
|
||||
}
|
||||
|
||||
UI_StyleCombo :: struct #raw_union {
|
||||
|
@ -91,6 +91,14 @@ UI_InteractState :: struct {
|
||||
|
||||
UI_Key :: distinct u64
|
||||
|
||||
UI_RenderBoxInfo :: struct {
|
||||
using computed : UI_Computed,
|
||||
using style : UI_Style,
|
||||
text : StrRunesPair,
|
||||
font_size : UI_Scalar,
|
||||
border_width : UI_Scalar,
|
||||
}
|
||||
|
||||
UI_Scalar :: f32
|
||||
|
||||
UI_ScalarConstraint :: struct {
|
||||
@ -119,20 +127,15 @@ UI_Box :: struct {
|
||||
flags : UI_BoxFlags,
|
||||
computed : UI_Computed,
|
||||
|
||||
// TODO(Ed): Move prev_layout out, this is no longer managed by the core UI, its managed by w/e is constructing the graph
|
||||
prev_layout : UI_Layout,
|
||||
layout : UI_Layout,
|
||||
|
||||
// TODO(Ed): Move prev_style out, this is no longer managed by the core UI, its managed by w/e is constructing the graph
|
||||
prev_style : UI_Style,
|
||||
style : UI_Style,
|
||||
layout : UI_Layout,
|
||||
style : UI_Style,
|
||||
|
||||
// Persistent Data
|
||||
first_frame : b8, // TODO(Ed): Move to end if keeping as b8
|
||||
hot_delta : f32,
|
||||
active_delta : f32,
|
||||
disabled_delta : f32,
|
||||
style_delta : f32,
|
||||
first_frame : b8,
|
||||
// root_order_id : i16,
|
||||
|
||||
// prev_computed : UI_Computed,
|
||||
@ -146,7 +149,7 @@ UI_Layout_Stack_Size :: 512
|
||||
UI_Style_Stack_Size :: 512
|
||||
UI_Parent_Stack_Size :: 512
|
||||
// UI_Built_Boxes_Array_Size :: 8
|
||||
UI_Built_Boxes_Array_Size :: 16 * Kilobyte
|
||||
UI_Built_Boxes_Array_Size :: 128 * Kilobyte
|
||||
|
||||
UI_State :: struct {
|
||||
// TODO(Ed) : Use these
|
||||
@ -159,6 +162,8 @@ UI_State :: struct {
|
||||
prev_cache : ^HMapZPL( UI_Box ),
|
||||
curr_cache : ^HMapZPL( UI_Box ),
|
||||
|
||||
render_queue : Array(UI_RenderBoxInfo),
|
||||
|
||||
null_box : ^UI_Box, // This was used with the Linked list interface...
|
||||
// TODO(Ed): Should we change our convention for null boxes to use the above and nil as an invalid state?
|
||||
root : ^UI_Box,
|
||||
@ -205,6 +210,10 @@ ui_startup :: proc( ui : ^ UI_State, cache_allocator : Allocator /* , cache_rese
|
||||
ui.curr_cache = (& ui.caches[1])
|
||||
ui.prev_cache = (& ui.caches[0])
|
||||
|
||||
allocation_error : AllocatorError
|
||||
ui.render_queue, allocation_error = array_init_reserve( UI_RenderBoxInfo, cache_allocator, UI_Built_Boxes_Array_Size, fixed_cap = true )
|
||||
verify( allocation_error == AllocatorError.None, "Failed to allocate render queue" )
|
||||
|
||||
log("ui_startup completed")
|
||||
}
|
||||
|
||||
@ -365,6 +374,8 @@ ui_graph_build_begin :: proc( ui : ^ UI_State, bounds : Vec2 = {} )
|
||||
get_state().ui_context = ui
|
||||
using get_state().ui_context
|
||||
|
||||
array_clear( render_queue )
|
||||
|
||||
temp := prev_cache
|
||||
prev_cache = curr_cache
|
||||
curr_cache = temp
|
||||
|
Reference in New Issue
Block a user