msdf.cc (4008B)
1 #include "game.h" 2 #include "intrinsics.h" 3 #include "linear_algebra.h" 4 #include "gl.h" 5 #include "renderer.h" 6 #include "shaders.h" 7 #include "immediate.h" 8 #include "log.h" 9 #include "obj.h" 10 11 #include "bitmap_font_desc.c" 12 13 #include "liberation.h" 14 #include "libs/stb/stb_truetype.h" 15 16 static Texture atlas; 17 static stbtt_fontinfo font_info; 18 19 GAME_INIT( game_init ) { 20 atlas = load_png( "msdf.png", TEXFMT_RGB_U8, 3 ); 21 22 u8 * ttf = file_get_contents( "Montserrat-Bold.ttf" ); 23 int offset = stbtt_GetFontOffsetForIndex( ttf, 0 ); 24 int ok = stbtt_InitFont( &font_info, ttf, offset ); 25 ASSERT( ok != 0 ); 26 } 27 28 v3 to_clip( v2 v ) { 29 v2u32 ws = get_window_size(); 30 v2 clip = v2( v.x / ws.x, v.y / ws.y ) * 2.0f - 1.0f; 31 return v3( clip.x, clip.y, 0 ); 32 } 33 34 static v2 glyph_bounds( u8 glyph, float scale ) { 35 return v2(); 36 } 37 38 static void msdf_text( u8 pass, const char * str, int x, int y, float scale ) { 39 const v4 white( 1, 1, 1, 1 ); 40 41 float height = font_information.max_y - font_information.min_y; 42 scale /= height; 43 44 float pad = font_information.glyph_padding; 45 46 v2u32 ws = get_window_size(); 47 float left = float( x ); 48 float top = ws.y - y - font_information.max_y * scale; 49 50 while( *str != '\0' ) { 51 // todo: way too much padding, should be 2 or 3px to allow for antialiasing/border 52 const bitmap_glyph & glyph = font_codepoint_infos[ u8( *str ) ]; 53 // printf( "%c: %f\n", *str, glyph.advance ); 54 55 ImmediateVertex tl = { 56 to_clip( v2( left + scale * ( glyph.minx - pad ), top + scale * ( glyph.miny - pad ) ) ), 57 v3( 0 ), 58 white, 59 v2( ( glyph.atlas_x + 0.5f ) / 1024.0f, 1.0f - ( glyph.atlas_y + 0.5f ) / 512.0f ), 60 }; 61 ImmediateVertex tr = { 62 to_clip( v2( left + scale * ( glyph.maxx + pad ), top + scale * ( glyph.miny - pad ) ) ), 63 v3( 0 ), 64 white, 65 v2( ( glyph.atlas_x + glyph.atlas_w + 0.5f ) / 1024.0f, 1.0f - ( glyph.atlas_y + 0.5f ) / 512.0f ), 66 }; 67 ImmediateVertex bl = { 68 to_clip( v2( left + scale * ( glyph.minx - pad ), top + scale * ( glyph.maxy + pad ) ) ), 69 v3( 0 ), 70 white, 71 v2( ( glyph.atlas_x + 0.5f ) / 1024.0f, 1.0f - ( glyph.atlas_y + glyph.atlas_h + 0.5f ) / 512.0f ), 72 }; 73 ImmediateVertex br = { 74 to_clip( v2( left + scale * ( glyph.maxx + pad ), top + scale * ( glyph.maxy + pad ) ) ), 75 v3( 0 ), 76 white, 77 v2( ( glyph.atlas_x + glyph.atlas_w + 0.5f ) / 1024.0f, 1.0f - ( glyph.atlas_y + glyph.atlas_h + 0.5f ) / 512.0f ), 78 }; 79 80 immediate_triangle( tr, bl, tl ); 81 immediate_triangle( bl, tr, br ); 82 83 left += glyph.advance * scale; 84 if( str[ 1 ] != '\0' ) { 85 int kern = stbtt_GetCodepointKernAdvance( &font_info, str[ 0 ], str[ 1 ] ); 86 // left += kern / 24.0f; 87 } 88 89 str++; 90 } 91 92 RenderState render_state; 93 render_state.pass = pass; 94 render_state.shader = get_shader( SHADER_MSDF ); 95 render_state.set_texture( "atlas", atlas ); 96 render_state.depth_func = DEPTHFUNC_DISABLED; 97 render_state.enable_alpha_blending = true; 98 render_state.disable_depth_writes = true; 99 100 immediate_render( render_state ); 101 } 102 103 float lol = 0.5; 104 105 GAME_FRAME( game_frame ) { 106 RenderPass pass; 107 pass.name = "Render frame"; 108 pass.clear_colour = true; 109 pass.colour = v4( 0.1, 0.1, 0.1, 0 ); 110 111 if( input->keys[ KEY_MINUS ] ) 112 lol -= 0.1 * dt; 113 if( input->keys[ KEY_EQUALS ] ) 114 lol += 0.1 * dt; 115 116 renderer_begin_frame(); 117 118 u8 main_pass = renderer_add_pass( pass ); 119 120 { 121 // for( int i = 0; i < 8; i++ ) { 122 // msdf_text( "DEFEND COCAINE DIESEL AVA Ty fr fi \xc4\xe4\xc5\xe5\xdf", 2, i * 30, i / 2.45f ); 123 // } 124 // 125 // float scale = sinf( current_time ) + 2.0; 126 // msdf_text( "COCAINE DIESEL", 2, -50, scale ); 127 // 128 // msdf_text( "Couldn't execute: autoexec_postinit.cfg", 2, -250 / lol, lol ); 129 130 int y = 0; 131 for( int i = 0; i < 6; i++ ) { 132 y += 2; 133 // msdf_text( "\xc5rt of Respect", 2, y, 16 << i ); 134 float x = 2.0f + 0.015f * ( 16 << i ) * sinf( current_time * 40 + i ); 135 // msdf_text( "\xc5rt of Respect", x, y, 16 << i ); 136 y += 16 << i; 137 } 138 139 msdf_text( main_pass, "Thanks again!", 10, 200, 50 ); 140 } 141 142 renderer_end_frame(); 143 }