text3d
[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 mdl_load_mesh_block( &font->mdl, vg_mem.scratch );
35 mdl_load_pack_block( &font->mdl, vg_mem.scratch );
36 mdl_close( &font->mdl );
37
38 vg_acquire_thread_sync();
39 {
40 /* upload mesh */
41 mesh_upload( &font->mesh,
42 font->mdl.verts.data, font->mdl.verts.count,
43 font->mdl.indices.data, font->mdl.indices.count );
44
45 /* upload first texture */
46 font->texture = vg_tex2d_new();
47 mdl_texture *tex0 = mdl_arritm( &font->mdl.textures, 0 );
48
49 vg_tex2d_set_error();
50 vg_tex2d_qoi( mdl_arritm( &font->mdl.pack, tex0->file.pack_offset ),
51 tex0->file.pack_size,
52 mdl_pstr( &font->mdl, tex0->file.pstr_path ));
53 vg_tex2d_nearest();
54 vg_tex2d_repeat();
55 }
56 vg_release_thread_sync();
57 }
58
59 VG_STATIC void font3d_init(void)
60 {
61 shader_model_font_register();
62 }
63
64 VG_STATIC u32 font3d_find_variant( font3d *font, const char *name )
65 {
66 for( u32 i=0; i<mdl_arrcount( &font->font_variants ); i ++ ){
67 ent_font_variant *variant = mdl_arritm( &font->font_variants, i );
68
69 if( !strcmp( mdl_pstr( &font->mdl, variant->name ), name ) ){
70 return i;
71 }
72 }
73
74 return 0;
75 }
76
77 VG_STATIC void font3d_bind( font3d *font, camera *cam )
78 {
79 shader_model_font_use();
80 shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
81 shader_model_font_uTexMain( 1 );
82 glActiveTexture( GL_TEXTURE1 );
83 glBindTexture( GL_TEXTURE_2D, font->texture );
84
85 shader_model_font_uPv( cam->mtx.pv );
86 mesh_bind( &font->mesh );
87 }
88
89 VG_STATIC
90 void font3d_simple_draw( font3d *font, u32 variant_id, const char *text,
91 camera *cam, m4x3f transform )
92 {
93 v3f offset;
94 v3_zero( offset );
95
96 m4x4f prev_mtx;
97
98 m4x3_expand( transform, prev_mtx );
99 m4x4_mul( cam->mtx_prev.pv, prev_mtx, prev_mtx );
100
101 shader_model_font_uPvmPrev( prev_mtx );
102 shader_model_font_uMdl( transform );
103
104 for( int i=0;; i++ ){
105 u32 c = text[i];
106 if(!c) break;
107
108 if( c < font->info.glyph_utf32_base ) continue;
109 if( c >= font->info.glyph_utf32_base+font->info.glyph_count) continue;
110
111 u32 index = c - font->info.glyph_utf32_base;
112 index += font->info.glyph_start;
113 index += font->info.glyph_count * variant_id;
114 ent_glyph *glyph = mdl_arritm( &font->glyphs, index );
115
116 if( glyph->indice_count ){
117 shader_model_font_uOffset( offset );
118 mesh_drawn( glyph->indice_start, glyph->indice_count );
119 }
120 offset[0] += glyph->size[0];
121 }
122 }
123
124 VG_STATIC
125 float font3d_string_width( font3d *font, u32 variant_id, const char *text )
126 {
127 float width = 0.0f;
128 for( int i=0;; i++ ){
129 u32 c = text[i];
130 if(!c) break;
131
132 if( c < font->info.glyph_utf32_base ) continue;
133 if( c >= font->info.glyph_utf32_base+font->info.glyph_count) continue;
134
135 u32 index = c - font->info.glyph_utf32_base;
136 index += font->info.glyph_start;
137 index += font->info.glyph_count * variant_id;
138 ent_glyph *glyph = mdl_arritm( &font->glyphs, index );
139
140 width += glyph->size[0];
141 }
142
143 return width;
144 }
145
146 #endif /* FONT_H */