Misc changes (refactors, notes)
This commit is contained in:
parent
03500acb9a
commit
489faf5515
@ -154,17 +154,15 @@ eval_point_on_bezier4 :: proc( p0, p1, p2, p3 : Vec2, alpha : f32 ) -> Vec2
|
||||
}
|
||||
|
||||
screenspace_x_form :: proc( position, scale : ^Vec2, width, height : f32 ) {
|
||||
scale.x = (scale.x / width ) * 2.0
|
||||
scale.y = (scale.y / height) * 2.0
|
||||
position.x = position.x * (2.0 / width) - 1.0
|
||||
position.y = position.y * (2.0 / height) - 1.0
|
||||
quotient := 1.0 / Vec2 { width, height }
|
||||
(position^) = (position^) * quotient * 2.0 - 1.0
|
||||
(scale^) = (scale^) * quotient * 2.0
|
||||
}
|
||||
|
||||
textspace_x_form :: proc( position, scale : ^Vec2, width, height : f32 ) {
|
||||
position.x /= width
|
||||
position.y /= height
|
||||
scale.x /= width
|
||||
scale.y /= height
|
||||
quotient := 1.0 / Vec2 { width, height }
|
||||
(position^) *= quotient
|
||||
(scale^) *= quotient
|
||||
}
|
||||
|
||||
InitAtlasRegionParams :: struct {
|
||||
|
@ -310,14 +310,3 @@ array_block_size :: proc "contextless" ( self : Array( $Type ) ) -> u64 {
|
||||
block_size := cast(u64) (header_size + self.capacity * size_of(Type))
|
||||
return block_size
|
||||
}
|
||||
|
||||
array_memtracker_entry :: proc( self : Array( $Type ), name : string ) -> MemoryTrackerEntry {
|
||||
header_size :: size_of(ArrayHeader(Type))
|
||||
block_size := cast(uintptr) (header_size + (cast(uintptr) self.capacity) * size_of(Type))
|
||||
|
||||
block_start := transmute(^u8) self.header
|
||||
block_end := ptr_offset( block_start, block_size )
|
||||
|
||||
tracker_entry := MemoryTrackerEntry { name, block_start, block_end }
|
||||
return tracker_entry
|
||||
}
|
||||
|
1
code/grime/growing_sub_arena.odin
Normal file
1
code/grime/growing_sub_arena.odin
Normal file
@ -0,0 +1 @@
|
||||
package grime
|
@ -21,27 +21,6 @@ push_back_slice_queue :: proc( self : ^$QueueType / Queue($Type), slice : []Type
|
||||
{
|
||||
queue.push_back_elems( self, ..slice )
|
||||
return
|
||||
|
||||
// num := cast(uint) len(slice)
|
||||
|
||||
// if uint( space_left( self^ )) < num {
|
||||
// error = queue._grow( self, self.len + num )
|
||||
// if error != .None do return
|
||||
// }
|
||||
|
||||
// size := uint(len(self.data))
|
||||
// insert_from := (self.offset + self.len) % size
|
||||
// insert_to := num
|
||||
|
||||
// if insert_from + insert_to > size {
|
||||
// insert_to = size - insert_from
|
||||
// }
|
||||
|
||||
// copy( self.data[ insert_from : ], slice[ : insert_to ])
|
||||
// copy( self.data[ : insert_from ], slice[ insert_to : ])
|
||||
|
||||
// self.len += num
|
||||
// return
|
||||
}
|
||||
|
||||
QueueIterator :: struct( $Type : typeid ) {
|
||||
|
@ -64,6 +64,8 @@ str_cache_init :: proc( table_allocator, slabs_allocator : Allocator ) -> (cache
|
||||
|
||||
@static dbg_name := "StringCache slab"
|
||||
|
||||
// TODO(Ed): Is this nessary (essentially is there a perf impact of using vs not using, which is better because thats all that matters)
|
||||
// Interning should only be handled on a growing arena anyway so it doesn't really need this.
|
||||
alloc_error : AllocatorError
|
||||
cache.slab, alloc_error = slab_init( & policy, allocator = slabs_allocator, dbg_name = dbg_name )
|
||||
verify(alloc_error == .None, "Failed to initialize the string cache" )
|
||||
|
@ -123,16 +123,40 @@ setup_memory :: proc( profiler : ^SpallProfiler ) -> ClientMemory
|
||||
// Setup the static arena for the entire application
|
||||
{
|
||||
alloc_error : AllocatorError
|
||||
persistent, alloc_error = varena_init( sectr.Memory_Base_Address_Persistent, sectr.Memory_Reserve_Persistent, sectr.Memory_Commit_Initial_Persistent, nil, dbg_name = "persistent" )
|
||||
persistent, alloc_error = varena_init(
|
||||
sectr.Memory_Base_Address_Persistent,
|
||||
sectr.Memory_Reserve_Persistent,
|
||||
sectr.Memory_Commit_Initial_Persistent,
|
||||
growth_policy = nil,
|
||||
allow_any_resize = false,
|
||||
dbg_name = "persistent" )
|
||||
verify( alloc_error == .None, "Failed to allocate persistent virtual arena for the sectr module")
|
||||
|
||||
frame, alloc_error = varena_init( sectr.Memory_Base_Address_Frame, sectr.Memory_Reserve_Frame, sectr.Memory_Commit_Initial_Frame, nil, allow_any_reize = true, dbg_name = "frame" )
|
||||
frame, alloc_error = varena_init(
|
||||
sectr.Memory_Base_Address_Frame,
|
||||
sectr.Memory_Reserve_Frame,
|
||||
sectr.Memory_Commit_Initial_Frame,
|
||||
growth_policy = nil,
|
||||
allow_any_resize = true,
|
||||
dbg_name = "frame" )
|
||||
verify( alloc_error == .None, "Failed to allocate frame virtual arena for the sectr module")
|
||||
|
||||
transient, alloc_error = varena_init( sectr.Memory_Base_Address_Transient, sectr.Memory_Reserve_Transient, sectr.Memory_Commit_Initial_Transient, nil, allow_any_reize = true, dbg_name = "transient" )
|
||||
transient, alloc_error = varena_init(
|
||||
sectr.Memory_Base_Address_Transient,
|
||||
sectr.Memory_Reserve_Transient,
|
||||
sectr.Memory_Commit_Initial_Transient,
|
||||
growth_policy = nil,
|
||||
allow_any_resize = true,
|
||||
dbg_name = "transient" )
|
||||
verify( alloc_error == .None, "Failed to allocate transient virtual arena for the sectr module")
|
||||
|
||||
files_buffer, alloc_error = varena_init( sectr.Memory_Base_Address_Files_Buffer, sectr.Memory_Reserve_FilesBuffer, sectr.Memory_Commit_Initial_Filebuffer, nil, dbg_name = "files_buffer" )
|
||||
files_buffer, alloc_error = varena_init(
|
||||
sectr.Memory_Base_Address_Files_Buffer,
|
||||
sectr.Memory_Reserve_FilesBuffer,
|
||||
sectr.Memory_Commit_Initial_Filebuffer,
|
||||
growth_policy = nil,
|
||||
allow_any_resize = true,
|
||||
dbg_name = "files_buffer" )
|
||||
verify( alloc_error == .None, "Failed to allocate files buffer virtual arena for the sectr module")
|
||||
}
|
||||
|
||||
@ -149,8 +173,8 @@ setup_memory :: proc( profiler : ^SpallProfiler ) -> ClientMemory
|
||||
file_resize( snapshot_file, sectr.Memory_Chunk_Size )
|
||||
}
|
||||
}
|
||||
map_error : MapFileError
|
||||
map_flags : MapFileFlags = { MapFileFlag.Read, MapFileFlag.Write }
|
||||
map_error : MapFileError
|
||||
map_flags : MapFileFlags = { MapFileFlag.Read, MapFileFlag.Write }
|
||||
sectr_snapshot, map_error = virtual.map_file_from_file_descriptor( uintptr(snapshot_file), map_flags )
|
||||
verify( map_error == MapFileError.None, "Failed to allocate snapshot memory for the sectr module" )
|
||||
file_close(snapshot_file)
|
||||
@ -250,7 +274,7 @@ sync_sectr_api :: proc( sectr_api : ^sectr.ModuleAPI, memory : ^ClientMemory, lo
|
||||
|
||||
fmt_backing : [16 * Kilobyte] u8
|
||||
|
||||
persistent_backing : [2 * Megabyte] byte
|
||||
persistent_backing : [2 * Megabyte] byte
|
||||
transient_backing : [32 * Megabyte] byte
|
||||
|
||||
main :: proc()
|
||||
|
@ -1,169 +0,0 @@
|
||||
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,
|
||||
}
|
||||
|
||||
// TODO(Ed) : Review this and put into space.odin when ready
|
||||
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()
|
||||
{
|
||||
Bindings :: sokol_gfx.Bindings
|
||||
Range :: sokol_gfx.Range
|
||||
ShaderStage :: sokol_gfx.Shader_Stage
|
||||
|
||||
state := get_state(); using state
|
||||
using render_data
|
||||
|
||||
do_nothing : bool
|
||||
do_nothing = false
|
||||
|
||||
// apply_bindings :: sokol_gfx.apply_bindings
|
||||
|
||||
// Clear Demo
|
||||
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
|
||||
|
||||
sokol_gfx.begin_pass( sokol_gfx.Pass {
|
||||
action = debug.gfx_clear_demo_pass_action,
|
||||
swapchain = sokol_glue.swapchain()
|
||||
})
|
||||
sokol_gfx.end_pass()
|
||||
sokol_gfx.commit()
|
||||
}
|
||||
|
||||
// Triangle Demo
|
||||
if false
|
||||
{
|
||||
using debug.gfx_tri_demo_state
|
||||
sokol_gfx.begin_pass(sokol_gfx.Pass { action = pass_action, swapchain = sokol_glue.swapchain() })
|
||||
sokol_gfx.apply_pipeline( pipeline )
|
||||
sokol_gfx.apply_bindings( bindings )
|
||||
|
||||
sokol_gfx.draw( 0, 3, 1 )
|
||||
|
||||
sokol_gfx.end_pass()
|
||||
sokol_gfx.commit()
|
||||
}
|
||||
|
||||
// learnopengl.com/In-Practice/Text-Rendering
|
||||
when true
|
||||
{
|
||||
profile("learngl_text_render_pass")
|
||||
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( ShaderStage.VS, SLOT_font_glyph_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 = 0.5
|
||||
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]Vec2 = {
|
||||
{ pos.x, pos.y + height },
|
||||
{ pos.x, pos.y },
|
||||
{ pos.x + width, pos.y },
|
||||
|
||||
{ pos.x, pos.y + height },
|
||||
{ pos.x + width, pos.y },
|
||||
{ pos.x + width, pos.y + height }
|
||||
}
|
||||
|
||||
uv_coords : [6]Vec2 = {
|
||||
0 = { 0.0, 0.0 },
|
||||
1 = { 0.0, 1.0 },
|
||||
2 = { 1.0, 1.0 },
|
||||
|
||||
3 = { 0.0, 0.0 },
|
||||
4 = { 1.0, 1.0 },
|
||||
5 = { 1.0, 0.0 },
|
||||
}
|
||||
|
||||
color : Vec3 = { 1.0, 1.0, 1.0 }
|
||||
fs_uniform := Font_Glyph_Fs_Params {
|
||||
glyph_color = color
|
||||
}
|
||||
sokol_gfx.apply_uniforms( sokol_gfx.Shader_Stage.FS, SLOT_font_glyph_fs_params, Range{ & fs_uniform, size_of(fs_uniform) })
|
||||
|
||||
vbuf_offset := sokol_gfx.append_buffer( gfx_v_buffer, { & vertices[0], size_of(vertices) })
|
||||
// sokol_gfx.update_buffer( gfx_uv_buffer, { & uv_coords[0], size_of(uv_coords) })
|
||||
|
||||
bindings := Bindings {
|
||||
vertex_buffers = {
|
||||
ATTR_font_glyph_vs_vertex = gfx_v_buffer,
|
||||
ATTR_font_glyph_vs_texture_coord = gfx_uv_buffer,
|
||||
},
|
||||
vertex_buffer_offsets = {
|
||||
ATTR_font_glyph_vs_vertex = vbuf_offset,
|
||||
ATTR_font_glyph_vs_texture_coord = 0,
|
||||
},
|
||||
fs = {
|
||||
images = { SLOT_glyph_bitmap = glyph.texture },
|
||||
samplers = { SLOT_glyph_bitmap_sampler = gfx_sampler }
|
||||
},
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
@ -97,7 +97,7 @@ sokol_app_log_callback :: proc "c" (
|
||||
logf( "%-80s %s::%v", cloned_msg, cloned_tag, line_nr, level = odin_level )
|
||||
}
|
||||
|
||||
// TODO(Ed): This needs to queue to a job stask for a event callback handling thread to deal with.
|
||||
// TODO(Ed): Does this need to be queued to a separate thread?
|
||||
sokol_app_event_callback :: proc "c" (sokol_event : ^sokol_app.Event)
|
||||
{
|
||||
state := get_state(); using state
|
||||
|
@ -119,7 +119,7 @@ render_mode_screenspace :: proc()
|
||||
content := str_fmt_buffer( draw_text_scratch[:], format, ..args )
|
||||
debug_draw_text( content, position, 12.0 )
|
||||
|
||||
debug.draw_debug_text_y += 14
|
||||
debug.draw_debug_text_y += 12
|
||||
}
|
||||
|
||||
debug.debug_text_vis = true
|
||||
|
@ -1,3 +0,0 @@
|
||||
package sectr
|
||||
|
||||
import fstash "codebase:font/fontstash"
|
@ -1,319 +0,0 @@
|
||||
package sectr
|
||||
|
||||
import "core:os"
|
||||
import "core:strings"
|
||||
import "core:unicode"
|
||||
import sokol_gfx "thirdparty:sokol/gfx"
|
||||
import "thirdparty:freetype"
|
||||
|
||||
Font_Provider_Use_Freetype :: true
|
||||
|
||||
Font_Largest_Px_Size :: 32
|
||||
|
||||
Font_Size_Interval :: 2
|
||||
|
||||
// Font_Default :: ""
|
||||
Font_Default :: FontID { 0, "" }
|
||||
Font_Default_Point_Size :: 18.0
|
||||
|
||||
Font_TTF_Default_Chars_Padding :: 4
|
||||
|
||||
Font_Load_Use_Default_Size :: -1
|
||||
Font_Load_Gen_ID :: ""
|
||||
|
||||
FontID :: struct {
|
||||
key : u64,
|
||||
label : string,
|
||||
}
|
||||
FontTag :: struct {
|
||||
key : FontID,
|
||||
point_size : f32
|
||||
}
|
||||
|
||||
when Font_Provider_Use_Freetype
|
||||
{
|
||||
FontParserFontData :: struct {
|
||||
using face : freetype.Face,
|
||||
}
|
||||
FontParserData :: struct {
|
||||
lib : freetype.Library,
|
||||
}
|
||||
}
|
||||
|
||||
FontGlyph :: struct {
|
||||
size : Vec2i,
|
||||
bearing : Vec2i,
|
||||
advance : u32,
|
||||
texture : sokol_gfx.Image,
|
||||
}
|
||||
|
||||
FontDef :: struct {
|
||||
path_file : string,
|
||||
parser_info : FontParserFontData,
|
||||
glyphs : [256]FontGlyph,
|
||||
}
|
||||
|
||||
FontProviderData :: struct {
|
||||
font_cache : HMapChained(FontDef),
|
||||
parser : FontParserData,
|
||||
glyph_shader : sokol_gfx.Shader,
|
||||
gfx_bindings : sokol_gfx.Bindings,
|
||||
gfx_pipeline : sokol_gfx.Pipeline,
|
||||
gfx_v_buffer : sokol_gfx.Buffer,
|
||||
gfx_uv_buffer : sokol_gfx.Buffer,
|
||||
gfx_sampler : sokol_gfx.Sampler,
|
||||
}
|
||||
|
||||
Font_Quad_Vert_Size :: size_of(Vec2) * 6
|
||||
Font_Provider_Gfx_vBuffer_Size :: Font_Quad_Vert_Size * Kilo * 64
|
||||
|
||||
font_provider_startup :: proc()
|
||||
{
|
||||
profile(#procedure)
|
||||
state := get_state()
|
||||
font_provider_data := & get_state().font_provider_data; using font_provider_data
|
||||
|
||||
font_cache_alloc_error : AllocatorError
|
||||
font_cache, font_cache_alloc_error = make( HMapChained(FontDef), hmap_closest_prime(1 * Kilo), persistent_allocator() /*dbg_name = "font_cache"*/ )
|
||||
verify( font_cache_alloc_error == AllocatorError.None, "Failed to allocate font_cache" )
|
||||
|
||||
log("font_cache created")
|
||||
|
||||
when Font_Provider_Use_Freetype
|
||||
{
|
||||
result := freetype.init_free_type( & font_provider_data.parser.lib )
|
||||
if result != freetype.Error.Ok {
|
||||
fatal( "font_provider_setup: Failed to initialize freetype" )
|
||||
}
|
||||
}
|
||||
|
||||
// Setup Graphics Pipeline
|
||||
{
|
||||
BlendFactor :: sokol_gfx.Blend_Factor
|
||||
BlendOp :: sokol_gfx.Blend_Op
|
||||
BlendState :: sokol_gfx.Blend_State
|
||||
BorderColor :: sokol_gfx.Border_Color
|
||||
BufferDesciption :: sokol_gfx.Buffer_Desc
|
||||
BufferUsage :: sokol_gfx.Usage
|
||||
BufferType :: sokol_gfx.Buffer_Type
|
||||
ColorTargetState :: sokol_gfx.Color_Target_State
|
||||
Filter :: sokol_gfx.Filter
|
||||
Range :: sokol_gfx.Range
|
||||
SamplerDescription :: sokol_gfx.Sampler_Desc
|
||||
Wrap :: sokol_gfx.Wrap
|
||||
VertexAttributeState :: sokol_gfx.Vertex_Attr_State
|
||||
VertexBufferLayoutState :: sokol_gfx.Vertex_Buffer_Layout_State
|
||||
VertexIndexType :: sokol_gfx.Index_Type
|
||||
VertexFormat :: sokol_gfx.Vertex_Format
|
||||
VertexLayoutState :: sokol_gfx.Vertex_Layout_State
|
||||
VertexStep :: sokol_gfx.Vertex_Step
|
||||
|
||||
using font_provider_data
|
||||
backend := sokol_gfx.query_backend()
|
||||
|
||||
glyph_shader = sokol_gfx.make_shader(font_glyph_shader_desc(backend))
|
||||
|
||||
// Glyphs append to a large vertex buffer that must be able to hold all verts per frame, the budget is fixed.
|
||||
// TODO(Ed): Add a way to relase and remake the buffer when an overflow is detected for a frame.
|
||||
gfx_v_buffer = sokol_gfx.make_buffer( BufferDesciption {
|
||||
size = Font_Provider_Gfx_vBuffer_Size,
|
||||
usage = BufferUsage.DYNAMIC,
|
||||
type = BufferType.VERTEXBUFFER,
|
||||
})
|
||||
verify( sokol_gfx.query_buffer_state(gfx_v_buffer) != sokol_gfx.Resource_State.INVALID,
|
||||
"Failed to make font provider's gfx_v_buffer" )
|
||||
|
||||
uv_coords : [6]Vec2 = {
|
||||
0 = { 0.0, 0.0 },
|
||||
1 = { 0.0, 1.0 },
|
||||
2 = { 1.0, 1.0 },
|
||||
|
||||
3 = { 0.0, 0.0 },
|
||||
4 = { 1.0, 1.0 },
|
||||
5 = { 1.0, 0.0 },
|
||||
}
|
||||
|
||||
// All quads will use the same vertex buffer for texture coordinates.
|
||||
gfx_uv_buffer = sokol_gfx.make_buffer( BufferDesciption {
|
||||
size = 0,
|
||||
usage = BufferUsage.IMMUTABLE,
|
||||
type = BufferType.VERTEXBUFFER,
|
||||
data = Range { & uv_coords[0], size_of(uv_coords) },
|
||||
})
|
||||
verify( sokol_gfx.query_buffer_state(gfx_uv_buffer) != sokol_gfx.Resource_State.INVALID,
|
||||
"Failed to make font provider's gfx_uv_buffer" )
|
||||
|
||||
|
||||
gfx_sampler = sokol_gfx.make_sampler( SamplerDescription {
|
||||
min_filter = Filter.NEAREST,
|
||||
mag_filter = Filter.NEAREST,
|
||||
mipmap_filter = Filter.NONE,
|
||||
wrap_u = Wrap.CLAMP_TO_EDGE,
|
||||
wrap_v = Wrap.CLAMP_TO_EDGE,
|
||||
border_color = BorderColor.OPAQUE_BLACK,
|
||||
})
|
||||
|
||||
glyph_vs_layout : VertexLayoutState
|
||||
{
|
||||
using glyph_vs_layout
|
||||
attrs[ATTR_font_glyph_vs_vertex] = VertexAttributeState {
|
||||
format = VertexFormat.FLOAT2,
|
||||
offset = 0,
|
||||
buffer_index = ATTR_font_glyph_vs_vertex,
|
||||
}
|
||||
buffers[ATTR_font_glyph_vs_vertex] = VertexBufferLayoutState {
|
||||
stride = size_of(Vec2),
|
||||
step_func = VertexStep.PER_VERTEX,
|
||||
}
|
||||
|
||||
attrs[ATTR_font_glyph_vs_texture_coord] = VertexAttributeState {
|
||||
format = VertexFormat.FLOAT2,
|
||||
offset = 0,
|
||||
buffer_index = ATTR_font_glyph_vs_texture_coord,
|
||||
}
|
||||
buffers[ATTR_font_glyph_vs_texture_coord] = VertexBufferLayoutState {
|
||||
stride = size_of(Vec2),
|
||||
step_func = VertexStep.PER_VERTEX,
|
||||
}
|
||||
}
|
||||
|
||||
gfx_pipeline = sokol_gfx.make_pipeline(
|
||||
{
|
||||
shader = glyph_shader,
|
||||
layout = glyph_vs_layout,
|
||||
index_type = VertexIndexType.NONE,
|
||||
colors = {
|
||||
0 = ColorTargetState \
|
||||
{
|
||||
blend = BlendState {
|
||||
enabled = true,
|
||||
src_factor_rgb = BlendFactor.SRC_ALPHA,
|
||||
dst_factor_rgb = BlendFactor.ONE_MINUS_SRC_ALPHA,
|
||||
op_rgb = BlendOp.ADD,
|
||||
src_factor_alpha = BlendFactor.ONE,
|
||||
dst_factor_alpha = BlendFactor.ZERO,
|
||||
op_alpha = BlendOp.ADD,
|
||||
}
|
||||
},
|
||||
},
|
||||
color_count = 1,
|
||||
sample_count = 1,
|
||||
})
|
||||
}
|
||||
|
||||
log("font_provider initialized")
|
||||
}
|
||||
|
||||
font_provider_reload :: proc()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
font_provider_shutdown :: proc()
|
||||
{
|
||||
font_provider_data := & get_state().font_provider_data; using font_provider_data
|
||||
for & entry in font_cache.lookup
|
||||
{
|
||||
if entry == nil do continue
|
||||
def := entry.value
|
||||
|
||||
// TODO(Ed): Free entry resources.
|
||||
}
|
||||
}
|
||||
|
||||
when Font_Provider_Use_Freetype
|
||||
{
|
||||
font_load :: proc(path_file : string,
|
||||
default_size : f32 = Font_Load_Use_Default_Size,
|
||||
desired_id : string = Font_Load_Gen_ID
|
||||
) -> FontID
|
||||
{
|
||||
profile(#procedure)
|
||||
|
||||
logf("Loading font: %v", path_file)
|
||||
font_provider_data := & get_state().font_provider_data; using font_provider_data
|
||||
|
||||
font_data, read_succeded : = os.read_entire_file( path_file )
|
||||
verify( b32(read_succeded), str_fmt("Failed to read font file for: %v", path_file) )
|
||||
font_data_size := cast(i32) len(font_data)
|
||||
|
||||
desired_id := desired_id
|
||||
// Use file name as key
|
||||
if len(desired_id) == 0 {
|
||||
// NOTE(Ed): This should never be used except for laziness so I'll be throwing a warning everytime.
|
||||
log("desired_key not provided, using file name. Give it a proper name!", LogLevel.Warning)
|
||||
// desired_id = cast(FontID) file_name_from_path(path_file)
|
||||
desired_id = file_name_from_path(path_file)
|
||||
}
|
||||
|
||||
key := cast(u64) crc32( transmute([]byte) desired_id )
|
||||
def, set_error := hmap_chained_set(font_cache, key, FontDef{})
|
||||
verify( set_error == AllocatorError.None, "Failed to add new font entry to cache" )
|
||||
|
||||
def.path_file = path_file
|
||||
|
||||
face_index :: 0
|
||||
freetype.new_memory_face( font_provider_data.parser.lib, raw_data(font_data), font_data_size, face_index, & def.parser_info.face )
|
||||
|
||||
// Hardcoding to 24 pt for testing (until we have a proper cached atlas)
|
||||
freetype.set_pixel_sizes( def.parser_info.face, 0, 72 )
|
||||
|
||||
for ascii_code in 0 ..< 128
|
||||
{
|
||||
load_error := freetype.load_char(def.parser_info.face, u32(ascii_code), {freetype.Load_Flag.Render})
|
||||
verify( load_error == .Ok, "Failed to load character using freetype" )
|
||||
|
||||
// using def.parser_info
|
||||
using def
|
||||
// glyph := parser_info.face.glyph
|
||||
// bitmap := & glyph.bitmap
|
||||
using parser_info.face.glyph
|
||||
|
||||
codepoint := rune(ascii_code)
|
||||
if ! unicode.is_print(codepoint) || bitmap.width <= 0 do continue
|
||||
|
||||
ImageDescription :: sokol_gfx.Image_Desc
|
||||
ImageUsage :: sokol_gfx.Usage
|
||||
Range :: sokol_gfx.Range
|
||||
PixelFormat :: sokol_gfx.Pixel_Format
|
||||
|
||||
glyph_data : sokol_gfx.Image_Data
|
||||
glyph_data.subimage[0][0] = Range { bitmap.buffer, u64(bitmap.width * bitmap.rows) }
|
||||
|
||||
desc := sokol_gfx.Image_Desc {
|
||||
type = sokol_gfx.Image_Type._2D,
|
||||
render_target = false,
|
||||
width = i32(bitmap.width),
|
||||
height = i32(bitmap.rows),
|
||||
num_slices = 1,
|
||||
num_mipmaps = 1,
|
||||
usage = ImageUsage.IMMUTABLE,
|
||||
pixel_format = PixelFormat.R8,
|
||||
sample_count = 0,
|
||||
data = glyph_data,
|
||||
label = strings.clone_to_cstring(str_fmt("font_ascii %v", ascii_code))
|
||||
}
|
||||
|
||||
// width := i32(bitmap.width)
|
||||
// rows := i32(bitmap.rows)
|
||||
// logf("font_ascii : %v", ascii_code )
|
||||
// logf("font_ascii glyph: %v", rune(ascii_code) )
|
||||
|
||||
sokol_img := sokol_gfx.make_image( desc )
|
||||
verify( sokol_gfx.query_image_state(sokol_img) != sokol_gfx.Resource_State.INVALID,
|
||||
"Failed to create image on sokol gfx" );
|
||||
|
||||
def.glyphs[ascii_code] = FontGlyph {
|
||||
size = { i32(bitmap.width), i32(bitmap.rows) },
|
||||
bearing = { bitmap_left, bitmap_top },
|
||||
texture = sokol_img,
|
||||
advance = u32(advance.x),
|
||||
}
|
||||
}
|
||||
|
||||
freetype.done_face( def.parser_info.face )
|
||||
|
||||
fid := FontID { key, desired_id }
|
||||
return fid
|
||||
}
|
||||
}
|
@ -191,6 +191,9 @@ poll_input_events :: proc( input, prev_input : ^InputState, input_events : Input
|
||||
input.mouse.btns[id].ended_down = prev_btn.ended_down
|
||||
}
|
||||
|
||||
input.mouse.raw_pos = prev_input.mouse.raw_pos
|
||||
input.mouse.pos = prev_input.mouse.pos
|
||||
|
||||
input_events := input_events
|
||||
using input_events
|
||||
|
||||
@ -266,11 +269,12 @@ poll_input_events :: proc( input, prev_input : ^InputState, input_events : Input
|
||||
case .Mouse_Move:
|
||||
case .Mouse_Enter:
|
||||
case .Mouse_Leave:
|
||||
// Handled elsewhere
|
||||
// Handled below
|
||||
}
|
||||
|
||||
input.mouse.pos = event.pos
|
||||
input.mouse.delta = event.delta
|
||||
input.mouse.raw_pos = event.pos
|
||||
input.mouse.pos = render_to_screen_pos( event.pos )
|
||||
input.mouse.delta = event.delta
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ PWS_LineArray_ReserveSize :: 32 * Kilobyte
|
||||
PWS_ParseResult :: struct {
|
||||
content : string,
|
||||
tokens : Array(PWS_Token),
|
||||
nodes : Array(PWS_AST), // Nodes should be dumped in a pool.
|
||||
nodes : Array(PWS_AST), // Nodes should be dumped in a pool?
|
||||
lines : Array( ^PWS_AST),
|
||||
errors : [PWS_ParseError_Max] PWS_ParseError,
|
||||
}
|
||||
|
@ -32,26 +32,6 @@ Side :: enum i32 {
|
||||
// Count,
|
||||
// }
|
||||
|
||||
// UI_AnchorPresets :: enum u32 {
|
||||
// Top_Left,
|
||||
// Top_Right,
|
||||
// Bottom_Right,
|
||||
// Bottom_Left,
|
||||
// Center_Left,
|
||||
// Center_Top,
|
||||
// Center_Right,
|
||||
// Center_Bottom,
|
||||
// Center,
|
||||
// Left_Wide,
|
||||
// Top_Wide,
|
||||
// Right_Wide,
|
||||
// Bottom_Wide,
|
||||
// VCenter_Wide,
|
||||
// HCenter_Wide,
|
||||
// Full,
|
||||
// Count,
|
||||
// }
|
||||
|
||||
UI_Cursor :: struct {
|
||||
placeholder : int,
|
||||
}
|
||||
@ -78,7 +58,6 @@ UI_ScalarConstraint :: struct {
|
||||
|
||||
UI_Scalar2 :: [Axis2.Count]UI_Scalar
|
||||
|
||||
|
||||
// UI_BoxFlags_Stack_Size :: 512
|
||||
UI_Layout_Stack_Size :: 512
|
||||
UI_Style_Stack_Size :: 512
|
||||
@ -88,7 +67,7 @@ UI_Built_Boxes_Array_Size :: 128 * Kilobyte
|
||||
|
||||
// TODO(Ed): Rename to UI_Context
|
||||
UI_State :: struct {
|
||||
// TODO(Ed) : Use these
|
||||
// TODO(Ed) : Use these?
|
||||
// build_arenas : [2]Arena,
|
||||
// build_arena : ^ Arena,
|
||||
|
||||
|
@ -3,6 +3,25 @@ package sectr
|
||||
import "core:math"
|
||||
import "core:math/linalg"
|
||||
|
||||
// UI_AnchorPresets :: enum u32 {
|
||||
// Top_Left,
|
||||
// Top_Right,
|
||||
// Bottom_Right,
|
||||
// Bottom_Left,
|
||||
// Center_Left,
|
||||
// Center_Top,
|
||||
// Center_Right,
|
||||
// Center_Bottom,
|
||||
// Center,
|
||||
// Left_Wide,
|
||||
// Top_Wide,
|
||||
// Right_Wide,
|
||||
// Bottom_Wide,
|
||||
// VCenter_Wide,
|
||||
// HCenter_Wide,
|
||||
// Full,
|
||||
// Count,
|
||||
// }
|
||||
|
||||
// Anchor_
|
||||
|
||||
@ -16,7 +35,6 @@ LayoutAlign_OriginTL_Bottom :: Vec2{0.5, 1}
|
||||
LayoutAlign_OriginTL_BottomLeft :: Vec2{ 0, 1}
|
||||
LayoutAlign_OriginTL_BottomRight :: Vec2{ 1, 1}
|
||||
|
||||
|
||||
Layout_OriginCenter_Centered :: Vec2{0.5, 0.5}
|
||||
|
||||
UI_Align_Presets_Struct :: struct {
|
||||
|
Loading…
Reference in New Issue
Block a user