text3d
[carveJwlIkooP6JGAAIwe30JlM.git] / font.h
diff --git a/font.h b/font.h
new file mode 100644 (file)
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; i<mdl_arrcount( &font->font_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 */