sfd
[carveJwlIkooP6JGAAIwe30JlM.git] / world_sfd.h
1 /*
2 * Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
3 */
4
5 #ifndef SFD_H
6 #define SFD_H
7
8 #include "world.h"
9 #include "shaders/scene_scoretext.h"
10 #include "shaders/scene_vertex_blend.h"
11
12 vg_tex2d tex_scoretext = { .path = "textures/scoretext.qoi",
13 .flags = VG_TEXTURE_CLAMP|VG_TEXTURE_NEAREST };
14
15 float sfd_encode_glyph( char c )
16 {
17 int value = 0;
18 if( c >= 'a' && c <= 'z' )
19 value = c-'a'+11;
20 else if( c >= '0' && c <= '9' )
21 value = c-'0'+1;
22 else if( c >= 'A' && c <= 'Z' )
23 value = c-'A'+11;
24 else if( c >= '\x01' && c <= '\x01'+10 )
25 value = 63-c;
26 else{
27 int base = 11+26;
28
29 switch( c ){
30 case '!': value=base+0; break;
31 case '?': value=base+1; break;
32 case ',': value=base+2; break;
33 case '.': value=base+3; break;
34 case '#': value=base+4; break;
35 case '$': value=base+5; break;
36 case '%': value=base+6; break;
37 case '*': value=base+7; break;
38 case '+': value=base+8; break;
39 case '-': value=base+9; break;
40 case '/': value=base+10; break;
41 case ':': value=base+11; break;
42 default: value=0; break;
43 }
44 }
45
46 return (float)value;
47 }
48
49 VG_STATIC void sfd_encode( u32 row, const char *str )
50 {
51 int end=0;
52 u32 row_h = world_global.sfd.h -1 -row;
53
54 for( int i=0; i<world_global.sfd.w; i++ ){
55 u32 idx = (world_global.sfd.w*row_h + i) * 2;
56
57 if( end ){
58 world_global.sfd.buffer[idx] = 0.0f;
59 }
60 else{
61 if( !str[i] )
62 end = 1;
63
64 world_global.sfd.buffer[idx] = sfd_encode_glyph( str[i] );
65 }
66 }
67 }
68
69 VG_STATIC void sfd_update(void)
70 {
71 for( int i=0; i<world_global.sfd.w*world_global.sfd.h; i++ ){
72 float *target = &world_global.sfd.buffer[i*2+0],
73 *cur = &world_global.sfd.buffer[i*2+1];
74
75 float const rate = vg.time_delta * 15.2313131414f;
76 float d1 = *target-*cur;
77
78 if( fabsf(d1) > rate ){
79 *cur += rate;
80 if( *cur > 60.0f )
81 *cur -= 60.0f;
82 }
83 else
84 *cur = *target;
85 }
86 }
87
88 VG_STATIC void bind_terrain_noise(void);
89 VG_STATIC void sfd_render( world_instance *world, camera *cam, m4x3f transform )
90 {
91 mesh_bind( &world_global.sfd.mesh_display );
92 shader_scene_scoretext_use();
93 shader_scene_scoretext_uTexMain(1);
94
95 world_link_lighting_ub( world, _shader_scene_scoretext.id );
96 world_bind_position_texture( world, _shader_scene_scoretext.id,
97 _uniform_scene_scoretext_g_world_depth, 2 );
98 world_bind_light_array( world, _shader_scene_scoretext.id,
99 _uniform_scene_scoretext_uLightsArray, 3 );
100 world_bind_light_index( world, _shader_scene_scoretext.id,
101 _uniform_scene_scoretext_uLightsIndex, 4 );
102
103 bind_terrain_noise();
104 vg_tex2d_bind( &tex_scoretext, 1 );
105
106 m4x4f pvm_prev;
107 m4x3_expand( transform, pvm_prev );
108 m4x4_mul( cam->mtx_prev.pv, pvm_prev, pvm_prev );
109
110 shader_scene_scoretext_uPv( cam->mtx.pv );
111 shader_scene_scoretext_uPvmPrev( pvm_prev );
112 shader_scene_scoretext_uMdl( transform );
113 shader_scene_scoretext_uCamera( cam->transform[3] );
114
115 for( int y=0;y<world_global.sfd.h; y++ ){
116 for( int x=0; x<world_global.sfd.w; x++ ){
117 float value = world_global.sfd.buffer[(y*world_global.sfd.w+x)*2+1];
118 shader_scene_scoretext_uInfo( (v3f){ x,y, value } );
119 mesh_draw( &world_global.sfd.mesh_display );
120 }
121 }
122
123 shader_scene_vertex_blend_use();
124 shader_scene_vertex_blend_uTexGarbage(0);
125 shader_scene_vertex_blend_uTexGradients(1);
126 world_link_lighting_ub( world, _shader_scene_vertex_blend.id );
127 world_bind_position_texture( world, _shader_scene_vertex_blend.id,
128 _uniform_scene_vertex_blend_g_world_depth, 2 );
129 world_bind_light_array( world, _shader_scene_vertex_blend.id,
130 _uniform_scene_vertex_blend_uLightsArray, 3 );
131 world_bind_light_index( world, _shader_scene_vertex_blend.id,
132 _uniform_scene_vertex_blend_uLightsIndex, 4 );
133 bind_terrain_noise();
134 vg_tex2d_bind( &tex_scoretext, 1 );
135
136 shader_scene_vertex_blend_uPv( cam->mtx.pv );
137 shader_scene_vertex_blend_uPvmPrev( pvm_prev );
138 shader_scene_vertex_blend_uMdl( transform );
139 shader_scene_vertex_blend_uCamera( cam->transform[3] );
140
141 mesh_bind( &world_global.sfd.mesh_base );
142 mdl_draw_submesh( &world_global.sfd.sm_base );
143 }
144
145 VG_STATIC int world_sfd_test( int argc, const char *argv[] )
146 {
147 if( argc == 2 ){
148 int row = vg_min( vg_max(atoi(argv[0]),0), world_global.sfd.h);
149 sfd_encode( row, argv[1] );
150 }
151
152 return 0;
153 }
154
155 VG_STATIC void world_sfd_init(void)
156 {
157 vg_info( "world_sfd_init\n" );
158 shader_scene_scoretext_register();
159
160 vg_function_push( (struct vg_cmd){
161 .name = "sfd",
162 .function = world_sfd_test
163 });
164
165 vg_linear_clear( vg_mem.scratch );
166
167 mdl_context mscoreboard;
168 mdl_open( &mscoreboard, "models/rs_scoretext.mdl", vg_mem.scratch );
169 mdl_load_metadata_block( &mscoreboard, vg_mem.scratch );
170 mdl_load_mesh_block( &mscoreboard, vg_mem.scratch );
171
172 scene *sc = scene_init( vg_mem.scratch, 3000, 8000 );
173
174 mdl_mesh *m_backer = mdl_find_mesh( &mscoreboard, "backer" ),
175 *m_card = mdl_find_mesh( &mscoreboard, "score_card" );
176
177 mdl_submesh
178 *sm_backer = mdl_arritm( &mscoreboard.submeshs, m_backer->submesh_start ),
179 *sm_card = mdl_arritm( &mscoreboard.submeshs, m_card->submesh_start );
180 world_global.sfd.sm_base = *sm_backer;
181
182 mdl_close( &mscoreboard );
183
184 m4x3f identity;
185 m4x3_identity( identity );
186
187 for( int i=0;i<4;i++ ){
188 u32 vert_start = sc->vertex_count;
189 scene_add_mdl_submesh( sc, &mscoreboard, sm_card, identity );
190
191 for( int j=0; j<sm_card->vertex_count; j++ ){
192 scene_vert *vert = &sc->arrvertices[ vert_start+j ];
193
194 float const k_glyph_uvw = 1.0f/64.0f;
195 vert->uv[0] -= k_glyph_uvw * (float)(i-1);
196 vert->norm[3] = i*42;
197 }
198 }
199
200 vg_acquire_thread_sync();
201 {
202 scene_upload( sc, &world_global.sfd.mesh_display );
203 mdl_unpack_glmesh( &mscoreboard, &world_global.sfd.mesh_base );
204 vg_tex2d_init( (vg_tex2d *[]){ &tex_scoretext }, 1 );
205 }
206 vg_release_thread_sync();
207
208 int w = 27,
209 h = 13;
210
211 world_global.sfd.w = w;
212 world_global.sfd.h = h;
213 world_global.sfd.buffer =
214 vg_linear_alloc( vg_mem.rtmemory, 2*w*h*sizeof(float) );
215
216 for( int i=0; i<w*h*2; i++ )
217 world_global.sfd.buffer[i] = 0.0f;
218 }
219
220 #endif /* SFD_H */