reduced shader bind code dupe & adjust skate uprighter strenght
[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 {
45 int end=0;
46 u32 row_h = world_sfd.h -1 -row;
47
48 for( int i=0; i<world_sfd.w; i++ ){
49 u32 idx = (world_sfd.w*row_h + i) * 2;
50
51 if( end ){
52 world_sfd.buffer[idx] = 0.0f;
53 }
54 else{
55 if( !str[i] )
56 end = 1;
57
58 world_sfd.buffer[idx] = sfd_encode_glyph( str[i] );
59 }
60 }
61 }
62
63 static void world_sfd_update( world_instance *world, v3f pos ){
64 if( mdl_arrcount( &world->ent_route ) ){
65 u32 closest = 0;
66 float min_dist = INFINITY;
67
68 for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i++ ){
69 ent_route *route = mdl_arritm( &world->ent_route, i );
70 float dist = v3_dist2( route->board_transform[3], pos );
71
72 if( dist < min_dist ){
73 min_dist = dist;
74 closest = i;
75 }
76 }
77
78 if( (world_sfd.active_route_board != closest) || network_scores_updated ){
79 network_scores_updated = 0;
80 world_sfd.active_route_board = closest;
81
82 ent_route *route = mdl_arritm( &world->ent_route, closest );
83 u32 id = route->anon.official_track_id;
84
85 if( id != 0xffffffff ){
86 struct netmsg_board *local_board =
87 &scoreboard_client_data.boards[id];
88
89 for( int i=0; i<13; i++ ){
90 sfd_encode( i, &local_board->data[27*i] );
91 }
92 }else{
93 sfd_encode( 0, mdl_pstr( &world->meta, route->pstr_name ) );
94 sfd_encode( 1, "No data" );
95 }
96 }
97 }
98
99 for( int i=0; i<world_sfd.w*world_sfd.h; i++ ){
100 float *target = &world_sfd.buffer[i*2+0],
101 *cur = &world_sfd.buffer[i*2+1];
102
103 float const rate = vg.time_delta * 15.2313131414f;
104 float d1 = *target-*cur;
105
106 if( fabsf(d1) > rate ){
107 *cur += rate;
108 if( *cur > 60.0f )
109 *cur -= 60.0f;
110 }
111 else
112 *cur = *target;
113 }
114 }
115
116 static void bind_terrain_noise(void);
117 static void sfd_render( world_instance *world, camera *cam, m4x3f transform ){
118 mesh_bind( &world_sfd.mesh_display );
119 shader_scene_scoretext_use();
120 shader_scene_scoretext_uTexMain(1);
121 WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_scoretext );
122
123 bind_terrain_noise();
124
125 glActiveTexture( GL_TEXTURE1 );
126 glBindTexture( GL_TEXTURE_2D, world_sfd.tex_scoretex );
127
128 m4x4f pvm_prev;
129 m4x3_expand( transform, pvm_prev );
130 m4x4_mul( cam->mtx_prev.pv, pvm_prev, pvm_prev );
131
132 shader_scene_scoretext_uPv( cam->mtx.pv );
133 shader_scene_scoretext_uPvmPrev( pvm_prev );
134 shader_scene_scoretext_uMdl( transform );
135 shader_scene_scoretext_uCamera( cam->transform[3] );
136
137 for( int y=0;y<world_sfd.h; y++ ){
138 for( int x=0; x<world_sfd.w; x++ ){
139 float value = world_sfd.buffer[(y*world_sfd.w+x)*2+1];
140 shader_scene_scoretext_uInfo( (v3f){ x,y, value } );
141 mesh_draw( &world_sfd.mesh_display );
142 }
143 }
144
145 shader_scene_vertex_blend_use();
146 shader_scene_vertex_blend_uTexGarbage(0);
147 shader_scene_vertex_blend_uTexGradients(1);
148 WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, scene_vertex_blend );
149
150 bind_terrain_noise();
151 glActiveTexture( GL_TEXTURE1 );
152 glBindTexture( GL_TEXTURE_2D, world_sfd.tex_scoretex );
153
154 shader_scene_vertex_blend_uPv( cam->mtx.pv );
155 shader_scene_vertex_blend_uPvmPrev( pvm_prev );
156 shader_scene_vertex_blend_uMdl( transform );
157 shader_scene_vertex_blend_uCamera( cam->transform[3] );
158
159 mesh_bind( &world_sfd.mesh_base );
160 mdl_draw_submesh( &world_sfd.sm_base );
161 }
162
163 static int world_sfd_test( int argc, const char *argv[] ){
164 if( argc == 2 ){
165 int row = vg_min( vg_max(atoi(argv[0]),0), world_sfd.h);
166 sfd_encode( row, argv[1] );
167 }
168
169 return 0;
170 }
171
172 static void world_sfd_init(void){
173 vg_info( "world_sfd_init\n" );
174 shader_scene_scoretext_register();
175 vg_console_reg_cmd( "sfd", world_sfd_test, NULL );
176
177 vg_linear_clear( vg_mem.scratch );
178
179 mdl_context mscoreboard;
180 mdl_open( &mscoreboard, "models/rs_scoretext.mdl", vg_mem.scratch );
181 mdl_load_metadata_block( &mscoreboard, vg_mem.scratch );
182 mdl_async_load_glmesh( &mscoreboard, &world_sfd.mesh_base );
183
184 mdl_load_mesh_block( &mscoreboard, vg_mem.scratch );
185
186 scene_context *scene = &world_sfd.scene;
187 vg_async_item *call = scene_alloc_async( scene, &world_sfd.mesh_display,
188 3000, 8000 );
189
190
191 mdl_mesh *m_backer = mdl_find_mesh( &mscoreboard, "backer" ),
192 *m_card = mdl_find_mesh( &mscoreboard, "score_card" );
193
194 mdl_submesh
195 *sm_backer = mdl_arritm( &mscoreboard.submeshs, m_backer->submesh_start ),
196 *sm_card = mdl_arritm( &mscoreboard.submeshs, m_card->submesh_start );
197 world_sfd.sm_base = *sm_backer;
198
199 m4x3f identity;
200 m4x3_identity( identity );
201
202 for( int i=0;i<4;i++ ){
203 u32 vert_start = scene->vertex_count;
204 scene_add_mdl_submesh( scene, &mscoreboard, sm_card, identity );
205
206 for( int j=0; j<sm_card->vertex_count; j++ ){
207 scene_vert *vert = &scene->arrvertices[ vert_start+j ];
208
209 float const k_glyph_uvw = 1.0f/64.0f;
210 vert->uv[0] -= k_glyph_uvw * (float)(i-1);
211 vert->norm[3] = i*42;
212 }
213 }
214
215 vg_async_dispatch( call, async_scene_upload );
216 vg_tex2d_load_qoi_async_file( "textures/scoretext.qoi",
217 VG_TEX2D_CLAMP|VG_TEX2D_NEAREST,
218 &world_sfd.tex_scoretex );
219
220 mdl_close( &mscoreboard );
221
222 int w = 27,
223 h = 13;
224
225 world_sfd.w = w;
226 world_sfd.h = h;
227 world_sfd.buffer = vg_linear_alloc( vg_mem.rtmemory, 2*w*h*sizeof(float) );
228
229 for( int i=0; i<w*h*2; i++ )
230 world_sfd.buffer[i] = 0.0f;
231 }
232
233 #endif /* WORLD_SFD_C */