medfall

A super great game engine
Log | Files | Refs

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 }