challenge effects
authorhgn <hgodden00@gmail.com>
Sat, 12 Aug 2023 14:49:42 +0000 (15:49 +0100)
committerhgn <hgodden00@gmail.com>
Sat, 12 Aug 2023 14:49:42 +0000 (15:49 +0100)
15 files changed:
blender_export.py
build.c
ent_challenge.c
ent_objective.c
entity.h
font.h
maps_src/mp_spawn/main.mdl
menu.h
player.c
shaders/scene_fxglow.h
shaders/scene_fxglow.vs [new file with mode: 0644]
skaterift.c
world.c
world.h
world_render.c

index 1b1c4fb69e9e22ad098c73109230ffeb6303db74..50f46c3d7184917431fad6d799748b6ea56ea24b 100644 (file)
@@ -2148,7 +2148,7 @@ class SR_SCENE_SETTINGS(bpy.types.PropertyGroup):
 #{
    use_hidden: bpy.props.BoolProperty( name="use hidden", default=False )
    export_dir: bpy.props.StringProperty( name="Export Dir", subtype='DIR_PATH' )
-   gizmos: bpy.props.BoolProperty( name="Draw Gizmos", default=True )
+   gizmos: bpy.props.BoolProperty( name="Draw Gizmos", default=False )
 
    panel: bpy.props.EnumProperty(
         name='Panel',
diff --git a/build.c b/build.c
index 811317d82f64ca6100390c06f65b23e00150b1e6..a0a253f1a037626ab7f4987b9306a20a500e4aa9 100644 (file)
--- a/build.c
+++ b/build.c
@@ -190,7 +190,7 @@ void build_shaders(void)
    /* Scene */
    _S( "scene_standard",            "scene.vs", "scene_standard.fs" );
    _S( "scene_standard_alphatest",  "scene.vs", "scene_standard_alphatest.fs" );
-   _S( "scene_fxglow",              "scene.vs", "scene_fxglow.fs" );
+   _S( "scene_fxglow",              "scene_fxglow.vs", "scene_fxglow.fs" );
    _S( "scene_vertex_blend",        "scene.vs", "scene_vertex_blend.fs" );
    _S( "scene_terrain",             "scene.vs", "scene_terrain.fs" );
    _S( "scene_route",               "scene.vs", "scene_route.fs" );
index 515aeb09d5e456b813dbb00c40642cc7fa72348a..bed85870c08d2ce0b1fa0f581bdfc85b8f6ebc36 100644 (file)
@@ -3,12 +3,13 @@
 
 #include "entity.h"
 #include "input.h"
+#include "gui.h"
 
 VG_STATIC void ent_challenge_call( world_instance *world, ent_call *call ){
    u32 index = mdl_entity_id_id( call->id );
    ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
 
-   if( call->function == 0 ){ /* challenge() */
+   if( call->function == 0 ){ /* unlock() */
       if( !challenge->status ){
          vg_info( "challenge( '%s' )\n", 
                   mdl_pstr( &world->meta, challenge->pstr_alias) );
@@ -21,7 +22,11 @@ VG_STATIC void ent_challenge_call( world_instance *world, ent_call *call ){
       challenge->status = 1;
    }
    else if( call->function == 1 ){  /* view() */
-      world_entity_focus( call->id );
+      if( (localplayer.subsystem == k_player_subsystem_walk) &&
+          (world_static.challenge_target == NULL) ){
+         world_static.challenge_target = NULL;
+         world_entity_focus( call->id );
+      }
    }
    else {
       vg_print_backtrace();
@@ -53,7 +58,31 @@ VG_STATIC void ent_challenge_preupdate( ent_challenge *challenge ){
       world_static.focus_cam.farz = localplayer.cam.farz;
    }
 
+   gui_helper_action( button_display_string( k_srbind_maccept ), "start" );
+   gui_helper_action( button_display_string( k_srbind_mback ), "exit" );
+
+   if( mdl_entity_id_type( challenge->first ) == k_ent_objective ){
+      if( button_down( k_srbind_maccept ) ){
+         u32 index = mdl_entity_id_id( challenge->first );
+         world_static.challenge_target = mdl_arritm( &world->ent_objective, 
+                                                     index );
+         world_static.challenge_timer = 0.0f;
+         world_entity_unfocus();
+
+         u32 next = challenge->first;
+         while( mdl_entity_id_type(next) == k_ent_objective ){
+            u32 index = mdl_entity_id_id( next );
+            ent_objective *objective = mdl_arritm(&world->ent_objective,index);
+            objective->flags &= ~k_ent_objective_passed;
+            next = objective->id_next;
+            v3_fill( objective->transform.s, 1.0f );
+         }
+         return;
+      }
+   }
+
    if( button_down( k_srbind_mback ) ){
+      world_static.challenge_target = NULL;
       world_entity_unfocus();
       return;
    }
index 330e60fcb97524075020360909c37be6a1dcf848..68a3dd015f69882562201beadc2111940adeb19d 100644 (file)
@@ -8,11 +8,12 @@
 VG_STATIC void ent_objective_pass( world_instance *world, 
                                    ent_objective *objective ){
    if( objective->id_next ){
-      world->challenge_timer += objective->filter;
+      world_static.challenge_timer += objective->filter;
 
       u32 index = mdl_entity_id_id( objective->id_next );
       ent_objective *next = mdl_arritm( &world->ent_objective, index );
-      world->challenge_target = next;
+      world_static.challenge_target = next;
+      objective->flags |= k_ent_objective_passed;
 
       if( next->filter & k_ent_objective_filter_passthrough )
          ent_objective_pass( world, next );
@@ -21,8 +22,8 @@ VG_STATIC void ent_objective_pass( world_instance *world,
    }
    else {
       vg_success( "NYU Film school graduate SUCKAH\n" );
-      world->challenge_target = NULL;
-      world->challenge_timer = 0.0f;
+      world_static.challenge_target = NULL;
+      world_static.challenge_timer = 0.0f;
 
       if( objective->id_win ){
          ent_call call;
@@ -72,29 +73,21 @@ VG_STATIC void ent_objective_call( world_instance *world, ent_call *call ){
    ent_objective *objective = mdl_arritm( &world->ent_objective, index );
 
    if( call->function == 0 ){
-      if( objective->flags & k_ent_objective_hidden ) return;
+      if( objective->flags & (k_ent_objective_hidden|
+                              k_ent_objective_passed)) return;
 
-      if( world->challenge_target ){
-         if( (world->challenge_target == objective) && 
+      if( world_static.challenge_target ){
+         if( (world_static.challenge_target == objective) && 
               ent_objective_check_filter( objective )){
             ent_objective_pass( world, objective );
          }
          else {
             vg_error( "womp womp\n" );
-            world->challenge_target = NULL;
-            world->challenge_timer = 0.0f;
+            world_static.challenge_target = NULL;
+            world_static.challenge_timer = 0.0f;
          }
       }
    }
-#if 0
-   else if( call->function == 1 ){
-      if( objective->flags & k_ent_objective_hidden ) return;
-
-      vg_info( "begin the challenge\n" );
-      world->challenge_timer = 0.0f;
-      ent_objective_pass( world, objective );
-   }
-#endif
    else if( call->function == 2 ){
       objective->flags &= ~k_ent_objective_hidden;
 
index 6faa7d99e786a881ee97c4c2bb7eaea4df2699b2..5ac85d8b01e08290de63231e7ba8bcfb23a1fbd6 100644 (file)
--- a/entity.h
+++ b/entity.h
@@ -425,7 +425,8 @@ enum ent_objective_filter{
 };
 
 enum ent_objective_flag {
-   k_ent_objective_hidden = 0x1
+   k_ent_objective_hidden = 0x1,
+   k_ent_objective_passed = 0x2
 };
 
 struct ent_objective{
diff --git a/font.h b/font.h
index 76e63c85bb11d16f970375253452073875d9d9ea..4361e934795fc881bc71e886d86139bb013a66a7 100644 (file)
--- a/font.h
+++ b/font.h
@@ -169,13 +169,6 @@ void font3d_begin( const char *text,
       shader_model_font_uMdl( transform );
    }
    else if( render->shader == k_font_shader_world ){
-
-
-      vg_info( "-----\n" );
-      for( int i=0; i<4; i++ ){
-         vg_info( PRINTF_v4f( prev_mtx[i] ) );
-      }
-
       shader_scene_font_uPvmPrev( prev_mtx );
       shader_scene_font_uMdl( transform );
    }
index caf82eec3d24dd3f8c889ce4b4c15058d6f2d762..acbcb5130344d26b6c5ee22cf2b5219322a11bd7 100644 (file)
Binary files a/maps_src/mp_spawn/main.mdl and b/maps_src/mp_spawn/main.mdl differ
diff --git a/menu.h b/menu.h
index 44feffdf8cec1f2d5b219c61db681d149b591a9f..59c01f61a0b7ec7423db6232c48e6fd9ff95a604 100644 (file)
--- a/menu.h
+++ b/menu.h
@@ -215,8 +215,7 @@ static void menu_trigger_item( ent_menuitem *item )
          menu_close();
       }
       else if( MDL_CONST_PSTREQ( &menu.model, q, "reset_home" ) ){
-         world_static.active_instance = 0;
-         world_static.active_trigger_volume_count = 0;
+         world_set_active_instance( 0 );
          localplayer.viewable_world = world_current_instance();
          localplayer_cmd_respawn( 1, (const char *[]){"start"} );
          menu_close();
index 12f8cbdc1bf11e7dcba48e2dd263c3fd4b9738cd..f5176eb21e69701b0f45aa887d1a8d7a4736d216 100644 (file)
--- a/player.c
+++ b/player.c
@@ -165,7 +165,7 @@ void player__pass_gate( player_instance *player, ent_gate *gate )
    m4x3_mulv( gate->transport, player->cam.pos, player->cam.pos );
 
    if( gate->flags & k_ent_gate_nonlocal )
-      world_static.active_instance = gate->target;
+      world_set_active_instance( gate->target );
 
    audio_lock();
    audio_oneshot( &audio_gate_pass, 1.0f, 0.0f );
@@ -282,6 +282,9 @@ PLAYER_API void player__spawn( player_instance *player, ent_spawn *rp ){
    player->immobile = 0;
    player->gate_waiting = NULL;
    world_static.last_use = 0.0;
+   world_static.focused_entity = 0;
+   world_static.challenge_target = NULL;
+   world_static.challenge_timer = 0.0f;
    world_entity_unfocus();
 
    if( _player_reset[ player->subsystem ] )
index 82251455ee48d0232ca5ed6978dc8ea0fc23cf88..a86f5207db00688f5ded3d26c3a33049a8a4bb57 100644 (file)
@@ -7,7 +7,7 @@ static struct vg_shader _shader_scene_fxglow = {
    .link = shader_scene_fxglow_link,
    .vs = 
 {
-.orig_file = "shaders/scene.vs",
+.orig_file = "shaders/scene_fxglow.vs",
 .static_src = 
 "layout (location=0) in vec3  a_co;\n"
 "layout (location=1) in vec4  a_norm;\n"
@@ -36,6 +36,7 @@ static struct vg_shader _shader_scene_fxglow = {
 "uniform mat4x3 uMdl;\n"
 "uniform mat4   uPv;\n"
 "uniform mat4   uPvmPrev;\n"
+"uniform vec2   uUvOffset;\n"
 "\n"
 "out vec2 aUv;\n"
 "out vec4 aNorm;\n"
@@ -52,7 +53,7 @@ static struct vg_shader _shader_scene_fxglow = {
 "\n"
 "   gl_Position = vproj0;\n"
 "\n"
-"   aUv = a_uv;\n"
+"   aUv = a_uv + uUvOffset;\n"
 "   aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
 "   aCo = a_co;\n"
 "   aWorldCo = world_pos0;\n"
@@ -444,6 +445,7 @@ static struct vg_shader _shader_scene_fxglow = {
 static GLuint _uniform_scene_fxglow_uMdl;
 static GLuint _uniform_scene_fxglow_uPv;
 static GLuint _uniform_scene_fxglow_uPvmPrev;
+static GLuint _uniform_scene_fxglow_uUvOffset;
 static GLuint _uniform_scene_fxglow_uTexMain;
 static GLuint _uniform_scene_fxglow_uCamera;
 static GLuint _uniform_scene_fxglow_g_world_depth;
@@ -458,6 +460,9 @@ static void shader_scene_fxglow_uPv(m4x4f m){
 static void shader_scene_fxglow_uPvmPrev(m4x4f m){
    glUniformMatrix4fv(_uniform_scene_fxglow_uPvmPrev,1,GL_FALSE,(float*)m);
 }
+static void shader_scene_fxglow_uUvOffset(v2f v){
+   glUniform2fv(_uniform_scene_fxglow_uUvOffset,1,v);
+}
 static void shader_scene_fxglow_uTexMain(int i){
    glUniform1i(_uniform_scene_fxglow_uTexMain,i);
 }
@@ -475,6 +480,7 @@ static void shader_scene_fxglow_link(void){
    _uniform_scene_fxglow_uMdl = glGetUniformLocation( _shader_scene_fxglow.id, "uMdl" );
    _uniform_scene_fxglow_uPv = glGetUniformLocation( _shader_scene_fxglow.id, "uPv" );
    _uniform_scene_fxglow_uPvmPrev = glGetUniformLocation( _shader_scene_fxglow.id, "uPvmPrev" );
+   _uniform_scene_fxglow_uUvOffset = glGetUniformLocation( _shader_scene_fxglow.id, "uUvOffset" );
    _uniform_scene_fxglow_uTexMain = glGetUniformLocation( _shader_scene_fxglow.id, "uTexMain" );
    _uniform_scene_fxglow_uCamera = glGetUniformLocation( _shader_scene_fxglow.id, "uCamera" );
    _uniform_scene_fxglow_g_world_depth = glGetUniformLocation( _shader_scene_fxglow.id, "g_world_depth" );
diff --git a/shaders/scene_fxglow.vs b/shaders/scene_fxglow.vs
new file mode 100644 (file)
index 0000000..10c820a
--- /dev/null
@@ -0,0 +1,31 @@
+layout (location=0) in vec3  a_co;
+layout (location=1) in vec4  a_norm;
+layout (location=2) in vec2  a_uv;
+
+#include "motion_vectors_vs.glsl"
+
+uniform mat4x3 uMdl;
+uniform mat4   uPv;
+uniform mat4   uPvmPrev;
+uniform vec2   uUvOffset;
+
+out vec2 aUv;
+out vec4 aNorm;
+out vec3 aCo;
+out vec3 aWorldCo;
+
+void main()
+{
+   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );
+   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );
+   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );
+
+   vs_motion_out( vproj0, vproj1 );
+
+   gl_Position = vproj0;
+
+   aUv = a_uv + uUvOffset;
+   aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );
+   aCo = a_co;
+   aWorldCo = world_pos0;
+}
index e56a43a6cbe53b464443a09c7ec9cd2e2030a670..9b90548c3f64a28f4e62949ce5c83f77b7d240cd 100644 (file)
@@ -143,7 +143,7 @@ static void skaterift_restore_state(void){
          };
          skaterift_world_load_thread( &args );
 
-         world_static.active_instance = vg_msg_seekkvu32( &world, "index", 0 );
+         world_set_active_instance( vg_msg_seekkvu32( &world, "index", 0 ) );
          world_static.active_trigger_volume_count = 0;
          localplayer.viewable_world = world_current_instance();
       }
diff --git a/world.c b/world.c
index c3b55163110fe686905d99ba31e0d878719a9ad8..019e572a63b714c6c690a0ecb438bdc369b7f518 100644 (file)
--- a/world.c
+++ b/world.c
@@ -26,6 +26,15 @@ static void world_init(void)
                                                    VG_MEMORY_SYSTEM );
 }
 
+static void world_set_active_instance( u32 index ){
+   world_static.challenge_target = NULL;
+   world_static.challenge_timer = 0.0f;
+   world_static.focused_entity = 0;
+   world_static.focus_strength = 0.0f;
+   world_static.active_trigger_volume_count = 0;
+   world_static.active_instance = index;
+}
+
 static void skaterift_world_get_save_path( enum world_purpose which, 
                                            char buf[128] ){
    addon_reg *reg;
diff --git a/world.h b/world.h
index 63bfa9c4f9fb6d0d6e442e074cf5341be211f599..d35f0646b6ec1e8ed76b4d789e2f57bac4a74793 100644 (file)
--- a/world.h
+++ b/world.h
@@ -194,9 +194,6 @@ struct world_instance {
    u32 cubemap_cooldown, cubemap_side;
 
    rb_object rb_geo;
-
-   ent_objective *challenge_target;
-   f32 challenge_timer;
 };
 
 struct world_static {
@@ -214,12 +211,14 @@ struct world_static {
 
    world_instance instances[4];
    i32            active_instance;
-
-   /* TODO: FOCUSED_INSTANCE */
    u32            focused_entity; /* like skateshop, challenge.. */
    f32            focus_strength;
    camera         focus_cam;
 
+   /* challenges */
+   ent_objective *challenge_target;
+   f32 challenge_timer;
+
    addon_reg *addon_hub,
              *addon_client;
 
@@ -234,5 +233,6 @@ static world_static;
 
 static void world_init(void);
 static world_instance *world_current_instance(void);
+static void world_set_active_instance( u32 index );
 
 #endif /* WORLD_H */
index 35730acdc985030dbcb42b7c31998a5151a356f0..12728799bf2cbd4b0d1ae33b559bde16720793c9 100644 (file)
@@ -414,31 +414,68 @@ VG_STATIC
 void world_render_challenges( world_instance *world, struct world_pass *pass,
                               v3f pos, int layer_depth ){
    if( !world ) return;
+   if( skaterift.activity == k_skaterift_replay ) return;
 
    /* sort lists */
-   const f32 radius = 40.0f;
-   bh_iter it;
-   bh_iter_init_range( 0, &it, pos, radius+10.0f );
-   i32 idx;
+   f32 radius = 40.0f;
 
    u32 objective_list[ 32 ],
        challenge_list[ 16 ];
 
+   v2f objective_uv_offsets[ 32 ];
+
    u32 objective_count = 0,
        challenge_count = 0;
 
-   while( bh_next( world->entity_bh, &it, &idx ) ){
-      u32 id    = world->entity_list[ idx ],
-          type  = mdl_entity_id_type( id ),
-          index = mdl_entity_id_id( id );
+   ent_challenge *active_challenge = NULL;
+   int running = 0;
+   if( mdl_entity_id_type( world_static.focused_entity ) == k_ent_challenge ){
+      if( (skaterift.activity == k_skaterift_default) &&
+           world_static.challenge_target ){
+         running = 1;
+      }
 
-      if( type == k_ent_objective ) {
-         if( objective_count < vg_list_size(objective_list) )
-            objective_list[ objective_count ++ ] = index;
+      if( !((skaterift.activity != k_skaterift_ent_focus) &&
+            !world_static.challenge_target) ){
+         world_instance *challenge_world = world_current_instance();
+         u32 index = mdl_entity_id_id( world_static.focused_entity );
+         active_challenge = mdl_arritm(&challenge_world->ent_challenge, index);
       }
-      else if( type == k_ent_challenge ){
-         if( challenge_count < vg_list_size(challenge_list) )
-            challenge_list[ challenge_count ++ ] = index;
+   }
+
+   if( active_challenge ){
+      shader_scene_fxglow_uUvOffset( (v2f){ 8.0f/256.0f, 0.0f } );
+      challenge_list[ challenge_count ++ ] = world_static.focused_entity;
+
+      u32 next = active_challenge->first;
+      while( mdl_entity_id_type(next) == k_ent_objective ){
+         u32 index = mdl_entity_id_id( next );
+         objective_list[ objective_count ++ ] = index;
+         
+         ent_objective *objective = mdl_arritm( &world->ent_objective, index );
+         next = objective->id_next;
+      }
+
+      radius = 10000.0f;
+   }
+   else {
+      shader_scene_fxglow_uUvOffset( (v2f){ 0.0f, 0.0f } );
+      bh_iter it;
+      bh_iter_init_range( 0, &it, pos, radius+10.0f );
+      i32 idx;
+      while( bh_next( world->entity_bh, &it, &idx ) ){
+         u32 id    = world->entity_list[ idx ],
+             type  = mdl_entity_id_type( id ),
+             index = mdl_entity_id_id( id );
+
+         if( type == k_ent_objective ) {
+            if( objective_count < vg_list_size(objective_list) )
+               objective_list[ objective_count ++ ] = index;
+         }
+         else if( type == k_ent_challenge ){
+            if( challenge_count < vg_list_size(challenge_list) )
+               challenge_list[ challenge_count ++ ] = index;
+         }
       }
    }
 
@@ -449,15 +486,31 @@ void world_render_challenges( world_instance *world, struct world_pass *pass,
    for( u32 i=0; i<objective_count; i++ ){
       u32 index = objective_list[ i ];
       ent_objective *objective = mdl_arritm( &world->ent_objective, index );
-      if( objective->flags & k_ent_objective_hidden ) continue;
+      if( (objective->flags & k_ent_objective_hidden) &&
+          !active_challenge ) continue;
 
-      f32 dist = v3_dist( objective->transform.co, pos ) * (1.0f/radius),
-          scale = vg_smoothstepf( vg_clampf( 5.0f-dist*5.0f, 0.0f,1.0f ) );
+      f32 scale = 1.0f;
 
-      v3_fill( objective->transform.s, scale );
+      if( running ){
+         u32 passed = objective->flags & k_ent_objective_passed;
+         f32 target = passed? 0.0f: 1.0f;
+         vg_slewf(&objective->transform.s[0], target, vg.time_frame_delta*4.0f);
+         scale = vg_smoothstepf( objective->transform.s[0] );
+
+         if( (objective == world_static.challenge_target) || passed )
+            shader_scene_fxglow_uUvOffset( (v2f){ 16.0f/256.0f, 0.0f } );
+         else
+            shader_scene_fxglow_uUvOffset( (v2f){ 8.0f/256.0f, 0.0f } );
+      }
+      else {
+         f32 dist = v3_dist( objective->transform.co, pos ) * (1.0f/radius);
+         scale = vg_smoothstepf( vg_clampf( 5.0f-dist*5.0f, 0.0f,1.0f ) );
+      }
 
       m4x3f mmdl;
-      mdl_transform_m4x3( &objective->transform, mmdl );
+      q_m3x3( objective->transform.q, mmdl );
+      m3x3_scalef( mmdl, scale );
+      v3_copy( objective->transform.co, mmdl[3] );
       shader_scene_fxglow_uMdl( mmdl );
 
       for( u32 j=0; j<objective->submesh_count; j++ ){
@@ -466,10 +519,8 @@ void world_render_challenges( world_instance *world, struct world_pass *pass,
 
          if( sm->material_id != last_material ){
             last_material = sm->material_id;
-
             pass->fn_bind_textures( world, &world->surfaces[sm->material_id] );
          }
-
          mdl_draw_submesh( sm );
       }
    }
@@ -505,7 +556,6 @@ void world_render_challenges( world_instance *world, struct world_pass *pass,
 
    for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
       ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i );
-      vg_line_point( challenge->transform.co, 0.2f, VG__GREEN );
       if( challenge->status ) count ++;
    }
 
@@ -519,6 +569,8 @@ void world_render_challenges( world_instance *world, struct world_pass *pass,
    m4x3f mlocal;
    m3x3_identity( mlocal );
    mlocal[3][0] = -w*0.5f;
+   mlocal[3][1] = 0.0f;
+   mlocal[3][2] = 0.0f;
 
    for( u32 i=0; i<challenge_count; i++ ){
       u32 index = challenge_list[ i ];
@@ -553,6 +605,7 @@ void world_render_challenges( world_instance *world, struct world_pass *pass,
 VG_STATIC void render_world_fxglow( world_instance *world, camera *cam,
                                     int layer_depth ){
    shader_scene_fxglow_use();
+   shader_scene_fxglow_uUvOffset( (v2f){ 0.0f, 0.0f } );
    shader_scene_fxglow_uTexMain(1);
    shader_scene_fxglow_uPv( cam->mtx.pv );
 
@@ -806,7 +859,7 @@ VG_STATIC void render_world( world_instance *world, camera *cam,
       glBlendEquation(GL_FUNC_ADD);
 
       shader_blitcolour_use();
-      shader_blitcolour_uColour( (v4f){ 0.5f, 0.5f, 0.5f, greyout*0.5f } );
+      shader_blitcolour_uColour( (v4f){ 0.5f, 0.5f, 0.5f, greyout*0.56f } );
       render_fsquad();
       
       glDisable(GL_BLEND);