medfall

A super great game engine
Log | Files | Refs

commit cb20f91d3b7b9ad57f2829869df738dd03327818
parent ad69870125f9d260a4d667396d469b8662c089ad
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Mon, 26 Mar 2018 23:48:33 +0300

stb_truetype font supersampling

Diffstat:
main.cc | 2+-
text_renderer.cc | 66++++++++++++++++++++++++++++++++++++------------------------------
text_renderer.h | 7+++++--
3 files changed, 42 insertions(+), 33 deletions(-)

diff --git a/main.cc b/main.cc @@ -45,7 +45,7 @@ int main( int argc, char ** argv ) { GLFWwindow * window = gl_init( WINDOW_GAME ); renderer_init(); shaders_init(); - text_renderer_init(); + text_renderer_init( &mem.persistent_arena ); workqueue_init( &state.background_tasks, &mem.persistent_arena, 4 ); game_init( &state, &mem ); diff --git a/text_renderer.cc b/text_renderer.cc @@ -1,4 +1,5 @@ #include "intrinsics.h" +#include "memory_arena.h" #include "immediate.h" #include "gl.h" #include "renderer.h" @@ -11,18 +12,22 @@ struct FontSize { float pixel_size; float ascent; - Texture atlas; - stbtt_bakedchar baked_chars[ 256 ]; + stbtt_packedchar baked_chars[ 256 ]; }; -static stbtt_fontinfo font_info; +constexpr u32 atlas_width = 1024; +constexpr u32 atlas_height = 512; +static Texture atlas; static const float pixel_sizes[] = { 16.0f, 32.0f, 48.0f }; static FontSize sizes[ ARRAY_COUNT( pixel_sizes ) ]; -void text_renderer_init() { - const u8 * ttf = LiberationSans_Regular_ttf; +void text_renderer_init( MemoryArena * arena ) { + MEMARENA_SCOPED_CHECKPOINT( arena ); + u8 * ttf = ( u8 * ) LiberationSans_Regular_ttf; + + stbtt_fontinfo font_info; int offset = stbtt_GetFontOffsetForIndex( ttf, 0 ); { int ok = stbtt_InitFont( &font_info, ttf, offset ); @@ -32,28 +37,35 @@ void text_renderer_init() { int ascent; stbtt_GetFontVMetrics( &font_info, &ascent, NULL, NULL ); - for( size_t i = 0; i < ARRAY_COUNT( sizes ); i++ ) { - const u32 width = 512; - const u32 height = 256; - u8 texture[ width * height ]; - float pixel_size = pixel_sizes[ i ]; + u8 * texture = memarena_push_many( arena, u8, atlas_width * atlas_height ); + stbtt_pack_context pack_context; + int begin_ok = stbtt_PackBegin( &pack_context, texture, atlas_width, atlas_height, 0, 1, NULL ); + if( begin_ok == 0 ) + FATAL( "stbtt_PackBegin" ); - int ok = stbtt_BakeFontBitmap( ttf, offset, pixel_size, texture, width, height, ' ', 127 - ' ', sizes[ i ].baked_chars ); + for( size_t i = 0; i < ARRAY_COUNT( sizes ); i++ ) { + stbtt_PackSetOversampling( &pack_context, 2, 2 ); + int ok = stbtt_PackFontRange( &pack_context, ttf, 0, pixel_sizes[ i ], ' ', 127 - ' ', sizes[ i ].baked_chars ); ASSERT( ok != 0 ); - float scale = stbtt_ScaleForPixelHeight( &font_info, pixel_size ); - - TextureConfig texture_config; - texture_config.width = width; - texture_config.height = height; - texture_config.format = TEXFMT_R_U8; - texture_config.data = texture; - texture_config.data_size = sizeof( texture ); - - sizes[ i ].pixel_size = pixel_size; + float scale = stbtt_ScaleForPixelHeight( &font_info, pixel_sizes[ i ] ); + sizes[ i ].pixel_size = pixel_sizes[ i ]; sizes[ i ].ascent = ascent * scale; - sizes[ i ].atlas = renderer_new_texture( texture_config ); } + + stbtt_PackEnd( &pack_context ); + + TextureConfig texture_config; + texture_config.width = atlas_width; + texture_config.height = atlas_height; + texture_config.format = TEXFMT_R_U8; + texture_config.data = texture; + texture_config.data_size = sizeof( texture ); + atlas = renderer_new_texture( texture_config ); +} + +void text_renderer_term() { + renderer_delete_texture( atlas ); } void draw_text( const char * str, int x, int y, float pixel_size ) { @@ -77,7 +89,7 @@ void draw_text( const char * str, int x, int y, float pixel_size ) { while( *str != '\0' ) { stbtt_aligned_quad q; - stbtt_GetBakedQuad( sizes[ size_idx ].baked_chars, 512, 256, *str - ' ', &fx, &fy, &q, 1 ); + stbtt_GetPackedQuad( sizes[ size_idx ].baked_chars, atlas_width, atlas_height, *str - ' ', &fx, &fy, &q, 0 ); ImmediateVertex tl = { v3( left + scale * ( q.x0 - left ), top + scale * ( q.y0 - y ), 0 ), @@ -112,7 +124,7 @@ void draw_text( const char * str, int x, int y, float pixel_size ) { RenderState render_state; render_state.shader = get_shader( SHADER_TEXT ); - render_state.textures[ 0 ] = sizes[ size_idx ].atlas; + render_state.textures[ 0 ] = atlas; render_state.uniforms[ UNIFORMS_WINDOW ] = renderer_uniforms( get_window_size() ); render_state.depth_func = DEPTHFUNC_DISABLED; render_state.enable_alpha_blending = true; @@ -120,9 +132,3 @@ void draw_text( const char * str, int x, int y, float pixel_size ) { immediate_render( render_state ); } - -void text_renderer_term() { - for( size_t i = 0; i < ARRAY_COUNT( sizes ); i++ ) { - renderer_delete_texture( sizes[ i ].atlas ); - } -} diff --git a/text_renderer.h b/text_renderer.h @@ -1,5 +1,8 @@ #pragma once -void text_renderer_init(); -void draw_text( const char * str, int x, int y, float pixel_size ); +#include "memory_arena.h" + +void text_renderer_init( MemoryArena * arena ); void text_renderer_term(); + +void draw_text( const char * str, int x, int y, float pixel_size );