X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=font.h;fp=font.h;h=4c7d8f46f1e09ad0a970bf13d34af0b8b22c6b20;hb=d6171f1c56789b2ca79efa3313fbbf74a13bda7a;hp=0000000000000000000000000000000000000000;hpb=b888cce683d95cc01d0b4be9bbe92a0dd47452ac;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/font.h b/font.h new file mode 100644 index 0000000..4c7d8f4 --- /dev/null +++ b/font.h @@ -0,0 +1,146 @@ +#ifndef FONT_H +#define FONT_H + +#include "model.h" +#include "entity.h" +#include "camera.h" +#include "shaders/model_font.h" + +typedef struct font3d font3d; +struct font3d{ + mdl_context mdl; + GLuint texture; + glmesh mesh; + + ent_font info; + mdl_array_ptr font_variants, + glyphs; +}; + +VG_STATIC void font3d_load( font3d *font, const char *mdl_path, void *alloc ) +{ + mdl_open( &font->mdl, mdl_path, alloc ); + mdl_load_metadata_block( &font->mdl, alloc ); + + vg_linear_clear( vg_mem.scratch ); + mdl_array_ptr fonts; + mdl_load_array( &font->mdl, &fonts, "ent_font", vg_mem.scratch ); + font->info = *((ent_font *)mdl_arritm(&fonts,0)); + + mdl_load_array( &font->mdl, &font->font_variants, "ent_font_variant", alloc); + mdl_load_array( &font->mdl, &font->glyphs, "ent_glyph", alloc ); + + vg_linear_clear( vg_mem.scratch ); + mdl_load_mesh_block( &font->mdl, vg_mem.scratch ); + mdl_load_pack_block( &font->mdl, vg_mem.scratch ); + mdl_close( &font->mdl ); + + vg_acquire_thread_sync(); + { + /* upload mesh */ + mesh_upload( &font->mesh, + font->mdl.verts.data, font->mdl.verts.count, + font->mdl.indices.data, font->mdl.indices.count ); + + /* upload first texture */ + font->texture = vg_tex2d_new(); + mdl_texture *tex0 = mdl_arritm( &font->mdl.textures, 0 ); + + vg_tex2d_set_error(); + vg_tex2d_qoi( mdl_arritm( &font->mdl.pack, tex0->file.pack_offset ), + tex0->file.pack_size, + mdl_pstr( &font->mdl, tex0->file.pstr_path )); + vg_tex2d_nearest(); + vg_tex2d_repeat(); + } + vg_release_thread_sync(); +} + +VG_STATIC void font3d_init(void) +{ + shader_model_font_register(); +} + +VG_STATIC u32 font3d_find_variant( font3d *font, const char *name ) +{ + for( u32 i=0; ifont_variants ); i ++ ){ + ent_font_variant *variant = mdl_arritm( &font->font_variants, i ); + + if( !strcmp( mdl_pstr( &font->mdl, variant->name ), name ) ){ + return i; + } + } + + return 0; +} + +VG_STATIC void font3d_bind( font3d *font, camera *cam ) +{ + shader_model_font_use(); + shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} ); + shader_model_font_uTexMain( 1 ); + glActiveTexture( GL_TEXTURE1 ); + glBindTexture( GL_TEXTURE_2D, font->texture ); + + shader_model_font_uPv( cam->mtx.pv ); + mesh_bind( &font->mesh ); +} + +VG_STATIC +void font3d_simple_draw( font3d *font, u32 variant_id, const char *text, + camera *cam, m4x3f transform ) +{ + v3f offset; + v3_zero( offset ); + + m4x4f prev_mtx; + + m4x3_expand( transform, prev_mtx ); + m4x4_mul( cam->mtx_prev.pv, prev_mtx, prev_mtx ); + + shader_model_font_uPvmPrev( prev_mtx ); + shader_model_font_uMdl( transform ); + + for( int i=0;; i++ ){ + u32 c = text[i]; + if(!c) break; + + if( c < font->info.glyph_utf32_base ) continue; + if( c >= font->info.glyph_utf32_base+font->info.glyph_count) continue; + + u32 index = c - font->info.glyph_utf32_base; + index += font->info.glyph_start; + index += font->info.glyph_count * variant_id; + ent_glyph *glyph = mdl_arritm( &font->glyphs, index ); + + if( glyph->indice_count ){ + shader_model_font_uOffset( offset ); + mesh_drawn( glyph->indice_start, glyph->indice_count ); + } + offset[0] += glyph->size[0]; + } +} + +VG_STATIC +float font3d_string_width( font3d *font, u32 variant_id, const char *text ) +{ + float width = 0.0f; + for( int i=0;; i++ ){ + u32 c = text[i]; + if(!c) break; + + if( c < font->info.glyph_utf32_base ) continue; + if( c >= font->info.glyph_utf32_base+font->info.glyph_count) continue; + + u32 index = c - font->info.glyph_utf32_base; + index += font->info.glyph_start; + index += font->info.glyph_count * variant_id; + ent_glyph *glyph = mdl_arritm( &font->glyphs, index ); + + width += glyph->size[0]; + } + + return width; +} + +#endif /* FONT_H */