commit cb20f91d3b7b9ad57f2829869df738dd03327818
parent ad69870125f9d260a4d667396d469b8662c089ad
Author: Michael Savage <mikejsavage@gmail.com>
Date: Mon, 26 Mar 2018 23:48:33 +0300
stb_truetype font supersampling
Diffstat:
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 );