9310aee6a52e21f54040b1f46a8f559e81010570
[carveJwlIkooP6JGAAIwe30JlM.git] / world_sfd.c
1 #ifndef SFD_C
2 #define SFD_C
3
4 #include "world_sfd.h"
5 #include "shaders/scene_scoretext.h"
6 #include "shaders/scene_vertex_blend.h"
7 #include "network.h"
8 #include "entity.h"
9
10 static f32 sfd_encode_glyph( char c ){
11 int value = 0;
12 if( c >= 'a' && c <= 'z' )
13 value = c-'a'+11;
14 else if( c >= '0' && c <= '9' )
15 value = c-'0'+1;
16 else if( c >= 'A' && c <= 'Z' )
17 value = c-'A'+11;
18 else if( c >= '\x01' && c <= '\x01'+10 )
19 value = 63-c;
20 else{
21 int base = 11+26;
22
23 switch( c ){
24 case '!': value=base+0; break;
25 case '?': value=base+1; break;
26 case ',': value=base+2; break;
27 case '.': value=base+3; break;
28 case '#': value=base+4; break;
29 case '$': value=base+5; break;
30 case '%': value=base+6; break;
31 case '*': value=base+7; break;
32 case '+': value=base+8; break;
33 case '-': value=base+9; break;
34 case '/': value=base+10; break;
35 case ':': value=base+11; break;
36 default: value=0; break;
37 }
38 }
39
40 return (float)value;
41 }
42
43 static void sfd_encode( u32 row, const char *str ){
44 int end=0;
45 u32 row_h = world_sfd.h -1 -row;
46
47 for( int i=0; i<world_sfd.w; i++ ){
48 u32 idx = (world_sfd.w*row_h + i) * 2;
49
50 if( end ){
51 world_sfd.buffer[idx] = 0.0f;
52 }
53 else{
54 if( !str[i] )
55 end = 1;
56
57 world_sfd.buffer[idx] = sfd_encode_glyph( str[i] );
58 }
59 }
60 }
61
62 static void world_sfd_update( world_instance *world, v3f pos ){
63 if( mdl_arrcount( &world->ent_route ) ){
64 u32 closest = 0;
65 float min_dist = INFINITY;
66
67 for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i++ ){
68 ent_route *route = mdl_arritm( &world->ent_route, i );
69 float dist = v3_dist2( route->board_transform[3], pos );
70
71 if( dist < min_dist ){
72 min_dist = dist;
73 closest = i;
74 }
75 }
76
77 if( (world_sfd.active_route_board != closest) || network_scores_updated ){
78 network_scores_updated = 0;
79 world_sfd.active_route_board = closest;
80 ent_route *route = mdl_arritm( &world->ent_route, closest );
81
82 addon_reg *world_reg =
83 world_static.instance_addons[ world_static.active_instance ];
84
85 char mod_uid[ ADDON_UID_MAX ];
86 addon_alias_uid( &world_reg->alias, mod_uid );
87
88 network_request_scoreboard(
89 mod_uid,
90 mdl_pstr( &world->meta, route->pstr_name ),
91 0 );
92 }
93 }
94
95 for( int i=0; i<world_sfd.w*world_sfd.h; i++ ){
96 float *target = &world_sfd.buffer[i*2+0],
97 *cur = &world_sfd.buffer[i*2+1];
98
99 float const rate = vg.time_delta * 15.2313131414f;
100 float d1 = *target-*cur;
101
102 if( fabsf(d1) > rate ){
103 *cur += rate;
104 if( *cur > 60.0f )
105 *cur -= 60.0f;
106 }
107 else
108 *cur = *target;
109 }
110 }
111
112 static void bind_terrain_noise(void);
113 static void sfd_render( world_instance *world, camera *cam, m4x3f transform ){
114 mesh_bind( &world_sfd.mesh_display );
115 shader_scene_scoretext_use();
116 shader_scene_scoretext_uTexMain(1);
117 WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_scoretext );
118
119 bind_terrain_noise();
120
121 glActiveTexture( GL_TEXTURE1 );
122 glBindTexture( GL_TEXTURE_2D, world_sfd.tex_scoretex );
123
124 m4x4f pvm_prev;
125 m4x3_expand( transform, pvm_prev );
126 m4x4_mul( cam->mtx_prev.pv, pvm_prev, pvm_prev );
127
128 shader_scene_scoretext_uPv( cam->mtx.pv );
129 shader_scene_scoretext_uPvmPrev( pvm_prev );
130 shader_scene_scoretext_uMdl( transform );
131 shader_scene_scoretext_uCamera( cam->transform[3] );
132
133 for( int y=0;y<world_sfd.h; y++ ){
134 for( int x=0; x<world_sfd.w; x++ ){
135 float value = world_sfd.buffer[(y*world_sfd.w+x)*2+1];
136 shader_scene_scoretext_uInfo( (v3f){ x,y, value } );
137 mesh_draw( &world_sfd.mesh_display );
138 }
139 }
140
141 shader_scene_vertex_blend_use();
142 shader_scene_vertex_blend_uTexGarbage(0);
143 shader_scene_vertex_blend_uTexGradients(1);
144 WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_vertex_blend );
145
146 bind_terrain_noise();
147 glActiveTexture( GL_TEXTURE1 );
148 glBindTexture( GL_TEXTURE_2D, world_sfd.tex_scoretex );
149
150 shader_scene_vertex_blend_uPv( cam->mtx.pv );
151 shader_scene_vertex_blend_uPvmPrev( pvm_prev );
152 shader_scene_vertex_blend_uMdl( transform );
153 shader_scene_vertex_blend_uCamera( cam->transform[3] );
154
155 mesh_bind( &world_sfd.mesh_base );
156 mdl_draw_submesh( &world_sfd.sm_base );
157 }
158
159 static int world_sfd_test( int argc, const char *argv[] ){
160 if( argc == 2 ){
161 int row = vg_min( vg_max(atoi(argv[0]),0), world_sfd.h);
162 sfd_encode( row, argv[1] );
163 }
164
165 return 0;
166 }
167
168 static void world_sfd_init(void){
169 vg_info( "world_sfd_init\n" );
170 shader_scene_scoretext_register();
171 vg_console_reg_cmd( "sfd", world_sfd_test, NULL );
172
173 vg_linear_clear( vg_mem.scratch );
174
175 mdl_context mscoreboard;
176 mdl_open( &mscoreboard, "models/rs_scoretext.mdl", vg_mem.scratch );
177 mdl_load_metadata_block( &mscoreboard, vg_mem.scratch );
178 mdl_async_load_glmesh( &mscoreboard, &world_sfd.mesh_base );
179
180 mdl_load_mesh_block( &mscoreboard, vg_mem.scratch );
181
182 scene_context *scene = &world_sfd.scene;
183 vg_async_item *call = scene_alloc_async( scene, &world_sfd.mesh_display,
184 3000, 8000 );
185
186
187 mdl_mesh *m_backer = mdl_find_mesh( &mscoreboard, "backer" ),
188 *m_card = mdl_find_mesh( &mscoreboard, "score_card" );
189
190 mdl_submesh
191 *sm_backer = mdl_arritm( &mscoreboard.submeshs, m_backer->submesh_start ),
192 *sm_card = mdl_arritm( &mscoreboard.submeshs, m_card->submesh_start );
193 world_sfd.sm_base = *sm_backer;
194
195 m4x3f identity;
196 m4x3_identity( identity );
197
198 for( int i=0;i<4;i++ ){
199 u32 vert_start = scene->vertex_count;
200 scene_add_mdl_submesh( scene, &mscoreboard, sm_card, identity );
201
202 for( int j=0; j<sm_card->vertex_count; j++ ){
203 scene_vert *vert = &scene->arrvertices[ vert_start+j ];
204
205 float const k_glyph_uvw = 1.0f/64.0f;
206 vert->uv[0] -= k_glyph_uvw * (float)(i-1);
207 vert->norm[3] = i*42;
208 }
209 }
210
211 vg_async_dispatch( call, async_scene_upload );
212 vg_tex2d_load_qoi_async_file( "textures/scoretext.qoi",
213 VG_TEX2D_CLAMP|VG_TEX2D_NEAREST,
214 &world_sfd.tex_scoretex );
215
216 mdl_close( &mscoreboard );
217
218 int w = 27,
219 h = 13;
220
221 world_sfd.w = w;
222 world_sfd.h = h;
223 world_sfd.buffer = vg_linear_alloc( vg_mem.rtmemory, 2*w*h*sizeof(float) );
224
225 for( int i=0; i<w*h*2; i++ )
226 world_sfd.buffer[i] = 0.0f;
227 }
228
229 #endif /* WORLD_SFD_C */