5 #include "shaders/scene_scoretext.h"
6 #include "shaders/scene_vertex_blend.h"
8 static f32
sfd_encode_glyph( char c
)
11 if( c
>= 'a' && c
<= 'z' )
13 else if( c
>= '0' && c
<= '9' )
15 else if( c
>= 'A' && c
<= 'Z' )
17 else if( c
>= '\x01' && c
<= '\x01'+10 )
23 case '!': value
=base
+0; break;
24 case '?': value
=base
+1; break;
25 case ',': value
=base
+2; break;
26 case '.': value
=base
+3; break;
27 case '#': value
=base
+4; break;
28 case '$': value
=base
+5; break;
29 case '%': value
=base
+6; break;
30 case '*': value
=base
+7; break;
31 case '+': value
=base
+8; break;
32 case '-': value
=base
+9; break;
33 case '/': value
=base
+10; break;
34 case ':': value
=base
+11; break;
35 default: value
=0; break;
42 static void sfd_encode( u32 row
, const char *str
)
45 u32 row_h
= world_sfd
.h
-1 -row
;
47 for( int i
=0; i
<world_sfd
.w
; i
++ ){
48 u32 idx
= (world_sfd
.w
*row_h
+ i
) * 2;
51 world_sfd
.buffer
[idx
] = 0.0f
;
57 world_sfd
.buffer
[idx
] = sfd_encode_glyph( str
[i
] );
62 static void world_sfd_update( world_instance
*world
, v3f pos
){
63 if( mdl_arrcount( &world
->ent_route
) ){
65 float min_dist
= INFINITY
;
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
);
71 if( dist
< min_dist
){
77 if( (world_sfd
.active_route_board
!= closest
) || network_scores_updated
)
79 network_scores_updated
= 0;
80 world_sfd
.active_route_board
= closest
;
82 ent_route
*route
= mdl_arritm( &world
->ent_route
, closest
);
83 u32 id
= route
->official_track_id
;
85 if( id
!= 0xffffffff ){
86 struct netmsg_board
*local_board
=
87 &scoreboard_client_data
.boards
[id
];
89 for( int i
=0; i
<13; i
++ ){
90 sfd_encode( i
, &local_board
->data
[27*i
] );
93 sfd_encode( 0, mdl_pstr( &world
->meta
, route
->pstr_name
) );
94 sfd_encode( 1, "No data" );
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];
103 float const rate
= vg
.time_delta
* 15.2313131414f
;
104 float d1
= *target
-*cur
;
106 if( fabsf(d1
) > rate
){
116 static void bind_terrain_noise(void);
117 static void sfd_render( world_instance
*world
, camera
*cam
, m4x3f transform
)
119 mesh_bind( &world_sfd
.mesh_display
);
120 shader_scene_scoretext_use();
121 shader_scene_scoretext_uTexMain(1);
123 world_link_lighting_ub( world
, _shader_scene_scoretext
.id
);
124 world_bind_position_texture( world
, _shader_scene_scoretext
.id
,
125 _uniform_scene_scoretext_g_world_depth
, 2 );
126 world_bind_light_array( world
, _shader_scene_scoretext
.id
,
127 _uniform_scene_scoretext_uLightsArray
, 3 );
128 world_bind_light_index( world
, _shader_scene_scoretext
.id
,
129 _uniform_scene_scoretext_uLightsIndex
, 4 );
131 bind_terrain_noise();
133 glActiveTexture( GL_TEXTURE1
);
134 glBindTexture( GL_TEXTURE_2D
, world_sfd
.tex_scoretex
);
137 m4x3_expand( transform
, pvm_prev
);
138 m4x4_mul( cam
->mtx_prev
.pv
, pvm_prev
, pvm_prev
);
140 shader_scene_scoretext_uPv( cam
->mtx
.pv
);
141 shader_scene_scoretext_uPvmPrev( pvm_prev
);
142 shader_scene_scoretext_uMdl( transform
);
143 shader_scene_scoretext_uCamera( cam
->transform
[3] );
145 for( int y
=0;y
<world_sfd
.h
; y
++ ){
146 for( int x
=0; x
<world_sfd
.w
; x
++ ){
147 float value
= world_sfd
.buffer
[(y
*world_sfd
.w
+x
)*2+1];
148 shader_scene_scoretext_uInfo( (v3f
){ x
,y
, value
} );
149 mesh_draw( &world_sfd
.mesh_display
);
153 shader_scene_vertex_blend_use();
154 shader_scene_vertex_blend_uTexGarbage(0);
155 shader_scene_vertex_blend_uTexGradients(1);
156 world_link_lighting_ub( world
, _shader_scene_vertex_blend
.id
);
157 world_bind_position_texture( world
, _shader_scene_vertex_blend
.id
,
158 _uniform_scene_vertex_blend_g_world_depth
, 2 );
159 world_bind_light_array( world
, _shader_scene_vertex_blend
.id
,
160 _uniform_scene_vertex_blend_uLightsArray
, 3 );
161 world_bind_light_index( world
, _shader_scene_vertex_blend
.id
,
162 _uniform_scene_vertex_blend_uLightsIndex
, 4 );
163 bind_terrain_noise();
164 glActiveTexture( GL_TEXTURE1
);
165 glBindTexture( GL_TEXTURE_2D
, world_sfd
.tex_scoretex
);
167 shader_scene_vertex_blend_uPv( cam
->mtx
.pv
);
168 shader_scene_vertex_blend_uPvmPrev( pvm_prev
);
169 shader_scene_vertex_blend_uMdl( transform
);
170 shader_scene_vertex_blend_uCamera( cam
->transform
[3] );
172 mesh_bind( &world_sfd
.mesh_base
);
173 mdl_draw_submesh( &world_sfd
.sm_base
);
176 static int world_sfd_test( int argc
, const char *argv
[] )
179 int row
= vg_min( vg_max(atoi(argv
[0]),0), world_sfd
.h
);
180 sfd_encode( row
, argv
[1] );
186 static void world_sfd_init(void)
188 vg_info( "world_sfd_init\n" );
189 shader_scene_scoretext_register();
190 vg_console_reg_cmd( "sfd", world_sfd_test
, NULL
);
192 vg_linear_clear( vg_mem
.scratch
);
194 mdl_context mscoreboard
;
195 mdl_open( &mscoreboard
, "models/rs_scoretext.mdl", vg_mem
.scratch
);
196 mdl_load_metadata_block( &mscoreboard
, vg_mem
.scratch
);
197 mdl_async_load_glmesh( &mscoreboard
, &world_sfd
.mesh_base
);
199 mdl_load_mesh_block( &mscoreboard
, vg_mem
.scratch
);
201 scene_context
*scene
= &world_sfd
.scene
;
202 vg_async_item
*call
= scene_alloc_async( scene
, &world_sfd
.mesh_display
,
206 mdl_mesh
*m_backer
= mdl_find_mesh( &mscoreboard
, "backer" ),
207 *m_card
= mdl_find_mesh( &mscoreboard
, "score_card" );
210 *sm_backer
= mdl_arritm( &mscoreboard
.submeshs
, m_backer
->submesh_start
),
211 *sm_card
= mdl_arritm( &mscoreboard
.submeshs
, m_card
->submesh_start
);
212 world_sfd
.sm_base
= *sm_backer
;
215 m4x3_identity( identity
);
217 for( int i
=0;i
<4;i
++ ){
218 u32 vert_start
= scene
->vertex_count
;
219 scene_add_mdl_submesh( scene
, &mscoreboard
, sm_card
, identity
);
221 for( int j
=0; j
<sm_card
->vertex_count
; j
++ ){
222 scene_vert
*vert
= &scene
->arrvertices
[ vert_start
+j
];
224 float const k_glyph_uvw
= 1.0f
/64.0f
;
225 vert
->uv
[0] -= k_glyph_uvw
* (float)(i
-1);
226 vert
->norm
[3] = i
*42;
230 vg_async_dispatch( call
, async_scene_upload
);
231 vg_tex2d_load_qoi_async_file( "textures/scoretext.qoi",
232 VG_TEX2D_CLAMP
|VG_TEX2D_NEAREST
,
233 &world_sfd
.tex_scoretex
);
235 mdl_close( &mscoreboard
);
242 world_sfd
.buffer
= vg_linear_alloc( vg_mem
.rtmemory
, 2*w
*h
*sizeof(float) );
244 for( int i
=0; i
<w
*h
*2; i
++ )
245 world_sfd
.buffer
[i
] = 0.0f
;
248 #endif /* WORLD_SFD_C */