chaos caused by async
[carveJwlIkooP6JGAAIwe30JlM.git] / font.h
1 #ifndef FONT_H
2 #define FONT_H
3
4 #include "model.h"
5 #include "entity.h"
6 #include "camera.h"
7 #include "shaders/model_font.h"
8
9 typedef struct font3d font3d;
10 struct font3d{
11 mdl_context mdl;
12 GLuint texture;
13 glmesh mesh;
14
15 ent_font info;
16 mdl_array_ptr font_variants,
17 glyphs;
18 };
19
20 VG_STATIC void font3d_load( font3d *font, const char *mdl_path, void *alloc )
21 {
22 mdl_open( &font->mdl, mdl_path, alloc );
23 mdl_load_metadata_block( &font->mdl, alloc );
24
25 vg_linear_clear( vg_mem.scratch );
26 mdl_array_ptr fonts;
27 mdl_load_array( &font->mdl, &fonts, "ent_font", vg_mem.scratch );
28 font->info = *((ent_font *)mdl_arritm(&fonts,0));
29
30 mdl_load_array( &font->mdl, &font->font_variants, "ent_font_variant", alloc);
31 mdl_load_array( &font->mdl, &font->glyphs, "ent_glyph", alloc );
32
33 vg_linear_clear( vg_mem.scratch );
34
35 if( !mdl_arrcount( &font->mdl.textures ) )
36 vg_fatal_error( "No texture in font file" );
37
38 mdl_texture *tex0 = mdl_arritm( &font->mdl.textures, 0 );
39 void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
40 mdl_fread_pack_file( &font->mdl, &tex0->file, data );
41
42 mdl_async_load_glmesh( &font->mdl, &font->mesh );
43 vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
44 VG_TEX2D_NEAREST|VG_TEX2D_REPEAT|VG_TEX2D_NOMIP,
45 &font->texture );
46
47 mdl_close( &font->mdl );
48 }
49
50 VG_STATIC void font3d_init(void)
51 {
52 shader_model_font_register();
53 }
54
55 VG_STATIC u32 font3d_find_variant( font3d *font, const char *name )
56 {
57 for( u32 i=0; i<mdl_arrcount( &font->font_variants ); i ++ ){
58 ent_font_variant *variant = mdl_arritm( &font->font_variants, i );
59
60 if( !strcmp( mdl_pstr( &font->mdl, variant->name ), name ) ){
61 return i;
62 }
63 }
64
65 return 0;
66 }
67
68 VG_STATIC void font3d_bind( font3d *font, camera *cam )
69 {
70 shader_model_font_use();
71 shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
72 shader_model_font_uTexMain( 1 );
73 glActiveTexture( GL_TEXTURE1 );
74 glBindTexture( GL_TEXTURE_2D, font->texture );
75
76 shader_model_font_uPv( cam->mtx.pv );
77 mesh_bind( &font->mesh );
78 }
79
80 VG_STATIC ent_glyph *font3d_glyph( font3d *font, u32 variant_id, u32 utf32 )
81 {
82 if( utf32 < font->info.glyph_utf32_base ) return NULL;
83 if( utf32 >= font->info.glyph_utf32_base+font->info.glyph_count) return NULL;
84
85 u32 index = utf32 - font->info.glyph_utf32_base;
86 index += font->info.glyph_start;
87 index += font->info.glyph_count * variant_id;
88 return mdl_arritm( &font->glyphs, index );
89 }
90
91 VG_STATIC
92 void font3d_simple_draw( font3d *font, u32 variant_id, const char *text,
93 camera *cam, m4x3f transform )
94 {
95 v3f offset;
96 v3_zero( offset );
97
98 m4x4f prev_mtx;
99
100 m4x3_expand( transform, prev_mtx );
101 m4x4_mul( cam->mtx_prev.pv, prev_mtx, prev_mtx );
102
103 shader_model_font_uPvmPrev( prev_mtx );
104 shader_model_font_uMdl( transform );
105
106 for( int i=0;; i++ ){
107 u32 c = text[i];
108 if(!c) break;
109
110 ent_glyph *glyph = font3d_glyph( font, variant_id, c );
111 if( !glyph ) continue;
112
113 if( glyph->indice_count ){
114 shader_model_font_uOffset( offset );
115 mesh_drawn( glyph->indice_start, glyph->indice_count );
116 }
117 offset[0] += glyph->size[0];
118 }
119 }
120
121 VG_STATIC
122 float font3d_string_width( font3d *font, u32 variant_id, const char *text )
123 {
124 float width = 0.0f;
125 for( int i=0;; i++ ){
126 u32 c = text[i];
127 if(!c) break;
128
129 ent_glyph *glyph = font3d_glyph( font, variant_id, c );
130 if( !glyph ) continue;
131
132 width += glyph->size[0];
133 }
134
135 return width;
136 }
137
138 #endif /* FONT_H */