+++ /dev/null
-#pragma once
-#include "model.h"
-#include "entity.h"
-#include "vg/vg_camera.h"
-#include "shaders/model_font.h"
-#include "shaders/scene_font.h"
-#include "world_render.h"
-#include "depth_compare.h"
-
-enum efont_SRglyph{
- k_SRglyph_end = 0x00, /* control characters */
- k_SRglyph_ctrl_variant = 0x01,
- k_SRglyph_ctrl_size = 0x02, /* normalized 0-1 */
- k_SRglyph_ctrl_center = 0x03, /* useful when text is scaled down */
- k_SRglyph_ctrl_baseline = 0x04, /* . */
- k_SRglyph_ctrl_top = 0x05, /* . */
- k_SRglyph_mod_circle = 0x1e, /* surround and center next charater */
- k_SRglyph_mod_square = 0x1f, /* surround and center next character */
- k_SRglyph_ascii_min = 0x20, /* standard ascii */
- k_SRglyph_ascii_max = 0x7e,
- k_SRglyph_ps4_square = 0x7f,/* playstation buttons */
- k_SRglyph_ps4_triangle = 0x80,
- k_SRglyph_ps4_circle = 0x81,
- k_SRglyph_ps4_cross = 0x82,
- k_SRglyph_xb1_x = 0x83,/* xbox buttons */
- k_SRglyph_xb1_y = 0x84,
- k_SRglyph_xb1_a = 0x85,
- k_SRglyph_xb1_b = 0x86,
- k_SRglyph_gen_ls = 0x87,/* generic gamepad */
- k_SRglyph_gen_lsh = 0x88,
- k_SRglyph_gen_lsv = 0x89,
- k_SRglyph_gen_lshv = 0x8a,
- k_SRglyph_gen_rs = 0x8b,
- k_SRglyph_gen_rsh = 0x8c,
- k_SRglyph_gen_rsv = 0x8d,
- k_SRglyph_gen_rshv = 0x8e,
- k_SRglyph_gen_lt = 0x8f,
- k_SRglyph_gen_rt = 0x90,
- k_SRglyph_gen_lb = 0x91,
- k_SRglyph_gen_rb = 0x92,
- k_SRglyph_gen_left = 0x93,
- k_SRglyph_gen_up = 0x94,
- k_SRglyph_gen_right = 0x95,
- k_SRglyph_gen_down = 0x96,
- k_SRglyph_gen_options = 0x97,
- k_SRglyph_gen_shareview = 0x98,
- k_SRglyph_kbm_m0 = 0x99,/* mouse */
- k_SRglyph_kbm_m1 = 0x9a,
- k_SRglyph_kbm_m01 = 0x9b,
- k_SRglyph_kbm_m2 = 0x9c,
- k_SRglyph_kbm_m2s = 0x9d,
- k_SRglyph_kbm_shift = 0x9e,/* modifiers */
- k_SRglyph_kbm_ctrl = 0x9f,
- k_SRglyph_kbm_alt = 0xa0,
- k_SRglyph_kbm_space = 0xa1,
- k_SRglyph_kbm_return = 0xa2,
- k_SRglyph_kbm_escape = 0xa3,
- k_SRglyph_kbm_mousemove = 0xa4,
- k_SRglyph_vg_ret = 0xa5,
- k_SRglyph_vg_link = 0xa6,
- k_SRglyph_vg_square = 0xa7,
- k_SRglyph_vg_triangle = 0xa8,
- k_SRglyph_vg_circle = 0xa9
-};
-
-typedef struct font3d font3d;
-struct font3d{
- mdl_context mdl;
- GLuint texture;
- glmesh mesh;
-
- ent_font info;
- mdl_array_ptr font_variants,
- glyphs;
-};
-
-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 );
-
- if( !mdl_arrcount( &font->mdl.textures ) )
- vg_fatal_error( "No texture in font file" );
-
- mdl_texture *tex0 = mdl_arritm( &font->mdl.textures, 0 );
- void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
- mdl_fread_pack_file( &font->mdl, &tex0->file, data );
-
- mdl_async_load_glmesh( &font->mdl, &font->mesh, NULL );
- vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
- VG_TEX2D_LINEAR|VG_TEX2D_CLAMP,
- &font->texture );
-
- mdl_close( &font->mdl );
-}
-
-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;
-}
-
-struct _font3d_render{
- v4f offset;
- font3d *font;
- u32 variant_id;
-
- enum font_shader {
- k_font_shader_default,
- k_font_shader_world
- }
- shader;
-}
-static gui_font3d;
-
-/*
- * world can be null if not using world shader
- */
-static void font3d_bind( font3d *font, enum font_shader shader,
- int depth_compare, world_instance *world,
- vg_camera *cam ){
- gui_font3d.shader = shader;
- gui_font3d.font = font;
- glActiveTexture( GL_TEXTURE1 );
- glBindTexture( GL_TEXTURE_2D, font->texture );
-
- if( shader == k_font_shader_default )
- {
- shader_model_font_use();
- shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
- shader_model_font_uTexMain( 1 );
- shader_model_font_uDepthMode( depth_compare );
-
- if( depth_compare ){
- depth_compare_bind(
- shader_model_font_uTexSceneDepth,
- shader_model_font_uInverseRatioDepth,
- shader_model_font_uInverseRatioMain, cam );
- }
-
- shader_model_font_uPv( cam->mtx.pv );
- }
- else if( shader == k_font_shader_world )
- {
- shader_scene_font_use();
- shader_scene_font_uTexGarbage(0);
- shader_scene_font_uTexMain(1);
-
- shader_scene_font_uPv( skaterift.cam.mtx.pv );
- shader_scene_font_uTime( vg.time );
-
- WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_font );
-
- bind_terrain_noise();
- shader_scene_font_uCamera( skaterift.cam.transform[3] );
- }
- mesh_bind( &font->mesh );
-}
-
-static ent_glyph *font3d_glyph( font3d *font, u32 variant_id, u32 utf32 ){
- if( utf32 < font->info.glyph_utf32_base ) return NULL;
- if( utf32 >= font->info.glyph_utf32_base+font->info.glyph_count) return NULL;
-
- u32 index = utf32 - font->info.glyph_utf32_base;
- index += font->info.glyph_start;
- index += font->info.glyph_count * variant_id;
- return mdl_arritm( &font->glyphs, index );
-}
-
-static void font3d_set_transform( const char *text,
- vg_camera *cam, m4x3f transform ){
- v4_copy( (v4f){0.0f,0.0f,0.0f,1.0f}, gui_font3d.offset );
-
- m4x4f prev_mtx;
- m4x3_expand( transform, prev_mtx );
- m4x4_mul( cam->mtx_prev.pv, prev_mtx, prev_mtx );
-
- if( gui_font3d.shader == k_font_shader_default ){
- shader_model_font_uPvmPrev( prev_mtx );
- shader_model_font_uMdl( transform );
- }
- else if( gui_font3d.shader == k_font_shader_world ){
- shader_scene_font_uPvmPrev( prev_mtx );
- shader_scene_font_uMdl( transform );
- }
-}
-
-static void font3d_setoffset( v4f offset ){
- if( gui_font3d.shader == k_font_shader_default )
- shader_model_font_uOffset( offset );
- else if( gui_font3d.shader == k_font_shader_world )
- shader_scene_font_uOffset( offset );
-}
-
-static void font3d_setcolour( v4f colour ){
- if( gui_font3d.shader == k_font_shader_default )
- shader_model_font_uColour( colour );
-#if 0
- else if( gui_font3d.shader == k_font_shader_world )
- shader_scene_font_uColour( colour );
-#endif
-}
-
-static void font3d_draw( const char *text ){
- u8 *u8pch = (u8*)text;
-
- u32 max_chars = 512;
- while( u8pch && max_chars ){
- max_chars --;
-
- u32 c0 = *u8pch, c1;
- u8pch ++;
-
- if( !c0 ) break;
-
- ent_glyph *glyph0 = font3d_glyph( gui_font3d.font,
- gui_font3d.variant_id, c0 ),
- *glyph1 = NULL;
-
- /* multibyte characters */
- if( c0 >= 1 && c0 < k_SRglyph_ascii_min ){
- c1 = *u8pch;
- if( !c1 ) break;
- glyph1 = font3d_glyph( gui_font3d.font, gui_font3d.variant_id, c1 );
- }
-
- if( c0 == k_SRglyph_ctrl_variant ){
- gui_font3d.variant_id = c1;
- u8pch ++;
- continue;
- }
- else if( c0 == k_SRglyph_ctrl_size ){
- gui_font3d.offset[3] = (float)c1 * (1.0f/255.0f);
- u8pch ++;
- continue;
- }
- else if( c0 == k_SRglyph_ctrl_baseline ){
- gui_font3d.offset[1] = 0.0f;
- continue;
- }
- else if( c0 == k_SRglyph_ctrl_center ){
- if( glyph1 ){
- float diff = glyph1->size[1] - glyph1->size[1]*gui_font3d.offset[3];
- gui_font3d.offset[1] = diff * 0.5f;
- }
- continue;
- }
- else if( c0 == k_SRglyph_ctrl_top ){
- if( glyph1 ){
- float diff = glyph1->size[1] - glyph1->size[1]*gui_font3d.offset[3];
- gui_font3d.offset[1] = diff;
- }
- continue;
- }
-
- if( !glyph0 ) continue;
-
- if( glyph1 && (c0 == k_SRglyph_mod_square || c0 == k_SRglyph_mod_circle)){
- v4f v0;
- v2_sub( glyph0->size, glyph1->size, v0 );
- v2_muladds( gui_font3d.offset, v0, -0.5f, v0 );
- v0[2] = gui_font3d.offset[2];
- v0[3] = gui_font3d.offset[3];
-
- font3d_setoffset( v0 );
- mesh_drawn( glyph0->indice_start, glyph0->indice_count );
- continue;
- }
- else{
- font3d_setoffset( gui_font3d.offset );
- mesh_drawn( glyph0->indice_start, glyph0->indice_count );
- }
-
- gui_font3d.offset[0] += glyph0->size[0]*gui_font3d.offset[3];
- }
-}
-
-static f32 font3d_simple_draw( u32 variant_id, const char *text,
- vg_camera *cam, m4x3f transform ){
- if( !text ) return 0.0f;
-
- gui_font3d.variant_id = variant_id;
- font3d_set_transform( text, cam, transform );
- font3d_draw( text );
- return gui_font3d.offset[0];
-}
-
-static f32 font3d_string_width( u32 variant_id, const char *text ){
- if( !text ) return 0.0f;
- float width = 0.0f;
-
- const u8 *buf = (const u8 *)text;
- for( int i=0;; i++ ){
- u32 c = buf[i];
- if(!c) break;
-
- ent_glyph *glyph = font3d_glyph( gui_font3d.font, variant_id, c );
- if( !glyph ) continue;
-
- width += glyph->size[0];
- }
-
- return width;
-}