From: hgn Date: Mon, 1 Aug 2022 16:34:47 +0000 (+0100) Subject: sfd X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;ds=sidebyside;h=4c49b11c317034277be4d117c5d2847ef2f3492b;p=carveJwlIkooP6JGAAIwe30JlM.git sfd --- diff --git a/models/mp_dev.mdl b/models/mp_dev.mdl index 1768051..5f0de7c 100644 Binary files a/models/mp_dev.mdl and b/models/mp_dev.mdl differ diff --git a/models/rs_scoretext.mdl b/models/rs_scoretext.mdl new file mode 100644 index 0000000..5eef656 Binary files /dev/null and b/models/rs_scoretext.mdl differ diff --git a/shaders/scoretext.h b/shaders/scoretext.h new file mode 100644 index 0000000..304715c --- /dev/null +++ b/shaders/scoretext.h @@ -0,0 +1,260 @@ +#ifndef SHADER_scoretext_H +#define SHADER_scoretext_H +static void shader_scoretext_link(void); +static void shader_scoretext_register(void); +static struct vg_shader _shader_scoretext = { + .name = "scoretext", + .link = shader_scoretext_link, + .vs = +{ +.orig_file = "../shaders/scoretext.vs", +.static_src = +"layout (location=0) in vec3 a_co;\n" +"layout (location=1) in vec3 a_norm;\n" +"layout (location=2) in vec4 a_colour;\n" +"layout (location=3) in vec2 a_uv;\n" +"\n" +"#line 2 0 \n" +"\n" +"uniform mat4 uPv;\n" +"uniform mat4x3 uMdl;\n" +"\n" +"uniform vec3 uInfo;\n" +"\n" +"out vec4 aColour;\n" +"out vec2 aUv;\n" +"out vec3 aNorm;\n" +"out vec3 aCo;\n" +"out vec3 aWorldCo;\n" +"\n" +"void main()\n" +"{\n" +" float w = a_colour.g + fract(uInfo.z+0.5)-0.75;\n" +" float c = -cos(w*0.2);\n" +" float s = -sin(w*0.2);\n" +" float r = 0.2;\n" +"\n" +" float w1 = clamp( w*4.0 - a_co.y*10.0, -1.0, 1.0 ) *(3.14159265*0.5);\n" +" float c1 = cos(w1);\n" +" float s1 = sin(w1);\n" +"\n" +" float yoff = step(0.01,fract(uInfo.z))*-0.5;\n" +"\n" +" mat4x3 mlocal;\n" +" mlocal[0] = vec3(c1, s1,0.0);\n" +" mlocal[1] = vec3(-s1,c1,0.0);\n" +" mlocal[2] = vec3(0.0,0.0,1.0);\n" +" mlocal[3] = vec3(c*r,uInfo.y*0.875 + s*r,uInfo.x*0.5);\n" +"\n" +" vec3 world_pos = uMdl * vec4(mlocal * vec4(a_co,1.0),1.0);\n" +" gl_Position = uPv * vec4( world_pos, 1.0 );\n" +" aColour = a_colour;\n" +" aUv = a_uv + vec2( floor(uInfo.z+0.5)*(1.0/64.0), yoff );\n" +" aNorm = mat3(uMdl) * mat3(mlocal) * a_norm;\n" +" aCo = a_co;\n" +" aWorldCo = world_pos;\n" +"}\n" +""}, + .fs = +{ +.orig_file = "../shaders/vblend.fs", +.static_src = +"out vec4 FragColor;\n" +"\n" +"uniform sampler2D uTexGarbage;\n" +"uniform sampler2D uTexGradients;\n" +"uniform vec3 uCamera;\n" +"\n" +"in vec4 aColour;\n" +"in vec2 aUv;\n" +"in vec3 aNorm;\n" +"in vec3 aCo;\n" +"in vec3 aWorldCo;\n" +"\n" +"#line 1 1 \n" +"layout (std140) uniform ub_world_lighting\n" +"{\n" +" vec4 g_light_colours[3];\n" +" vec4 g_light_directions[3];\n" +" vec4 g_ambient_colour;\n" +"\n" +" vec4 g_water_plane;\n" +" vec4 g_depth_bounds;\n" +" float g_water_fog;\n" +" int g_light_count;\n" +" int g_light_preview;\n" +"};\n" +"\n" +"uniform sampler2D g_world_depth;\n" +"\n" +"// Standard diffuse + spec models\n" +"// ==============================\n" +"\n" +"vec3 do_light_diffuse( vec3 vfrag, vec3 wnormal )\n" +"{\n" +" vec3 vtotal = g_ambient_colour.rgb;\n" +"\n" +" for( int i=0; i world_traffic.h */ #include "world_routes.h" +#include "world_sfd.h" #include "shaders/terrain.h" #include "shaders/sky.h" @@ -40,6 +41,7 @@ static struct gworld u32 spawn_count; struct subworld_routes routes; + struct subworld_sfd sfd; /* ... struct subworld_spawns system_spawns; @@ -85,6 +87,7 @@ static struct gworld world; static struct subworld_routes *subworld_routes(void) { return &world.routes; } +static struct subworld_sfd *subworld_sfd(void) { return &world.sfd; } vg_tex2d tex_terrain_colours = { .path = "textures/gradients.qoi", @@ -122,11 +125,14 @@ static void world_register(void) shader_alphatest_register(); world_routes_register(); + world_sfd_register(); } static void world_free(void) { /* TODO.. */ + + world_sfd_free(); } static void render_world_depth( m4x4f projection, m4x3f camera ); @@ -497,11 +503,16 @@ static void world_init(void) world.dome_lower = *mdl_node_submesh( msky, nlower, 0 ); world.dome_upper = *mdl_node_submesh( msky, nupper, 0 ); free(msky); + + + /* Other systems */ + world_sfd_init(); } static void world_update(void) { world_routes_debug(); + sfd_update( &world.sfd.tester ); #if 0 rb_solver_reset(); @@ -685,6 +696,16 @@ static void render_world( m4x4f projection, m4x3f camera ) render_world_vb( projection, camera[3] ); render_world_alphatest( projection, camera[3] ); render_terrain( projection, camera[3] ); + + m4x3f identity_matrix; + m4x3_identity( identity_matrix ); + identity_matrix[3][1] = 125.0f; + + v4f t; + q_axis_angle( t, (v3f){0.0f,1.0f,0.0f}, 2.3f ); + q_m3x3( t, identity_matrix ); + + sfd_render( &world.sfd.tester, projection, camera[3], identity_matrix ); } static void render_world_depth( m4x4f projection, m4x3f camera ) diff --git a/world_routes.h b/world_routes.h index 82d5da7..4c198e1 100644 --- a/world_routes.h +++ b/world_routes.h @@ -58,11 +58,6 @@ struct subworld_routes static struct subworld_routes *subworld_routes(void); -/* - * TODO list: - * when a gate is passed through it needs to trigger into an active state - */ - static void debug_sbpath( struct route_node *rna, struct route_node *rnb, u32 colour, float xoffset ) { diff --git a/world_sfd.h b/world_sfd.h new file mode 100644 index 0000000..88f7331 --- /dev/null +++ b/world_sfd.h @@ -0,0 +1,232 @@ +#ifndef SFD_H +#define SFD_H + +#include "common.h" +#include "model.h" +#include "world.h" + +#include "shaders/scoretext.h" +#include "shaders/vblend.h" + +vg_tex2d tex_scoretext = { .path = "textures/scoretext.qoi", + .flags = VG_TEXTURE_CLAMP|VG_TEXTURE_NEAREST }; + +struct sfd_instance +{ + float *buffer; + + u32 w,h; +}; + + +struct subworld_sfd +{ + scene mesh; + mdl_submesh *sm_module, *sm_card; + glmesh temp; + + struct sfd_instance tester; +}; + +static struct subworld_sfd *subworld_sfd(void); + + +float sfd_encode_glyph( char c ) +{ + int value = 0; + if( c >= 'a' && c <= 'z' ) + value = c-'a'+11; + else if( c >= '0' && c <= '9' ) + value = c-'0'+1; + else if( c >= 'A' && c <= 'Z' ) + value = c-'A'+11; + else if( c >= '\x01' && c <= '\x01'+10 ) + value = 63-c; + else + { + int base = 'A'+11+27; + + switch( c ) + { + case '!': value=base+0; break; + case '?': value=base+1; break; + case ',': value=base+2; break; + case '.': value=base+3; break; + case '#': value=base+4; break; + case '$': value=base+5; break; + case '%': value=base+6; break; + case '*': value=base+7; break; + case '+': value=base+8; break; + case '-': value=base+9; break; + case ':': value=base+10; break; + case '/': value=base+11; break; + default: value=0; break; + } + } + + return (float)value; +} + +static void sfd_encode( struct sfd_instance *display, u32 row, const char *str ) +{ + int end=0; + for( int i=0; iw; i++ ) + { + if( end ) + { + display->buffer[display->w*row + i] = 0.0f; + } + else + { + if( !str[i] ) + end = 1; + + display->buffer[display->w*row + i] = sfd_encode_glyph( str[i] ); + } + } +} + +static void sfd_new( struct sfd_instance *display, u32 w, u32 h ) +{ + display->w = w; + display->h = h; + display->buffer = malloc( w*h*sizeof(float)*2 ); + + for( int i=0; ibuffer[i] = 0.0f; +} + +static void sfd_update( struct sfd_instance *display ) +{ + for( int i=0; iw*display->h; i++ ) + { + float *target = &display->buffer[i], + *cur = target+display->w*display->h; + + float const rate = ktimestep*15.2313131414f; + float d1 = *target-*cur; + + if( fabsf(d1) > rate ) + { + *cur += rate; + if( *cur > 60.0f ) + *cur -= 60.0f; + } + else + *cur = *target; + } +} + +static void sfd_render( struct sfd_instance *display, + m4x4f projection, v3f camera, m4x3f transform ) +{ + struct subworld_sfd *sfd = subworld_sfd(); + scene_bind( &sfd->mesh ); + + shader_scoretext_use(); + shader_scoretext_uTexGarbage(0); + shader_scoretext_uTexGradients(1); + shader_link_standard_ub( _shader_scoretext.id, 2 ); + bind_terrain_textures(); + vg_tex2d_bind( &tex_scoretext, 1 ); + + shader_scoretext_uPv( projection ); + shader_scoretext_uMdl( transform ); + shader_scoretext_uCamera( camera ); + + for( int y=0;yh; y++ ) + { + for( int x=0; xw; x++ ) + { + float value = display->buffer[display->h*display->w+y*display->w+x]; + shader_scoretext_uInfo( (v3f){ x,y, value } ); + scene_draw( &sfd->mesh ); + } + } + + shader_vblend_use(); + shader_vblend_uTexGarbage(0); + shader_vblend_uTexGradients(1); + shader_link_standard_ub( _shader_vblend.id, 2 ); + bind_terrain_textures(); + + shader_vblend_uPv( projection ); + shader_vblend_uMdl( transform ); + shader_vblend_uCamera( camera ); + + mesh_bind( &sfd->temp ); + mesh_draw( &sfd->temp ); +} + +static int world_sfd_test( int argc, const char *argv[] ) +{ + struct subworld_sfd *sfd = subworld_sfd(); + + if( argc == 2 ) + { + int row = vg_min(vg_max(atoi(argv[0]),0),sfd->tester.h); + sfd_encode( &sfd->tester, row, argv[1] ); + } + + return 0; +} + +static void world_sfd_init(void) +{ + struct subworld_sfd *sfd = subworld_sfd(); + + vg_function_push( (struct vg_cmd){ + .name = "sfd", + .function = world_sfd_test + }); + + mdl_header *mboard = mdl_load( "models/rs_scoretext.mdl" ); + + scene_init( &sfd->mesh ); + + mdl_node *pn_card = mdl_node_from_name( mboard, "score_card" ); + mdl_submesh *card = mdl_submesh_from_id( mboard, pn_card->submesh_start ); + + mdl_node *pn_backer = mdl_node_from_name( mboard, "backer" ); + mdl_submesh *backer = mdl_submesh_from_id( mboard, pn_backer->submesh_start); + mdl_unpack_submesh( mboard, &sfd->temp, backer ); + + m4x3f identity; + m4x3_identity( identity ); + + for( int i=0;i<8;i++ ) + { + u32 vert_start = sfd->mesh.vertex_count; + scene_add_submesh( &sfd->mesh, mboard, card, identity ); + + for( int j=0; jvertex_count; j++ ) + { + mdl_vert *vert = &sfd->mesh.verts[ vert_start+j ]; + + float const k_glyph_uvw = 1.0f/64.0f; + vert->uv[0] -= k_glyph_uvw * (float)(i-4); + vert->colour[0] = 0.0f; + vert->colour[1] = i-4; + } + } + + scene_upload( &sfd->mesh ); + scene_free_offline_buffers( &sfd->mesh ); + + free( mboard ); + vg_tex2d_init( (vg_tex2d *[]){ &tex_scoretext }, 1 ); + + sfd_new( &sfd->tester, 16, 8 ); +} + +static void world_sfd_register(void) +{ + shader_scoretext_register(); +} + +static void world_sfd_free(void) +{ + vg_tex2d_free( (vg_tex2d *[]){ &tex_scoretext }, 1 ); +} + +#endif /* SFD_H */