add motion vectors to all shaders
authorhgn <hgodden00@gmail.com>
Thu, 1 Dec 2022 18:10:10 +0000 (18:10 +0000)
committerhgn <hgodden00@gmail.com>
Thu, 1 Dec 2022 18:10:10 +0000 (18:10 +0000)
52 files changed:
audio.h
build.c
camera.h
common.h
conf.h [new file with mode: 0644]
maps_src/mp_mtzero.mdl
menu.h
models_src/rs_menu.mdl
player.h
player_audio.h
player_physics.h
render.h
rigidbody.h
shaders/alphatest.h
shaders/blitblur.fs
shaders/blitblur.h
shaders/blitcolour.h [new file with mode: 0644]
shaders/common_world.glsl
shaders/gpos.h
shaders/menu.h
shaders/motion_vectors_fs.glsl [new file with mode: 0644]
shaders/motion_vectors_vs.glsl [new file with mode: 0644]
shaders/planeinf.h
shaders/route.fs
shaders/route.h
shaders/scoretext.h
shaders/scoretext.vs
shaders/sky.fs
shaders/sky.h
shaders/standard.fs
shaders/standard.h
shaders/standard.vs
shaders/standard_skinned.vs
shaders/std_alphatest.fs
shaders/terrain.fs
shaders/terrain.h
shaders/vblend.fs
shaders/vblend.h
shaders/viewchar.fs
shaders/viewchar.h
shaders/water.fs
shaders/water.h
shaders/water_fast.fs
shaders/water_fast.h
skaterift.c
world.h
world_gate.h
world_gen.h
world_render.h
world_routes.h
world_sfd.h
world_water.h

diff --git a/audio.h b/audio.h
index f13280be013e1a7c614c2778320c07ade983389b..8282c068183669efddbea0437be3fa96e56cdb10 100644 (file)
--- a/audio.h
+++ b/audio.h
@@ -305,7 +305,7 @@ VG_STATIC void audio_sample_occlusion( v3f origin )
 
    float occlusion = 1.0f - (d * (1.0f/(sample_dist*(float)sample_count))),
          rate = VG_TIMESTEP_FIXED * k_audio_occlusion_rate,
-         target = powf( occlusion, 6.0f );
+         target = powf( vg_maxf(occlusion,0.0f), 6.0f );
    audio_occlusion_current = vg_lerpf( audio_occlusion_current, target, rate );
 }
 
diff --git a/build.c b/build.c
index 053154fc6ed7555ece6b3abb5abd21d7eef5b5f5..61ac1c4caffa62ee2b63d81cc61ba85461dd8e96 100644 (file)
--- a/build.c
+++ b/build.c
@@ -118,23 +118,31 @@ void build_shaders(void)
 {
    vg_shader_set_include_dir( "shaders" );
 
+   // 2D
    _shader( "blit",      "shaders/blit.vs",      "shaders/blit.fs" );
    _shader( "blitblur",  "shaders/blit.vs",      "shaders/blitblur.fs" );
+   _shader( "blitcolour","shaders/blit.vs",      "shaders/colour.fs" );
+   _shader( "routeui",   "shaders/routeui.vs",   "shaders/routeui.fs" );
+   
+   // 3D Standard
    _shader( "standard",  "shaders/standard.vs",  "shaders/standard.fs" );
    _shader( "vblend",    "shaders/standard.vs",  "shaders/vblend.fs" );
+   _shader( "scoretext", "shaders/scoretext.vs", "shaders/vblend.fs" );
    _shader( "terrain",   "shaders/standard.vs",  "shaders/terrain.fs" );
-   _shader( "sky",       "shaders/standard.vs",  "shaders/sky.fs" );
-   _shader( "planeinf",  "shaders/standard.vs",  "shaders/planeinf.fs" );
-   _shader( "gpos",      "shaders/standard.vs",  "shaders/gpos.fs" );
-   _shader( "fscolour",  "shaders/blit.vs",      "shaders/colour.fs" );
    _shader( "alphatest", "shaders/standard.vs",  "shaders/std_alphatest.fs" );
-   _shader( "scoretext", "shaders/scoretext.vs", "shaders/vblend.fs" );
+   _shader( "route",     "shaders/standard.vs",  "shaders/route.fs" );
+   _shader( "menu",      "shaders/standard.vs",  "shaders/menu.fs" );
+   
+   // 3D Skinned
+   _shader( "viewchar",  "shaders/standard_skinned.vs", "shaders/viewchar.fs" );
+
+   // 3D extra/effects
+   _shader( "gpos",      "shaders/standard.vs",  "shaders/gpos.fs" );
+   _shader( "sky",       "shaders/standard.vs",  "shaders/sky.fs" );
    _shader( "water",     "shaders/standard.vs",  "shaders/water.fs" );
    _shader( "water_fast","shaders/standard.vs",  "shaders/water_fast.fs" );
-   _shader( "gate",      "shaders/gate.vs",      "shaders/gate.fs" );
    _shader( "gatelq",    "shaders/gate.vs",      "shaders/gate_lq.fs" );
-   _shader( "route",     "shaders/standard.vs",  "shaders/route.fs" );
-   _shader( "routeui",   "shaders/routeui.vs",   "shaders/routeui.fs" );
-   _shader( "viewchar",  "shaders/standard_skinned.vs", "shaders/viewchar.fs" );
-   _shader( "menu",      "shaders/standard.vs",  "shaders/menu.fs" );
+
+   //_shader( "planeinf",  "shaders/standard.vs",  "shaders/planeinf.fs" );
+   //_shader( "gate",      "shaders/gate.vs",      "shaders/gate.fs" );
 }
index 1c265a7515dd3bdf3209c9b9e5f1e9f791940e3f..596409937ceb3cf2f532c7d22f2c999533bd9fa7 100644 (file)
--- a/camera.h
+++ b/camera.h
 
 #include "common.h"
 
-VG_STATIC v2f camera_angles;
-VG_STATIC v3f camera_pos;
+typedef struct camera camera;
 
-VG_STATIC m4x3f camera_mtx,
-                camera_mtx_inverse;
+struct camera
+{
+   /* Input */
+   v2f angles;
+   v3f pos;
+   float fov, nearz, farz;
+
+   /* Output */
+   m4x3f transform,
+         transform_inverse;
 
-VG_STATIC void camera_update(void)
+   struct camera_mtx
+   {
+      m4x4f p,
+            v,
+            pv;
+   }
+   mtx,
+   mtx_prev;
+}
+VG_STATIC main_camera;
+
+/*
+ * 1) [angles, pos] -> transform 
+ */
+VG_STATIC void camera_update_transform( camera *cam )
 {
-   /* Update camera matrices */
    v4f qyaw, qpitch, qcam;
-   q_axis_angle( qyaw, (v3f){ 0.0f, 1.0f, 0.0f }, -camera_angles[0] );
-   q_axis_angle( qpitch, (v3f){ 1.0f, 0.0f, 0.0f }, -camera_angles[1] );
+   q_axis_angle( qyaw, (v3f){ 0.0f, 1.0f, 0.0f },   -cam->angles[0] );
+   q_axis_angle( qpitch, (v3f){ 1.0f, 0.0f, 0.0f }, -cam->angles[1] );
 
    q_mul( qyaw, qpitch, qcam );
-   q_m3x3( qcam, camera_mtx );
-   v3_copy( camera_pos, camera_mtx[3] );
+   q_m3x3( qcam, cam->transform );
+   v3_copy( cam->pos, cam->transform[3] );
+}
+
+/*
+ * 2) [transform] -> transform_inverse, view matrix
+ */
+VG_STATIC void camera_update_view( camera *cam )
+{
+   m4x4_copy( cam->mtx.v,  cam->mtx_prev.v );
+   m4x3_invert_affine( cam->transform, cam->transform_inverse );
+   m4x3_expand( cam->transform_inverse, cam->mtx.v );
+}
+
+/*
+ * 3) [fov,nearz,farz] -> projection matrix
+ */
+VG_STATIC void camera_update_projection( camera *cam )
+{
+   m4x4_copy( cam->mtx.p,  cam->mtx_prev.p );
+   m4x4_projection( cam->mtx.p, cam->fov,
+                    (float)vg.window_x / (float)vg.window_y, 
+                    cam->nearz, cam->farz );
+}
+
+/*
+ * 4) [projection matrix, view matrix] -> previous pv, new pv 
+ */
+VG_STATIC void camera_finalize( camera *cam )
+{
+   m4x4_copy( cam->mtx.pv, cam->mtx_prev.pv );
+   m4x4_mul( cam->mtx.p, cam->mtx.v, cam->mtx.pv );
+}
+
+/* 
+ * http://www.terathon.com/lengyel/Lengyel-Oblique.pdf 
+ */
+VG_STATIC void m4x4_clip_projection( m4x4f mat, v4f plane )
+{
+   v4f c = 
+   {
+      (vg_signf(plane[0]) + mat[2][0]) / mat[0][0],
+      (vg_signf(plane[1]) + mat[2][1]) / mat[1][1],
+      -1.0f,
+      (1.0f + mat[2][2]) / mat[3][2]
+   };
+
+   v4_muls( plane, 2.0f / v4_dot(plane,c), c );
 
-   m4x3_invert_affine( camera_mtx, camera_mtx_inverse );
+   mat[0][2] = c[0];
+   mat[1][2] = c[1];
+   mat[2][2] = c[2] + 1.0f;
+   mat[3][2] = c[3];
+}
+
+/*
+ * Undoes the above operation
+ */
+VG_STATIC void m4x4_reset_clipping( m4x4f mat, float ffar, float fnear )
+{
+   mat[0][2] = 0.0f; 
+   mat[1][2] = 0.0f; 
+   mat[2][2] = -(ffar + fnear) / (ffar - fnear); 
+   mat[3][2] = -2.0f * ffar * fnear / (ffar - fnear); 
 }
 
 #endif /* CAMERA_H */
index 2e254f9d22adb6849840618bf706aa1ffbc86696..bac81a78aa09ae898a0e018b9326d1fd9ab0632b 100644 (file)
--- a/common.h
+++ b/common.h
@@ -25,7 +25,6 @@ enum menu_controller_type
 };
 
 VG_STATIC enum menu_controller_type menu_display_controller;
-VG_STATIC float g_fov_option = 0.86f;
 
 typedef struct ray_hit ray_hit;
 struct ray_hit
diff --git a/conf.h b/conf.h
new file mode 100644 (file)
index 0000000..99d0e9f
--- /dev/null
+++ b/conf.h
@@ -0,0 +1,48 @@
+#ifndef CONF_H
+#define CONF_H
+
+#define VG_GAME
+#include "vg/vg.h"
+
+VG_STATIC float cl_fov              = 0.86f,
+                cl_volume           = 1.0f,
+                cl_blur_strength    = 2.0f;
+VG_STATIC int   cl_blur             = 1,
+                cl_playermdl_id     = 0;
+
+VG_STATIC void g_conf_init(void)
+{
+   vg_convar_push( (struct vg_convar){
+      .name = "cl_fov",
+      .data = &cl_fov,
+      .data_type = k_convar_dtype_f32,
+      .opt_f32 = { .clamp = 0 },
+      .persistent = 1
+   });
+
+   vg_convar_push( (struct vg_convar){
+      .name = "cl_blur_strength",
+      .data = &cl_blur_strength,
+      .data_type = k_convar_dtype_f32,
+      .opt_f32 = { .clamp = 0 },
+      .persistent = 1
+   });
+
+   vg_convar_push( (struct vg_convar){
+      .name = "cl_blur",
+      .data = &cl_blur,
+      .data_type = k_convar_dtype_i32,
+      .opt_i32 = { .min=0, .max=1, .clamp=1 },
+      .persistent = 1
+   });
+
+   vg_convar_push( (struct vg_convar){
+      .name = "cl_playermdl_id",
+      .data = &cl_playermdl_id,
+      .data_type = k_convar_dtype_i32,
+      .opt_i32 = { .min=0, .max=2, .clamp=1 },
+      .persistent = 1
+   });
+}
+
+#endif /* CONF_H */
index d7ed5d467bf5668af3f124e6c65e61c4858a3ab3..24c3c03ee5839ee03a68daab252a8f17be481c13 100644 (file)
Binary files a/maps_src/mp_mtzero.mdl and b/maps_src/mp_mtzero.mdl differ
diff --git a/menu.h b/menu.h
index e52f3d7faa8265a34d37aea146ee7a55ea0085ca..1b73beab3e35777b03c55cb3825d6b2517818d74 100644 (file)
--- a/menu.h
+++ b/menu.h
@@ -36,6 +36,7 @@ VG_STATIC struct input_binding input_menu_h,
 
 VG_STATIC void menu_btn_quit( int event );
 VG_STATIC void menu_btn_skater( int event );
+VG_STATIC void menu_btn_blur( int event );
 VG_STATIC void menu_btn_fuckoff( int event );
 VG_STATIC void menu_btn_reset( int event );
 VG_STATIC void menu_btn_map( int event );
@@ -43,7 +44,10 @@ VG_STATIC void menu_btn_settings( int event );
 
 VG_STATIC mdl_node *menu_pnode_fov_slider,
                    *menu_pnode_fov_min,
-                   *menu_pnode_fov_max;
+                   *menu_pnode_fov_max,
+                   *menu_pnode_vol_slider,
+                   *menu_pnode_vol_min,
+                   *menu_pnode_vol_max;
 
 struct
 {
@@ -72,25 +76,46 @@ enum menu_page
    k_menu_page_map      = 0x10
 };
 
-VG_STATIC int menu_vis( int group_mask )
+struct menu_btn_userdata
 {
-   if( group_mask & game_menu.page )
+   union
+   {
+      int   i;
+      void *ptr_generic;
+   };
+};
+
+VG_STATIC int menu_settings_if( struct menu_btn_userdata ud )
+{
+   if( game_menu.page & k_menu_page_settings )
+   {
+      int *ptr = ud.ptr_generic;
+      return *ptr;
+   }
+   else
+      return 0;
+}
+
+VG_STATIC int menu_vis( struct menu_btn_userdata ud )
+{
+   if( ud.i & game_menu.page )
       return 1;
    else
       return 0;
 }
 
-VG_STATIC int menu_controller( int ctr )
+VG_STATIC int menu_controller( struct menu_btn_userdata ud )
 {
    if( (game_menu.page & (k_menu_page_main|k_menu_page_settings)) 
-         && (ctr == menu_display_controller) )
+         && (ud.i == menu_display_controller) )
       return 1;
    return 0;
 }
 
-VG_STATIC int menu_controller_inf( int ctr )
+VG_STATIC int menu_controller_inf( struct menu_btn_userdata ud )
 {
-   if( (game_menu.page & k_menu_page_settings) && (ctr == menu_display_controller) )
+   if( (game_menu.page & k_menu_page_settings) 
+        && (ud.i == menu_display_controller) )
       return 1;
    return 0;
 }
@@ -99,8 +124,8 @@ struct menu_button
 {
    const char *name;
 
-   int (*fn_visibility)( int user );
-   int   user;
+   int (*fn_visibility)( struct menu_btn_userdata ud );
+   struct menu_btn_userdata user;
 
    void (*fn_press)( int event );
 
@@ -115,59 +140,77 @@ struct menu_button
 VG_STATIC menu_buttons[] = 
 {
 { 
-   "text_quit", menu_vis, k_menu_page_main|k_menu_page_quit,   
+   "text_quit", menu_vis, {.i=k_menu_page_main|k_menu_page_quit},   
    .fn_press = menu_btn_quit,
       .ld="text_reset", .lr="text_settings", .ll="text_map"
 },
    {
-      "text_quitty", menu_vis, k_menu_page_quit
+      "text_quitty", menu_vis, {.i=k_menu_page_quit}
    },
    {
-      "text_yes", menu_vis, k_menu_page_quit,
+      "text_yes", menu_vis, {.i=k_menu_page_quit},
          .fn_press = menu_btn_fuckoff
    },
 {
-   "text_reset", menu_vis, k_menu_page_main,
+   "text_reset", menu_vis, {.i=k_menu_page_main},
    .fn_press = menu_btn_reset,
       .lu="text_quit", .ld="text_skater", .ll="text_map", .lr="text_settings"
 },
 {  
-   "text_skater", menu_vis, k_menu_page_main|k_menu_page_skater
+   "text_skater", menu_vis, {.i=k_menu_page_main|k_menu_page_skater}
    .fn_press = menu_btn_skater,
       .lu="text_reset", .ll="text_map", .lr="text_settings"
 },
 {
-   "text_map", menu_vis, k_menu_page_main,
+   "text_map", menu_vis, {.i=k_menu_page_main},
    .fn_press = menu_btn_map,
-      .lr="text_skater"
+      .lr="text_reset"
 },
 {
-   "text_settings", menu_vis, k_menu_page_main|k_menu_page_settings,
+   "text_settings", menu_vis, {.i=k_menu_page_main|k_menu_page_settings},
    .fn_press = menu_btn_settings,
-      .ll="text_skater"
+      .ll="text_reset"
+},
+{
+   "skater_left", menu_vis, {k_menu_page_skater}
 },
 {
-   "skater_left", menu_vis, k_menu_page_skater
+   "skater_right", menu_vis, {k_menu_page_skater}
+},
+
+{ 
+   "fov_slider",     menu_vis, {k_menu_page_settings},
+   .ld="text_blur" 
+},
+{ "fov_info",        menu_vis, {k_menu_page_settings} },
+
+{ 
+   "vol_slider",     menu_vis, {k_menu_page_settings},
+   .lu="text_blur"
+},
+{ "vol_info",        menu_vis, {k_menu_page_settings} },
+
+{ 
+   "text_blur",      menu_vis, {k_menu_page_settings},
+   .fn_press = menu_btn_blur, 
+   .lu="fov_slider", .ld="vol_slider"
 },
 {
-   "skater_right", menu_vis, k_menu_page_skater
+   "text_blur_check", menu_settings_if, {.ptr_generic=&cl_blur} 
 },
 
-{ "fov_slider",      menu_vis, k_menu_page_settings },
-{ "fov_info",        menu_vis, k_menu_page_settings },
-
-{ "ctr_xbox",        menu_controller_inf, k_menu_controller_type_xbox, },
-{ "ctr_xbox_text",   menu_controller_inf, k_menu_controller_type_xbox },
-{ "ctr_steam",       menu_controller_inf, k_menu_controller_type_steam },
-{ "ctr_steam_text",  menu_controller_inf, k_menu_controller_type_steam },
-{ "ctr_deck",        menu_controller_inf, k_menu_controller_type_steam_deck },
-{ "ctr_deck_text",   menu_controller_inf, k_menu_controller_type_steam_deck },
-{ "ctr_ps",          menu_controller_inf, k_menu_controller_type_playstation },
-{ "ctr_ps_text",     menu_controller_inf, k_menu_controller_type_playstation },
-{ "ctr_kbm",         menu_controller_inf, k_menu_controller_type_keyboard },
-{ "ctr_kbm_text",    menu_controller_inf, k_menu_controller_type_keyboard },
-{
-   "text_paused", menu_vis, k_menu_page_main 
+{ "ctr_xbox",        menu_controller_inf, {k_menu_controller_type_xbox}},
+{ "ctr_xbox_text",   menu_controller_inf, {k_menu_controller_type_xbox}},
+{ "ctr_steam",       menu_controller_inf, {k_menu_controller_type_steam}},
+{ "ctr_steam_text",  menu_controller_inf, {k_menu_controller_type_steam}},
+{ "ctr_deck",        menu_controller_inf, {k_menu_controller_type_steam_deck}},
+{ "ctr_deck_text",   menu_controller_inf, {k_menu_controller_type_steam_deck}},
+{ "ctr_ps",          menu_controller_inf, {k_menu_controller_type_playstation}},
+{ "ctr_ps_text",     menu_controller_inf, {k_menu_controller_type_playstation}},
+{ "ctr_kbm",         menu_controller_inf, {k_menu_controller_type_keyboard}},
+{ "ctr_kbm_text",    menu_controller_inf, {k_menu_controller_type_keyboard}},
+{
+   "text_paused", menu_vis, {k_menu_page_main} 
 },
 };
 
@@ -212,6 +255,11 @@ VG_STATIC void menu_btn_skater( int event )
    game_menu.page = k_menu_page_skater;
 }
 
+VG_STATIC void menu_btn_blur( int event )
+{
+   cl_blur ^= 0x1;
+}
+
 VG_STATIC void menu_btn_map( int event )
 {
    game_menu.page = k_menu_page_map;
@@ -336,12 +384,18 @@ VG_STATIC void menu_init(void)
       btn->pnode = mdl_node_from_name( &menu_model, btn->name );
 
       if( !btn->pnode )
+      {
+         vg_info( "info: %s\n", btn->name );
          vg_fatal_exit_loop( "Menu programming error" );
+      }
    }
 
    menu_pnode_fov_max = mdl_node_from_name( &menu_model, "fov_slider_max" );
    menu_pnode_fov_min = mdl_node_from_name( &menu_model, "fov_slider_min" );
    menu_pnode_fov_slider = mdl_node_from_name( &menu_model, "fov_slider" );
+   menu_pnode_vol_max = mdl_node_from_name( &menu_model, "vol_slider_max" );
+   menu_pnode_vol_min = mdl_node_from_name( &menu_model, "vol_slider_min" );
+   menu_pnode_vol_slider = mdl_node_from_name( &menu_model, "vol_slider" );
 
    shader_menu_register();
 
@@ -531,17 +585,36 @@ VG_STATIC void menu_page_skater(void)
    }
 }
 
-VG_STATIC void menu_page_settings(void)
+VG_STATIC void menu_slider( float *value, float min, float max,
+                            mdl_node *slider, mdl_node *pmin, mdl_node *pmax )
 {
    float h = input_menu_h.axis.value;
+
    if( fabsf(h) > 0.04f )
-      g_fov_option += h * vg.frame_delta;
-   g_fov_option = vg_clampf( g_fov_option, 0.0f, 1.0f );
+      *value += h * vg.frame_delta;
+   *value = vg_clampf( *value, min, max );
+
+   v3_lerp( pmin->co, pmax->co, *value, slider->co );
+}
+
+VG_STATIC void menu_page_settings(void)
+{
+   menu_run_directional();
 
-   v3_lerp( menu_pnode_fov_min->co, menu_pnode_fov_max->co, g_fov_option,
-            menu_pnode_fov_slider->co );
+   if( game_menu.loc == menu_get_loc( "fov_slider" ) )
+   {
+      menu_slider( &cl_fov, 0.0f, 1.0f, 
+                     menu_pnode_fov_slider, menu_pnode_fov_min,
+                     menu_pnode_fov_max );
 
-   menu_fov_target = vg_lerpf( 97.0f, 135.0f, g_fov_option ) * 0.8f;
+      menu_fov_target = vg_lerpf( 97.0f, 135.0f, cl_fov ) * 0.8f;
+   }
+   else if( game_menu.loc == menu_get_loc( "vol_slider" ) )
+   {
+      menu_slider( &cl_volume, 0.0f, 1.0f, 
+                     menu_pnode_vol_slider, menu_pnode_vol_min,
+                     menu_pnode_vol_max );
+   }
 
    if( menu_page_should_backout() )
    {
@@ -656,10 +729,13 @@ VG_STATIC void menu_update(void)
    
    /* Update camera */
    {
-      camera_angles[0] = vg_alerpf( camera_angles[0], angles[0], menu_opacity );
-      camera_angles[1] = vg_lerpf ( camera_angles[1], angles[1], menu_opacity );
-      v3_lerp( camera_pos, pos, menu_opacity, camera_pos );
-      camera_update();
+      main_camera.angles[0] = 
+         vg_alerpf( main_camera.angles[0], angles[0], menu_opacity );
+      main_camera.angles[1] = 
+         vg_lerpf ( main_camera.angles[1], angles[1], menu_opacity );
+      v3_lerp( main_camera.pos, pos, menu_opacity, main_camera.pos );
+
+      camera_update_transform( &main_camera );
    }
 
    float dt = vg.frame_delta * 6.0f;
@@ -686,7 +762,7 @@ float expSustainedImpulse( float x, float f, float k )
     return fminf( x*x/(f*f), 1.0f+(2.0f/f)*s*expf(-k*s));
 }
 
-VG_STATIC void menu_render( m4x4f projection )
+VG_STATIC void menu_render( camera *cam )
 {
    glEnable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
@@ -707,7 +783,8 @@ VG_STATIC void menu_render( m4x4f projection )
    shader_menu_uTexMain( 1 );
    vg_tex2d_bind( &tex_menu, 1 );
 
-   shader_menu_uPv( projection );
+   shader_menu_uPv( cam->mtx.pv );
+   shader_menu_uPvmPrev( cam->mtx_prev.pv );
    mesh_bind( &menu_glmesh );
 
    for( int i=0; i<vg_list_size(menu_buttons); i++ )
index 8559fb3e8e145d7ce87e05abc3b92e8ea682a6ab..280af97a17523f671cff1de985ec4a1f676022b8 100644 (file)
Binary files a/models_src/rs_menu.mdl and b/models_src/rs_menu.mdl differ
index 7b5eeaa882158316eb7c9befe4f91700679cdb8a..c98f10c83654c9744c2e51802cdc2b7223dfd8e1 100644 (file)
--- a/player.h
+++ b/player.h
@@ -11,6 +11,7 @@
 
 #define PLAYER_REWIND_FRAMES 60*4
 
+#include "conf.h"
 #include "audio.h"
 #include "common.h"
 #include "world.h"
@@ -44,7 +45,6 @@ VG_STATIC float
    k_walk_accel            = 150.0f,
    k_walk_friction         = 8.0f;
 
-VG_STATIC int cl_playermdl_id = 0;
 VG_STATIC int freecam = 0;
 VG_STATIC int walk_grid_iterations = 1;
 VG_STATIC float fc_speed = 10.0f;
@@ -299,14 +299,6 @@ VG_STATIC void player_init(void)                                            /* 1
    rb_init( &player.collide_front );
    rb_init( &player.collide_back  );
 
-   vg_convar_push( (struct vg_convar){
-      .name = "cl_playermdl_id",
-      .data = &cl_playermdl_id,
-      .data_type = k_convar_dtype_i32,
-      .opt_i32 = { .min=0, .max=2, .clamp=1 },
-      .persistent = 1
-   });
-
    vg_convar_push( (struct vg_convar){
       .name = "gwalk_speed",
       .data = &k_walkspeed,
@@ -595,8 +587,8 @@ VG_STATIC void player_update_post(void)
 
 
    /* CAMERA POSITIONING: LAYER 0 */
-   v2_copy( player.angles, camera_angles );
-   v3_copy( player.camera_pos, camera_pos );
+   v2_copy( player.angles, main_camera.angles );
+   v3_copy( player.camera_pos, main_camera.pos );
 
    if( player.rewinding )
    {
@@ -687,8 +679,6 @@ VG_STATIC void player_update_post(void)
                   player.rewind_sound_wait = 0;
                }
             }
-
-
          }
          
          int i0 = floorf( player.rewind_time ),
@@ -707,17 +697,19 @@ VG_STATIC void player_update_post(void)
          float blend = (4.0f-player.rewind_time) * 0.25f,
                c     = vg_clampf( blend, 0.0f, 1.0f );
 
-         camera_angles[0] = vg_alerpf(override_angles[0], player.angles[0], c);
-         camera_angles[1] = vg_lerpf (override_angles[1], player.angles[1], c);
-         v3_lerp( override_pos, player.camera_pos, c, camera_pos );
+         main_camera.angles[0] = 
+            vg_alerpf(override_angles[0], player.angles[0], c);
+         main_camera.angles[1] = 
+            vg_lerpf (override_angles[1], player.angles[1], c);
+         v3_lerp( override_pos, player.camera_pos, c, main_camera.pos );
       }
    }
 
-   camera_update();
+   camera_update_transform( &main_camera );
    player_audio();
 }
 
-VG_STATIC void draw_player( m4x3f cam )
+VG_STATIC void draw_player( camera *cam )
 {
    if( player.is_dead )
       player_model_copy_ragdoll();
@@ -725,8 +717,8 @@ VG_STATIC void draw_player( m4x3f cam )
    shader_viewchar_use();
    vg_tex2d_bind( &tex_characters, 0 );
    shader_viewchar_uTexMain( 0 );
-   shader_viewchar_uCamera( cam[3] );
-   shader_viewchar_uPv( vg.pv );
+   shader_viewchar_uCamera( cam->transform[3] );
+   shader_viewchar_uPv( cam->mtx.pv );
    shader_link_standard_ub( _shader_viewchar.id, 2 );
    glUniformMatrix4x3fv( _uniform_viewchar_uTransforms, 
                          player.mdl.sk.bone_count,
index 3c86e3bde847df75fbccdea7e9701e95e909e29e..8e5c0d2c83e7affb77a30396380bde604e7e05f1 100644 (file)
@@ -53,7 +53,7 @@ VG_STATIC void player_audio(void)
    v3f ears = { 1.0f,0.0f,0.0f };
    v3f delta;
 
-   float *cam = camera_pos,
+   float *cam = main_camera.transform[3],
          *pos = phys->rb.co;
    
    audio_player_set_position( &audio_player0, phys->rb.co );
@@ -63,16 +63,16 @@ VG_STATIC void player_audio(void)
    audio_player_set_position( &audio_player_gate, world.render_gate_pos );
    audio_player_set_vol( &audio_player_gate, 5.0f );
 
-   v3_sub( phys->rb.co, camera_pos, delta );
+   v3_sub( phys->rb.co, main_camera.transform[3], delta );
    v3_normalize( delta );
-   m3x3_mulv( camera_mtx, ears, ears );
+   m3x3_mulv( main_camera.transform, ears, ears );
 
    /* TODO, Make function */
    v3_copy( ears, vg_audio.listener_ears );
-   v3_copy( camera_pos, vg_audio.listener_pos );
+   v3_copy( main_camera.transform[3], vg_audio.listener_pos );
 
    /* Tunnel / occlusion */
-   audio_sample_occlusion( camera_pos );
+   audio_sample_occlusion( main_camera.transform[3] );
 
    int sprite_avail = -1;
    for( int i=0; i<vg_list_size(ambient_sprites); i++ )
index 86f49a0f34a824554f25d409e8cc23879cb824aa..f395953932e19003e93cac528d76c538cb99531e 100644 (file)
@@ -980,11 +980,12 @@ VG_STATIC void player_do_motion(void)
          phys->grind = 1;
          v3f up = { 0.0f, 1.0f, 0.0f };
          float angle = v3_dot( phys->rb.up, up );
-         v3f axis; 
-         v3_cross( phys->rb.up, up, axis );
 
          if( fabsf(angle) < 0.99f )
          {
+            v3f axis; 
+            v3_cross( phys->rb.up, up, axis );
+
             v4f correction;
             q_axis_angle( correction, axis, 
                   VG_TIMESTEP_FIXED * 10.0f * acosf(angle) );
@@ -1130,8 +1131,8 @@ VG_STATIC void player_freecam(void)
    v3f lookdir = { 0.0f, 0.0f, -1.0f },
        sidedir = { 1.0f, 0.0f,  0.0f };
    
-   m3x3_mulv( camera_mtx, lookdir, lookdir );
-   m3x3_mulv( camera_mtx, sidedir, sidedir );
+   m3x3_mulv( main_camera.transform, lookdir, lookdir );
+   m3x3_mulv( main_camera.transform, sidedir, sidedir );
    
    static v3f move_vel = { 0.0f, 0.0f, 0.0f };
 
@@ -1193,6 +1194,13 @@ VG_STATIC int reset_player( int argc, char const *argv[] )
    if( !rp )
    {
       vg_error( "No spawn found\n" );
+      vg_info( "Player position: %f %f %f\n", player.phys.rb.co[0],
+                                              player.phys.rb.co[1],
+                                              player.phys.rb.co[2] );
+      vg_info( "Player velocity: %f %f %f\n", player.phys.rb.v[0],
+                                              player.phys.rb.v[1],
+                                              player.phys.rb.v[2] );
+
       if( !world.spawn_count )
          return 0;
 
index 33998221b83ea206f6ee8c0d90f44d1c4abe35b3..58c88311d76af42a6a6c7860af46f2224db3a9f8 100644 (file)
--- a/render.h
+++ b/render.h
@@ -4,17 +4,18 @@
 
 #include "common.h"
 #include "model.h"
+#include "camera.h"
 
 #include "shaders/blit.h"
 #include "shaders/blitblur.h"
 #include "shaders/standard.h"
 #include "shaders/vblend.h"
 
-VG_STATIC void render_water_texture( m4x3f camera );
-VG_STATIC void render_water_surface( m4x4f pv, m4x3f camera );
-VG_STATIC void render_world( m4x4f projection, m4x3f camera );
+VG_STATIC void render_water_texture( camera *cam );
+VG_STATIC void render_water_surface( camera *cam );
+VG_STATIC void render_world( camera *cam );
 VG_STATIC void shader_link_standard_ub( GLuint shader, int texture_id );
-VG_STATIC void render_world_depth( m4x4f projection, m4x3f camera );
+VG_STATIC void render_world_depth( camera *cam );
 
 #ifndef RENDER_H
 #define RENDER_H
@@ -28,13 +29,20 @@ struct framebuffer
    int allocated;
 };
 
+/* 
+ * All standard buffers used in rendering
+ */
 VG_STATIC struct pipeline
 {
+#if 0
    float fov;
+#endif
    glmesh fsquad;
 
    GLuint fb_background,
-          rgb_background;
+          rgb_background,
+          mv_background,
+          rb_background;
 
    /* STD140 */
    struct ub_world_lighting
@@ -99,38 +107,6 @@ gpipeline =
    }
 };
 
-/* 
- * Matrix Projections
- */
-/* 
- * http://www.terathon.com/lengyel/Lengyel-Oblique.pdf 
- */
-VG_STATIC void plane_clip_projection( m4x4f mat, v4f plane )
-{
-   v4f c = 
-   {
-      (vg_signf(plane[0]) + mat[2][0]) / mat[0][0],
-      (vg_signf(plane[1]) + mat[2][1]) / mat[1][1],
-      -1.0f,
-      (1.0f + mat[2][2]) / mat[3][2]
-   };
-
-   v4_muls( plane, 2.0f / v4_dot(plane,c), c );
-
-   mat[0][2] = c[0];
-   mat[1][2] = c[1];
-   mat[2][2] = c[2] + 1.0f;
-   mat[3][2] = c[3];
-}
-
-VG_STATIC void pipeline_projection( m4x4f mat, float nearz, float farz )
-{
-   m4x4_projection( mat,
-         gpipeline.fov,
-         (float)vg.window_x / (float)vg.window_y, 
-         nearz, farz );
-}
-
 /*
  * Shaders
  */
@@ -189,7 +165,7 @@ VG_STATIC void fb_use( struct framebuffer *fb )
 {
    if( !fb )
    {
-      glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+      glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_background );
       glViewport( 0, 0, vg.window_x, vg.window_y );
    }
    else
@@ -264,13 +240,14 @@ VG_STATIC void render_fb_resize(void)
       glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
       glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg.window_x, vg.window_y, 0, 
             GL_RGB, GL_UNSIGNED_BYTE, NULL );
+
+      /* FIXME: Resizeother textures and rb */
    }
 }
 
-/* used for drawing player onto */
 VG_STATIC void render_init_temp_buffer(void)
 {
-   vg_info( "[render] Allocate temporary framebuffer\n" );
+   vg_info( "[render] Allocate framebuffer\n" );
 
    glGenFramebuffers( 1, &gpipeline.fb_background );
    glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_background );
@@ -278,16 +255,58 @@ VG_STATIC void render_init_temp_buffer(void)
    glGenTextures( 1, &gpipeline.rgb_background );
    glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg.window_x, vg.window_y, 
-         0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
-
+                                0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
    glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
          GL_TEXTURE_2D, 
-         gpipeline.rgb_background, 0);
+         gpipeline.rgb_background, 0 );
 
+   glGenTextures( 1, &gpipeline.mv_background );
+   glBindTexture( GL_TEXTURE_2D, gpipeline.mv_background );
+#if 0
+   glTexImage2D( GL_TEXTURE_2D, 0, GL_RG, vg.window_x, vg.window_y, 
+                                0, GL_RG, GL_FLOAT, NULL);
+#endif
+   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA16F, vg.window_x, vg.window_y, 
+                                0, GL_RGBA, GL_FLOAT, NULL);
+
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+       glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+   glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, 
+         GL_TEXTURE_2D, 
+         gpipeline.mv_background, 0 );
+
+   /* render buffer */
+   glGenRenderbuffers( 1, &gpipeline.rb_background );
+   glBindRenderbuffer( GL_RENDERBUFFER, gpipeline.rb_background );
+   glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
+                          vg.window_x, vg.window_y );
+   glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+                              GL_RENDERBUFFER, gpipeline.rb_background );
+
+   GLuint attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
+   glDrawBuffers( 2, attachments );
+
+   GLenum result = glCheckFramebufferStatus( GL_FRAMEBUFFER );
+
+   if( result != GL_FRAMEBUFFER_COMPLETE )
+   {
+      if( result == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT )
+         vg_fatal_exit_loop( "Main RT: Incomplete attachment" );
+      else if( result == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT )
+         vg_fatal_exit_loop( "Main RT: Missing attachment" );
+      else if( result == GL_FRAMEBUFFER_UNSUPPORTED )
+         vg_fatal_exit_loop( "Main RT: Unsupported framebuffer format" );
+      else
+         vg_fatal_exit_loop( "Main RT: Generic Error" );
+   }
+
+   glBindFramebuffer( GL_FRAMEBUFFER, 0 );
    VG_CHECK_GL_ERR();
 }
 
index 16d38ea0df86d5003039acc09d2a4563e9151995..83d32c7eccda75eb841193bd59b9307375589ba8 100644 (file)
@@ -446,6 +446,13 @@ VG_STATIC void rb_init( rigidbody *rb )
 
 VG_STATIC void rb_iter( rigidbody *rb )
 {
+   if( isnanf( rb->v[0] ) ||
+       isnanf( rb->v[1] ) ||
+       isnanf( rb->v[2] ) )
+   {
+      vg_fatal_exit_loop( "NaN velocity" );
+   }
+
    v3f gravity = { 0.0f, -9.8f, 0.0f };
    v3_muladds( rb->v, gravity, k_rb_delta, rb->v );
 
index 13d11ae4c47834fcedc2562d0ca8795eeece3770..d5c38d0a7755fc2d8f2e82d0fa091e4261e91c95 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_alphatest = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
@@ -28,20 +40,23 @@ static struct vg_shader _shader_alphatest = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
 {
 .static_src = 
-"out vec4 FragColor;\n"
-"\n"
 "uniform sampler2D uTexGarbage;\n"
 "uniform sampler2D uTexMain;\n"
 "uniform vec3 uCamera;\n"
@@ -54,6 +69,8 @@ static struct vg_shader _shader_alphatest = {
 "in vec3 aWorldCo;\n"
 "\n"
 "#line       1        1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
 "layout (std140) uniform ub_world_lighting\n"
 "{\n"
 "   vec4 g_light_colours[3];\n"
@@ -157,10 +174,27 @@ static struct vg_shader _shader_alphatest = {
 "   return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
 "}\n"
 "\n"
-"#line     15        0 \n"
+"#line     13        0 \n"
+"#line       1        2 \n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"   oMotionVec = vmotion1-vmotion0;\n"
+"}\n"
+"\n"
+"#line     14        0 \n"
 "\n"
 "void main()\n"
 "{\n"
+"   compute_motion_vectors();\n"
+"\n"
 "   vec3 vfrag = vec3(0.5,0.5,0.5);\n"
 "   vec4 vsamplemain = texture( uTexMain, aUv );\n"
 "   vec3 qnorm = normalize(aNorm);\n"
@@ -185,13 +219,14 @@ static struct vg_shader _shader_alphatest = {
 "   vfrag = do_light_shadowing( vfrag );\n"
 "   vfrag = apply_fog( vfrag, fdist );\n"
 "\n"
-"   FragColor = vec4(vfrag, 1.0);\n"
+"   oColour = vec4(vfrag, 1.0);\n"
 "}\n"
 ""},
 };
 
 static GLuint _uniform_alphatest_uMdl;
 static GLuint _uniform_alphatest_uPv;
+static GLuint _uniform_alphatest_uPvmPrev;
 static GLuint _uniform_alphatest_uTexGarbage;
 static GLuint _uniform_alphatest_uTexMain;
 static GLuint _uniform_alphatest_uCamera;
@@ -203,6 +238,9 @@ static void shader_alphatest_uMdl(m4x3f m){
 static void shader_alphatest_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_alphatest_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_alphatest_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_alphatest_uPvmPrev,1,GL_FALSE,(float*)m);
+}
 static void shader_alphatest_uTexGarbage(int i){
    glUniform1i(_uniform_alphatest_uTexGarbage,i);
 }
@@ -225,6 +263,7 @@ static void shader_alphatest_use(void){ glUseProgram(_shader_alphatest.id); }
 static void shader_alphatest_link(void){
    _uniform_alphatest_uMdl = glGetUniformLocation( _shader_alphatest.id, "uMdl" );
    _uniform_alphatest_uPv = glGetUniformLocation( _shader_alphatest.id, "uPv" );
+   _uniform_alphatest_uPvmPrev = glGetUniformLocation( _shader_alphatest.id, "uPvmPrev" );
    _uniform_alphatest_uTexGarbage = glGetUniformLocation( _shader_alphatest.id, "uTexGarbage" );
    _uniform_alphatest_uTexMain = glGetUniformLocation( _shader_alphatest.id, "uTexMain" );
    _uniform_alphatest_uCamera = glGetUniformLocation( _shader_alphatest.id, "uCamera" );
index eac828e5e03b700127611dac7160d1235cbd5f00..860602281395bd57df0aacc669df7d6d28d0e518 100644 (file)
@@ -1,5 +1,8 @@
 out vec4 FragColor;
 uniform sampler2D uTexMain;
+uniform sampler2D uTexMotion;
+uniform float uBlurStrength;
+uniform float uBlurExponent;
 
 in vec2 aUv;
 
@@ -12,10 +15,16 @@ vec2 rand_hash22( vec2 p )
 
 void main()
 {
-   vec2 voffset = rand_hash22( aUv );
+   vec2 vcenter = (aUv-vec2(0.5))*vec2(2.0);
+   vec2 vrand = rand_hash22( aUv ) * 2.0 - vec2(1.0);
+   vec2 vrand1 = rand_hash22( vrand ) * 2.0 - vec2(1.0);
    
-   float bamt = abs(aUv.x-0.5)*2.0;
-   bamt = pow(bamt,4.0)*0.05;
+   vec2 vdir = texture( uTexMotion, aUv ).xy * uBlurStrength;
 
-   FragColor = texture( uTexMain, aUv + voffset*bamt );
+   vec4 vcolour0 = texture( uTexMain, aUv + vdir*vrand.x );
+   vec4 vcolour1 = texture( uTexMain, aUv + vdir*vrand.y );
+   vec4 vcolour2 = texture( uTexMain, aUv + vdir*vrand1.x );
+   vec4 vcolour3 = texture( uTexMain, aUv + vdir*vrand1.y );
+
+   FragColor = ( vcolour0 + vcolour1 + vcolour2 + vcolour3 ) * 0.25;
 }
index b754d12c965b18c5b0018d9755be8f5827edb606..e341cea2827f586283432bbcbd731a01255d6c04 100644 (file)
@@ -22,6 +22,9 @@ static struct vg_shader _shader_blitblur = {
 .static_src = 
 "out vec4 FragColor;\n"
 "uniform sampler2D uTexMain;\n"
+"uniform sampler2D uTexMotion;\n"
+"uniform float uBlurStrength;\n"
+"uniform float uBlurExponent;\n"
 "\n"
 "in vec2 aUv;\n"
 "\n"
@@ -34,25 +37,46 @@ static struct vg_shader _shader_blitblur = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec2 voffset = rand_hash22( aUv );\n"
+"   vec2 vcenter = (aUv-vec2(0.5))*vec2(2.0);\n"
+"   vec2 vrand = rand_hash22( aUv ) * 2.0 - vec2(1.0);\n"
+"   vec2 vrand1 = rand_hash22( vrand ) * 2.0 - vec2(1.0);\n"
 "   \n"
-"   float bamt = abs(aUv.x-0.5)*2.0;\n"
-"   bamt = pow(bamt,4.0)*0.05;\n"
+"   vec2 vdir = texture( uTexMotion, aUv ).xy * uBlurStrength;\n"
 "\n"
-"   FragColor = texture( uTexMain, aUv + voffset*bamt );\n"
+"   vec4 vcolour0 = texture( uTexMain, aUv + vdir*vrand.x );\n"
+"   vec4 vcolour1 = texture( uTexMain, aUv + vdir*vrand.y );\n"
+"   vec4 vcolour2 = texture( uTexMain, aUv + vdir*vrand1.x );\n"
+"   vec4 vcolour3 = texture( uTexMain, aUv + vdir*vrand1.y );\n"
+"\n"
+"   FragColor = ( vcolour0 + vcolour1 + vcolour2 + vcolour3 ) * 0.25;\n"
 "}\n"
 ""},
 };
 
 static GLuint _uniform_blitblur_uTexMain;
+static GLuint _uniform_blitblur_uTexMotion;
+static GLuint _uniform_blitblur_uBlurStrength;
+static GLuint _uniform_blitblur_uBlurExponent;
 static void shader_blitblur_uTexMain(int i){
    glUniform1i(_uniform_blitblur_uTexMain,i);
 }
+static void shader_blitblur_uTexMotion(int i){
+   glUniform1i(_uniform_blitblur_uTexMotion,i);
+}
+static void shader_blitblur_uBlurStrength(float f){
+   glUniform1f(_uniform_blitblur_uBlurStrength,f);
+}
+static void shader_blitblur_uBlurExponent(float f){
+   glUniform1f(_uniform_blitblur_uBlurExponent,f);
+}
 static void shader_blitblur_register(void){
    vg_shader_register( &_shader_blitblur );
 }
 static void shader_blitblur_use(void){ glUseProgram(_shader_blitblur.id); }
 static void shader_blitblur_link(void){
    _uniform_blitblur_uTexMain = glGetUniformLocation( _shader_blitblur.id, "uTexMain" );
+   _uniform_blitblur_uTexMotion = glGetUniformLocation( _shader_blitblur.id, "uTexMotion" );
+   _uniform_blitblur_uBlurStrength = glGetUniformLocation( _shader_blitblur.id, "uBlurStrength" );
+   _uniform_blitblur_uBlurExponent = glGetUniformLocation( _shader_blitblur.id, "uBlurExponent" );
 }
 #endif /* SHADER_blitblur_H */
diff --git a/shaders/blitcolour.h b/shaders/blitcolour.h
new file mode 100644 (file)
index 0000000..68880e3
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef SHADER_blitcolour_H
+#define SHADER_blitcolour_H
+static void shader_blitcolour_link(void);
+static void shader_blitcolour_register(void);
+static struct vg_shader _shader_blitcolour = {
+   .name = "blitcolour",
+   .link = shader_blitcolour_link,
+   .vs = 
+{
+.static_src = 
+"layout (location=0) in vec2 a_co;\n"
+"out vec2 aUv;\n"
+"\n"
+"void main()\n"
+"{\n"
+"   gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
+"   aUv = a_co;\n"
+"}\n"
+""},
+   .fs = 
+{
+.static_src = 
+"out vec4 FragColor;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec2 aUv;\n"
+"\n"
+"void main()\n"
+"{\n"
+"   FragColor = uColour;\n"
+"}\n"
+""},
+};
+
+static GLuint _uniform_blitcolour_uColour;
+static void shader_blitcolour_uColour(v4f v){
+   glUniform4fv(_uniform_blitcolour_uColour,1,v);
+}
+static void shader_blitcolour_register(void){
+   vg_shader_register( &_shader_blitcolour );
+}
+static void shader_blitcolour_use(void){ glUseProgram(_shader_blitcolour.id); }
+static void shader_blitcolour_link(void){
+   _uniform_blitcolour_uColour = glGetUniformLocation( _shader_blitcolour.id, "uColour" );
+}
+#endif /* SHADER_blitcolour_H */
index d7b3ccfefc0741947a9bcd380b64e44e24d4a23a..a394acb75b73724666528c640a0698b5ac66b882 100644 (file)
@@ -1,3 +1,5 @@
+layout (location = 0) out vec4 oColour;
+
 layout (std140) uniform ub_world_lighting
 {
    vec4 g_light_colours[3];
index 8549ec43384a2d0f2a3acc582014322cae69f03c..b60fb758deddf2bd360f05e5c9964ba0b6a1d39b 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_gpos = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
@@ -28,13 +40,18 @@ static struct vg_shader _shader_gpos = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
@@ -51,6 +68,8 @@ static struct vg_shader _shader_gpos = {
 "in vec3 aWorldCo;\n"
 "\n"
 "#line       1        1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
 "layout (std140) uniform ub_world_lighting\n"
 "{\n"
 "   vec4 g_light_colours[3];\n"
@@ -180,6 +199,7 @@ static struct vg_shader _shader_gpos = {
 
 static GLuint _uniform_gpos_uMdl;
 static GLuint _uniform_gpos_uPv;
+static GLuint _uniform_gpos_uPvmPrev;
 static GLuint _uniform_gpos_uCamera;
 static GLuint _uniform_gpos_g_world_depth;
 static void shader_gpos_uMdl(m4x3f m){
@@ -188,6 +208,9 @@ static void shader_gpos_uMdl(m4x3f m){
 static void shader_gpos_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_gpos_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_gpos_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_gpos_uPvmPrev,1,GL_FALSE,(float*)m);
+}
 static void shader_gpos_uCamera(v3f v){
    glUniform3fv(_uniform_gpos_uCamera,1,v);
 }
@@ -201,6 +224,7 @@ static void shader_gpos_use(void){ glUseProgram(_shader_gpos.id); }
 static void shader_gpos_link(void){
    _uniform_gpos_uMdl = glGetUniformLocation( _shader_gpos.id, "uMdl" );
    _uniform_gpos_uPv = glGetUniformLocation( _shader_gpos.id, "uPv" );
+   _uniform_gpos_uPvmPrev = glGetUniformLocation( _shader_gpos.id, "uPvmPrev" );
    _uniform_gpos_uCamera = glGetUniformLocation( _shader_gpos.id, "uCamera" );
    _uniform_gpos_g_world_depth = glGetUniformLocation( _shader_gpos.id, "g_world_depth" );
 }
index 75ed0ddc402b7e410502a4c37ff9837d3b6cec88..2a14ac1921673ce3a5e09f48d2a644b44961eb5d 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_menu = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
@@ -28,13 +40,18 @@ static struct vg_shader _shader_menu = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
@@ -64,6 +81,7 @@ static struct vg_shader _shader_menu = {
 
 static GLuint _uniform_menu_uMdl;
 static GLuint _uniform_menu_uPv;
+static GLuint _uniform_menu_uPvmPrev;
 static GLuint _uniform_menu_uTexMain;
 static GLuint _uniform_menu_uColour;
 static void shader_menu_uMdl(m4x3f m){
@@ -72,6 +90,9 @@ static void shader_menu_uMdl(m4x3f m){
 static void shader_menu_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_menu_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_menu_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_menu_uPvmPrev,1,GL_FALSE,(float*)m);
+}
 static void shader_menu_uTexMain(int i){
    glUniform1i(_uniform_menu_uTexMain,i);
 }
@@ -85,6 +106,7 @@ static void shader_menu_use(void){ glUseProgram(_shader_menu.id); }
 static void shader_menu_link(void){
    _uniform_menu_uMdl = glGetUniformLocation( _shader_menu.id, "uMdl" );
    _uniform_menu_uPv = glGetUniformLocation( _shader_menu.id, "uPv" );
+   _uniform_menu_uPvmPrev = glGetUniformLocation( _shader_menu.id, "uPvmPrev" );
    _uniform_menu_uTexMain = glGetUniformLocation( _shader_menu.id, "uTexMain" );
    _uniform_menu_uColour = glGetUniformLocation( _shader_menu.id, "uColour" );
 }
diff --git a/shaders/motion_vectors_fs.glsl b/shaders/motion_vectors_fs.glsl
new file mode 100644 (file)
index 0000000..e6d2759
--- /dev/null
@@ -0,0 +1,12 @@
+layout (location = 1) out vec2 oMotionVec;
+
+in vec3 aMotionVec0;
+in vec3 aMotionVec1;
+
+void compute_motion_vectors()
+{
+   // Write motion vectors
+   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;
+   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;
+   oMotionVec = vmotion1-vmotion0;
+}
diff --git a/shaders/motion_vectors_vs.glsl b/shaders/motion_vectors_vs.glsl
new file mode 100644 (file)
index 0000000..25c176d
--- /dev/null
@@ -0,0 +1,8 @@
+out vec3 aMotionVec0;
+out vec3 aMotionVec1;
+
+void vs_motion_out( vec4 vproj0, vec4 vproj1 )
+{
+   aMotionVec0 = vec3( vproj0.xy, vproj0.w );
+   aMotionVec1 = vec3( vproj1.xy, vproj1.w );
+}
index 4cf5c32216feb4e0347321a4280a67405e861578..e61776898ba2336214378d90d1de6ca594f2ab4d 100644 (file)
@@ -20,21 +20,34 @@ static struct vg_shader _shader_planeinf = {
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
 "\n"
+"uniform mat4x3 uMotion;\n"
+"\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
 "out vec3 aNorm;\n"
 "out vec3 aCo;\n"
 "out vec3 aWorldCo;\n"
 "\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl    * vec4(a_co,1.0);\n"
+"   vec3 world_pos1 = uMotion * vec4(world_pos0,1.0);\n"
+"   \n"
+"   vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1 = uPv * vec4( world_pos1, 1.0 );\n"
+"\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
@@ -72,6 +85,7 @@ static struct vg_shader _shader_planeinf = {
 
 static GLuint _uniform_planeinf_uMdl;
 static GLuint _uniform_planeinf_uPv;
+static GLuint _uniform_planeinf_uMotion;
 static GLuint _uniform_planeinf_uCamera;
 static GLuint _uniform_planeinf_uPlane;
 static void shader_planeinf_uMdl(m4x3f m){
@@ -80,6 +94,9 @@ static void shader_planeinf_uMdl(m4x3f m){
 static void shader_planeinf_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_planeinf_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_planeinf_uMotion(m4x3f m){
+   glUniformMatrix4x3fv(_uniform_planeinf_uMotion,1,GL_FALSE,(float*)m);
+}
 static void shader_planeinf_uCamera(v3f v){
    glUniform3fv(_uniform_planeinf_uCamera,1,v);
 }
@@ -93,6 +110,7 @@ static void shader_planeinf_use(void){ glUseProgram(_shader_planeinf.id); }
 static void shader_planeinf_link(void){
    _uniform_planeinf_uMdl = glGetUniformLocation( _shader_planeinf.id, "uMdl" );
    _uniform_planeinf_uPv = glGetUniformLocation( _shader_planeinf.id, "uPv" );
+   _uniform_planeinf_uMotion = glGetUniformLocation( _shader_planeinf.id, "uMotion" );
    _uniform_planeinf_uCamera = glGetUniformLocation( _shader_planeinf.id, "uCamera" );
    _uniform_planeinf_uPlane = glGetUniformLocation( _shader_planeinf.id, "uPlane" );
 }
index dfaa7f900184c8c4fb3c4d1f2f682870a310438e..3e82be7d679d84cd0cbfe72b8251f32751f7a92e 100644 (file)
@@ -1,5 +1,3 @@
-out vec4 FragColor;
-
 uniform sampler2D uTexGarbage;
 uniform sampler2D uTexGradients;
 uniform vec3 uCamera;
@@ -12,9 +10,12 @@ in vec3 aCo;
 in vec3 aWorldCo;
 
 #include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
 
 void main()
 {
+   compute_motion_vectors();
+
    vec3 vfrag = vec3(0.5,0.5,0.5);
 
    // ws modulation
@@ -52,5 +53,5 @@ void main()
    vfrag = do_light_shadowing( vfrag );
    vfrag = apply_fog( vfrag, fdist );
 
-   FragColor = vec4(vfrag, 1.0 );
+   oColour = vec4(vfrag, 1.0 );
 }
index 44fc21316d4845fe5c6addc404e4842d5a163924..521df235f1eb63c9f3cfeeb5a2fd7251bc05c8c3 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_route = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
@@ -28,20 +40,23 @@ static struct vg_shader _shader_route = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
 {
 .static_src = 
-"out vec4 FragColor;\n"
-"\n"
 "uniform sampler2D uTexGarbage;\n"
 "uniform sampler2D uTexGradients;\n"
 "uniform vec3 uCamera;\n"
@@ -54,6 +69,8 @@ static struct vg_shader _shader_route = {
 "in vec3 aWorldCo;\n"
 "\n"
 "#line       1        1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
 "layout (std140) uniform ub_world_lighting\n"
 "{\n"
 "   vec4 g_light_colours[3];\n"
@@ -157,10 +174,27 @@ static struct vg_shader _shader_route = {
 "   return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
 "}\n"
 "\n"
-"#line     15        0 \n"
+"#line     13        0 \n"
+"#line       1        2 \n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"   oMotionVec = vmotion1-vmotion0;\n"
+"}\n"
+"\n"
+"#line     14        0 \n"
 "\n"
 "void main()\n"
 "{\n"
+"   compute_motion_vectors();\n"
+"\n"
 "   vec3 vfrag = vec3(0.5,0.5,0.5);\n"
 "\n"
 "   // ws modulation\n"
@@ -198,13 +232,14 @@ static struct vg_shader _shader_route = {
 "   vfrag = do_light_shadowing( vfrag );\n"
 "   vfrag = apply_fog( vfrag, fdist );\n"
 "\n"
-"   FragColor = vec4(vfrag, 1.0 );\n"
+"   oColour = vec4(vfrag, 1.0 );\n"
 "}\n"
 ""},
 };
 
 static GLuint _uniform_route_uMdl;
 static GLuint _uniform_route_uPv;
+static GLuint _uniform_route_uPvmPrev;
 static GLuint _uniform_route_uTexGarbage;
 static GLuint _uniform_route_uTexGradients;
 static GLuint _uniform_route_uCamera;
@@ -216,6 +251,9 @@ static void shader_route_uMdl(m4x3f m){
 static void shader_route_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_route_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_route_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_route_uPvmPrev,1,GL_FALSE,(float*)m);
+}
 static void shader_route_uTexGarbage(int i){
    glUniform1i(_uniform_route_uTexGarbage,i);
 }
@@ -238,6 +276,7 @@ static void shader_route_use(void){ glUseProgram(_shader_route.id); }
 static void shader_route_link(void){
    _uniform_route_uMdl = glGetUniformLocation( _shader_route.id, "uMdl" );
    _uniform_route_uPv = glGetUniformLocation( _shader_route.id, "uPv" );
+   _uniform_route_uPvmPrev = glGetUniformLocation( _shader_route.id, "uPvmPrev" );
    _uniform_route_uTexGarbage = glGetUniformLocation( _shader_route.id, "uTexGarbage" );
    _uniform_route_uTexGradients = glGetUniformLocation( _shader_route.id, "uTexGradients" );
    _uniform_route_uCamera = glGetUniformLocation( _shader_route.id, "uCamera" );
index fae077e81e93a83fe452c0ca20dab88c0725240e..55734a37e1d36e3def197291dd00aa0d75975363 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_scoretext = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
-"uniform mat4 uPv;\n"
 "uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "uniform vec3 uInfo;\n"
 "\n"
@@ -47,8 +59,16 @@ static struct vg_shader _shader_scoretext = {
 "   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"
+"   vec3 local_pos = mlocal * vec4( a_co, 1.0 );\n"
+"   vec3 world_pos = uMdl * vec4( local_pos, 1.0 );\n"
+"\n"
+"   vec4 vproj0 = uPv      * vec4( world_pos, 1.0 );\n"
+"   vec4 vproj1 = uPvmPrev * vec4( local_pos, 1.0 );\n"
+"\n"
+"   // Output\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\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"
@@ -59,8 +79,6 @@ static struct vg_shader _shader_scoretext = {
    .fs = 
 {
 .static_src = 
-"out vec4 FragColor;\n"
-"\n"
 "uniform sampler2D uTexGarbage;\n"
 "uniform sampler2D uTexGradients;\n"
 "uniform vec3 uCamera;\n"
@@ -72,6 +90,8 @@ static struct vg_shader _shader_scoretext = {
 "in vec3 aWorldCo;\n"
 "\n"
 "#line       1        1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
 "layout (std140) uniform ub_world_lighting\n"
 "{\n"
 "   vec4 g_light_colours[3];\n"
@@ -175,10 +195,27 @@ static struct vg_shader _shader_scoretext = {
 "   return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
 "}\n"
 "\n"
-"#line     14        0 \n"
+"#line     12        0 \n"
+"#line       1        2 \n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"   oMotionVec = vmotion1-vmotion0;\n"
+"}\n"
+"\n"
+"#line     13        0 \n"
 "\n"
 "void main()\n"
 "{\n"
+"   compute_motion_vectors();\n"
+"\n"
 "   vec3 vfrag = vec3(0.5,0.5,0.5);\n"
 "\n"
 "   // ws modulation\n"
@@ -217,23 +254,27 @@ static struct vg_shader _shader_scoretext = {
 "   vfrag = do_light_shadowing( vfrag );\n"
 "   vfrag = apply_fog( vfrag, fdist );\n"
 "\n"
-"   FragColor = vec4(vfrag, 1.0 );\n"
+"   oColour = vec4(vfrag, 1.0 );\n"
 "}\n"
 ""},
 };
 
-static GLuint _uniform_scoretext_uPv;
 static GLuint _uniform_scoretext_uMdl;
+static GLuint _uniform_scoretext_uPv;
+static GLuint _uniform_scoretext_uPvmPrev;
 static GLuint _uniform_scoretext_uInfo;
 static GLuint _uniform_scoretext_uTexGarbage;
 static GLuint _uniform_scoretext_uTexGradients;
 static GLuint _uniform_scoretext_uCamera;
 static GLuint _uniform_scoretext_g_world_depth;
+static void shader_scoretext_uMdl(m4x3f m){
+   glUniformMatrix4x3fv(_uniform_scoretext_uMdl,1,GL_FALSE,(float*)m);
+}
 static void shader_scoretext_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_scoretext_uPv,1,GL_FALSE,(float*)m);
 }
-static void shader_scoretext_uMdl(m4x3f m){
-   glUniformMatrix4x3fv(_uniform_scoretext_uMdl,1,GL_FALSE,(float*)m);
+static void shader_scoretext_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_scoretext_uPvmPrev,1,GL_FALSE,(float*)m);
 }
 static void shader_scoretext_uInfo(v3f v){
    glUniform3fv(_uniform_scoretext_uInfo,1,v);
@@ -255,8 +296,9 @@ static void shader_scoretext_register(void){
 }
 static void shader_scoretext_use(void){ glUseProgram(_shader_scoretext.id); }
 static void shader_scoretext_link(void){
-   _uniform_scoretext_uPv = glGetUniformLocation( _shader_scoretext.id, "uPv" );
    _uniform_scoretext_uMdl = glGetUniformLocation( _shader_scoretext.id, "uMdl" );
+   _uniform_scoretext_uPv = glGetUniformLocation( _shader_scoretext.id, "uPv" );
+   _uniform_scoretext_uPvmPrev = glGetUniformLocation( _shader_scoretext.id, "uPvmPrev" );
    _uniform_scoretext_uInfo = glGetUniformLocation( _shader_scoretext.id, "uInfo" );
    _uniform_scoretext_uTexGarbage = glGetUniformLocation( _shader_scoretext.id, "uTexGarbage" );
    _uniform_scoretext_uTexGradients = glGetUniformLocation( _shader_scoretext.id, "uTexGradients" );
index bcd5b9507cb55af555f53b81a796e48c5a8e6dbb..ab714d6e5ec228b288efa15e9fb21dd6faa5e2dc 100644 (file)
@@ -1,7 +1,9 @@
 #include "vertex_standard.glsl"
+#include "motion_vectors_vs.glsl"
 
-uniform mat4 uPv;
 uniform mat4x3 uMdl;
+uniform mat4 uPv;
+uniform mat4 uPvmPrev;
 
 uniform vec3 uInfo;
 
@@ -30,8 +32,16 @@ void main()
    mlocal[2] = vec3(0.0,0.0,1.0);
    mlocal[3] = vec3(c*r,uInfo.y*0.875 + s*r,uInfo.x*0.5);
 
-   vec3 world_pos = uMdl * vec4(mlocal * vec4(a_co,1.0),1.0);
-   gl_Position = uPv * vec4( world_pos, 1.0 );
+   vec3 local_pos = mlocal * vec4( a_co, 1.0 );
+   vec3 world_pos = uMdl * vec4( local_pos, 1.0 );
+
+   vec4 vproj0 = uPv      * vec4( world_pos, 1.0 );
+   vec4 vproj1 = uPvmPrev * vec4( local_pos, 1.0 );
+
+   // Output
+   vs_motion_out( vproj0, vproj1 );
+
+   gl_Position = vproj0;
    aColour = a_colour;
    aUv = a_uv + vec2( floor(uInfo.z+0.5)*(1.0/64.0), yoff );
    aNorm = mat3(uMdl) * mat3(mlocal) * a_norm;
index ad050dba1142bb88383beb60cdad62e5795829a3..036f2445001ed8ccfddf0a2c9aee0cf165dda6da 100644 (file)
@@ -1,4 +1,4 @@
-out vec4 FragColor;
+layout (location = 0) out vec4 oColour;
 
 uniform vec4 uColour;
 uniform sampler2D uTexGarbage;
@@ -9,8 +9,12 @@ in vec2 aUv;
 in vec3 aNorm;
 in vec3 aCo;
 
+#include "motion_vectors_fs.glsl"
+
 void main()
 {
+   compute_motion_vectors();
+
    float fintensity = 1.0-(abs(aNorm.y)*0.7);
    float fblend = pow(fintensity,4.0);
    vec3 horizon = vec3( 0.8, 0.9, 0.9 );
@@ -29,5 +33,5 @@ void main()
    float fhorizon = step( aNorm.y * 0.5 + 0.5, 0.5 );
 
    vec3 skycomp = mix(diffuse, vec3(1.0,1.0,1.0), cloud_e);
-   FragColor = vec4(pow(skycomp, vec3(1.5)),1.0);
+   oColour = vec4(pow(skycomp, vec3(1.5)),1.0);
 }
index b93549bcd37165a9e9c32859d4365335dbea4935..fa0546f5bbb5bce4648615118de2ccb9760b75ac 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_sky = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
@@ -28,19 +40,24 @@ static struct vg_shader _shader_sky = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
 {
 .static_src = 
-"out vec4 FragColor;\n"
+"layout (location = 0) out vec4 oColour;\n"
 "\n"
 "uniform vec4 uColour;\n"
 "uniform sampler2D uTexGarbage;\n"
@@ -51,8 +68,26 @@ static struct vg_shader _shader_sky = {
 "in vec3 aNorm;\n"
 "in vec3 aCo;\n"
 "\n"
+"#line       1        1 \n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"   oMotionVec = vmotion1-vmotion0;\n"
+"}\n"
+"\n"
+"#line     13        0 \n"
+"\n"
 "void main()\n"
 "{\n"
+"   compute_motion_vectors();\n"
+"\n"
 "   float fintensity = 1.0-(abs(aNorm.y)*0.7);\n"
 "   float fblend = pow(fintensity,4.0);\n"
 "   vec3 horizon = vec3( 0.8, 0.9, 0.9 );\n"
@@ -71,13 +106,14 @@ static struct vg_shader _shader_sky = {
 "   float fhorizon = step( aNorm.y * 0.5 + 0.5, 0.5 );\n"
 "\n"
 "   vec3 skycomp = mix(diffuse, vec3(1.0,1.0,1.0), cloud_e);\n"
-"   FragColor = vec4(pow(skycomp, vec3(1.5)),1.0);\n"
+"   oColour = vec4(pow(skycomp, vec3(1.5)),1.0);\n"
 "}\n"
 ""},
 };
 
 static GLuint _uniform_sky_uMdl;
 static GLuint _uniform_sky_uPv;
+static GLuint _uniform_sky_uPvmPrev;
 static GLuint _uniform_sky_uColour;
 static GLuint _uniform_sky_uTexGarbage;
 static GLuint _uniform_sky_uTime;
@@ -87,6 +123,9 @@ static void shader_sky_uMdl(m4x3f m){
 static void shader_sky_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_sky_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_sky_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_sky_uPvmPrev,1,GL_FALSE,(float*)m);
+}
 static void shader_sky_uColour(v4f v){
    glUniform4fv(_uniform_sky_uColour,1,v);
 }
@@ -103,6 +142,7 @@ static void shader_sky_use(void){ glUseProgram(_shader_sky.id); }
 static void shader_sky_link(void){
    _uniform_sky_uMdl = glGetUniformLocation( _shader_sky.id, "uMdl" );
    _uniform_sky_uPv = glGetUniformLocation( _shader_sky.id, "uPv" );
+   _uniform_sky_uPvmPrev = glGetUniformLocation( _shader_sky.id, "uPvmPrev" );
    _uniform_sky_uColour = glGetUniformLocation( _shader_sky.id, "uColour" );
    _uniform_sky_uTexGarbage = glGetUniformLocation( _shader_sky.id, "uTexGarbage" );
    _uniform_sky_uTime = glGetUniformLocation( _shader_sky.id, "uTime" );
index d3a6842926edc966466f1dfe774c11f7aff297c9..58678f01195a3ff47fc4711ee45e7ed988080477 100644 (file)
@@ -1,5 +1,3 @@
-out vec4 FragColor;
-
 uniform sampler2D uTexGarbage;
 uniform sampler2D uTexMain;
 uniform vec3 uCamera;
@@ -12,9 +10,12 @@ in vec3 aCo;
 in vec3 aWorldCo;
 
 #include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
 
 void main()
 {
+   compute_motion_vectors();
+
    vec3 vfrag = vec3(0.5,0.5,0.5);
    vec4 vsamplemain = texture( uTexMain, aUv );
    vec3 qnorm = normalize(aNorm);
@@ -36,5 +37,5 @@ void main()
    vfrag = do_light_shadowing( vfrag );
    vfrag = apply_fog( vfrag, fdist );
 
-   FragColor = vec4(vfrag, 1.0);
+   oColour = vec4(vfrag, 1.0);
 }
index 4d52aa81fad8601b97d1788a133e8ea22770b1c7..3c759b6c8584a93decf24298faa23cd2577ba57a 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_standard = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
@@ -28,20 +40,23 @@ static struct vg_shader _shader_standard = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
 {
 .static_src = 
-"out vec4 FragColor;\n"
-"\n"
 "uniform sampler2D uTexGarbage;\n"
 "uniform sampler2D uTexMain;\n"
 "uniform vec3 uCamera;\n"
@@ -54,6 +69,8 @@ static struct vg_shader _shader_standard = {
 "in vec3 aWorldCo;\n"
 "\n"
 "#line       1        1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
 "layout (std140) uniform ub_world_lighting\n"
 "{\n"
 "   vec4 g_light_colours[3];\n"
@@ -157,10 +174,27 @@ static struct vg_shader _shader_standard = {
 "   return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
 "}\n"
 "\n"
-"#line     15        0 \n"
+"#line     13        0 \n"
+"#line       1        2 \n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"   oMotionVec = vmotion1-vmotion0;\n"
+"}\n"
+"\n"
+"#line     14        0 \n"
 "\n"
 "void main()\n"
 "{\n"
+"   compute_motion_vectors();\n"
+"\n"
 "   vec3 vfrag = vec3(0.5,0.5,0.5);\n"
 "   vec4 vsamplemain = texture( uTexMain, aUv );\n"
 "   vec3 qnorm = normalize(aNorm);\n"
@@ -182,13 +216,14 @@ static struct vg_shader _shader_standard = {
 "   vfrag = do_light_shadowing( vfrag );\n"
 "   vfrag = apply_fog( vfrag, fdist );\n"
 "\n"
-"   FragColor = vec4(vfrag, 1.0);\n"
+"   oColour = vec4(vfrag, 1.0);\n"
 "}\n"
 ""},
 };
 
 static GLuint _uniform_standard_uMdl;
 static GLuint _uniform_standard_uPv;
+static GLuint _uniform_standard_uPvmPrev;
 static GLuint _uniform_standard_uTexGarbage;
 static GLuint _uniform_standard_uTexMain;
 static GLuint _uniform_standard_uCamera;
@@ -200,6 +235,9 @@ static void shader_standard_uMdl(m4x3f m){
 static void shader_standard_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_standard_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_standard_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_standard_uPvmPrev,1,GL_FALSE,(float*)m);
+}
 static void shader_standard_uTexGarbage(int i){
    glUniform1i(_uniform_standard_uTexGarbage,i);
 }
@@ -222,6 +260,7 @@ static void shader_standard_use(void){ glUseProgram(_shader_standard.id); }
 static void shader_standard_link(void){
    _uniform_standard_uMdl = glGetUniformLocation( _shader_standard.id, "uMdl" );
    _uniform_standard_uPv = glGetUniformLocation( _shader_standard.id, "uPv" );
+   _uniform_standard_uPvmPrev = glGetUniformLocation( _shader_standard.id, "uPvmPrev" );
    _uniform_standard_uTexGarbage = glGetUniformLocation( _shader_standard.id, "uTexGarbage" );
    _uniform_standard_uTexMain = glGetUniformLocation( _shader_standard.id, "uTexMain" );
    _uniform_standard_uCamera = glGetUniformLocation( _shader_standard.id, "uCamera" );
index 33f41544f835b0dd83d43beac92cc33baeb8a3ae..679eae88deb12765d27388dd86520de08596535b 100644 (file)
@@ -1,7 +1,9 @@
 #include "vertex_standard.glsl"
+#include "motion_vectors_vs.glsl"
 
 uniform mat4x3 uMdl;
 uniform mat4 uPv;
+uniform mat4 uPvmPrev;
 
 out vec4 aColour;
 out vec2 aUv;
@@ -11,11 +13,16 @@ out vec3 aWorldCo;
 
 void main()
 {
-   vec3 world_pos = uMdl * vec4(a_co,1.0);
-   gl_Position = uPv * vec4( world_pos, 1.0 );
+   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;
+   aWorldCo = world_pos0;
    aColour = a_colour;
    aUv = a_uv;
    aNorm = mat3(uMdl) * a_norm;
    aCo = a_co;
-   aWorldCo = world_pos;
 }
index 5c959a080752c0a35349b22483d33c75385d6c4b..089379529e661dbffb61ce2a068aa486c68c6a9a 100644 (file)
@@ -1,6 +1,10 @@
 #include "vertex_standard.glsl"
+#include "motion_vectors_vs.glsl"
 
 uniform mat4 uPv;
+
+// TODO: Send a previous transform matrix stack
+//
 uniform mat4x3 uTransforms[32];
 
 out vec4 aColour;
@@ -28,4 +32,8 @@ void main()
    aNorm = world_normal;
    aCo = a_co;
    aWorldCo = world_pos;
+
+   // TODO:
+   aMotionVec0 = vec3(1.0);
+   aMotionVec1 = vec3(1.0);
 }
index 7881b51ed25153da52773c3f1a422920bc124c58..b0f18fd1db484d651a77685ac826543474ae6862 100644 (file)
@@ -1,5 +1,3 @@
-out vec4 FragColor;
-
 uniform sampler2D uTexGarbage;
 uniform sampler2D uTexMain;
 uniform vec3 uCamera;
@@ -12,9 +10,12 @@ in vec3 aCo;
 in vec3 aWorldCo;
 
 #include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
 
 void main()
 {
+   compute_motion_vectors();
+
    vec3 vfrag = vec3(0.5,0.5,0.5);
    vec4 vsamplemain = texture( uTexMain, aUv );
    vec3 qnorm = normalize(aNorm);
@@ -39,5 +40,5 @@ void main()
    vfrag = do_light_shadowing( vfrag );
    vfrag = apply_fog( vfrag, fdist );
 
-   FragColor = vec4(vfrag, 1.0);
+   oColour = vec4(vfrag, 1.0);
 }
index f093904b0f46ce5538bf9e78479cb992a877b5a4..6e01684cf9b85bb3825436488f5c2fc2c770e2de 100644 (file)
@@ -1,5 +1,3 @@
-out vec4 FragColor;
-
 uniform sampler2D uTexGarbage;
 uniform sampler2D uTexGradients;
 uniform vec3 uCamera;
@@ -13,9 +11,14 @@ in vec3 aCo;
 in vec3 aWorldCo;
 
 #include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
 
 void main()
 {
+   compute_motion_vectors();
+
+   // Colour
+   // ------
    vec3 vfrag = vec3(0.5,0.5,0.5);
 
    // ws modulation
@@ -55,5 +58,5 @@ void main()
    vfrag = do_light_shadowing( vfrag );
    vfrag = apply_fog( vfrag, fdist );
 
-   FragColor = vec4(vfrag, 1.0 );
+   oColour = vec4(vfrag, 1.0 );
 }
index 6b4c3de695a00f9e25e29cd15b088108cb612a6e..460ba9e5d02392e2ad3a2e94ffef59132a13a1d5 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_terrain = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
@@ -28,20 +40,23 @@ static struct vg_shader _shader_terrain = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
 {
 .static_src = 
-"out vec4 FragColor;\n"
-"\n"
 "uniform sampler2D uTexGarbage;\n"
 "uniform sampler2D uTexGradients;\n"
 "uniform vec3 uCamera;\n"
@@ -55,6 +70,8 @@ static struct vg_shader _shader_terrain = {
 "in vec3 aWorldCo;\n"
 "\n"
 "#line       1        1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
 "layout (std140) uniform ub_world_lighting\n"
 "{\n"
 "   vec4 g_light_colours[3];\n"
@@ -158,10 +175,29 @@ static struct vg_shader _shader_terrain = {
 "   return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
 "}\n"
 "\n"
-"#line     16        0 \n"
+"#line     14        0 \n"
+"#line       1        2 \n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"   oMotionVec = vmotion1-vmotion0;\n"
+"}\n"
+"\n"
+"#line     15        0 \n"
 "\n"
 "void main()\n"
 "{\n"
+"   compute_motion_vectors();\n"
+"\n"
+"   // Colour\n"
+"   // ------\n"
 "   vec3 vfrag = vec3(0.5,0.5,0.5);\n"
 "\n"
 "   // ws modulation\n"
@@ -201,13 +237,14 @@ static struct vg_shader _shader_terrain = {
 "   vfrag = do_light_shadowing( vfrag );\n"
 "   vfrag = apply_fog( vfrag, fdist );\n"
 "\n"
-"   FragColor = vec4(vfrag, 1.0 );\n"
+"   oColour = vec4(vfrag, 1.0 );\n"
 "}\n"
 ""},
 };
 
 static GLuint _uniform_terrain_uMdl;
 static GLuint _uniform_terrain_uPv;
+static GLuint _uniform_terrain_uPvmPrev;
 static GLuint _uniform_terrain_uTexGarbage;
 static GLuint _uniform_terrain_uTexGradients;
 static GLuint _uniform_terrain_uCamera;
@@ -220,6 +257,9 @@ static void shader_terrain_uMdl(m4x3f m){
 static void shader_terrain_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_terrain_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_terrain_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_terrain_uPvmPrev,1,GL_FALSE,(float*)m);
+}
 static void shader_terrain_uTexGarbage(int i){
    glUniform1i(_uniform_terrain_uTexGarbage,i);
 }
@@ -245,6 +285,7 @@ static void shader_terrain_use(void){ glUseProgram(_shader_terrain.id); }
 static void shader_terrain_link(void){
    _uniform_terrain_uMdl = glGetUniformLocation( _shader_terrain.id, "uMdl" );
    _uniform_terrain_uPv = glGetUniformLocation( _shader_terrain.id, "uPv" );
+   _uniform_terrain_uPvmPrev = glGetUniformLocation( _shader_terrain.id, "uPvmPrev" );
    _uniform_terrain_uTexGarbage = glGetUniformLocation( _shader_terrain.id, "uTexGarbage" );
    _uniform_terrain_uTexGradients = glGetUniformLocation( _shader_terrain.id, "uTexGradients" );
    _uniform_terrain_uCamera = glGetUniformLocation( _shader_terrain.id, "uCamera" );
index a30f83c9ee29f12d5020f206c92b649c6da1821d..9eddd6b7f25ecff0c36a32226413cf905c153024 100644 (file)
@@ -1,5 +1,3 @@
-out vec4 FragColor;
-
 uniform sampler2D uTexGarbage;
 uniform sampler2D uTexGradients;
 uniform vec3 uCamera;
@@ -11,9 +9,12 @@ in vec3 aCo;
 in vec3 aWorldCo;
 
 #include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
 
 void main()
 {
+   compute_motion_vectors();
+
    vec3 vfrag = vec3(0.5,0.5,0.5);
 
    // ws modulation
@@ -52,5 +53,5 @@ void main()
    vfrag = do_light_shadowing( vfrag );
    vfrag = apply_fog( vfrag, fdist );
 
-   FragColor = vec4(vfrag, 1.0 );
+   oColour = vec4(vfrag, 1.0 );
 }
index 9e7b0e241c753a9f4347d1ed1baee7620ea06396..2a5dacf8bcb16d9db7ede932a3e82b07143ca0b8 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_vblend = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
@@ -28,20 +40,23 @@ static struct vg_shader _shader_vblend = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
 {
 .static_src = 
-"out vec4 FragColor;\n"
-"\n"
 "uniform sampler2D uTexGarbage;\n"
 "uniform sampler2D uTexGradients;\n"
 "uniform vec3 uCamera;\n"
@@ -53,6 +68,8 @@ static struct vg_shader _shader_vblend = {
 "in vec3 aWorldCo;\n"
 "\n"
 "#line       1        1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
 "layout (std140) uniform ub_world_lighting\n"
 "{\n"
 "   vec4 g_light_colours[3];\n"
@@ -156,10 +173,27 @@ static struct vg_shader _shader_vblend = {
 "   return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
 "}\n"
 "\n"
-"#line     14        0 \n"
+"#line     12        0 \n"
+"#line       1        2 \n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"   oMotionVec = vmotion1-vmotion0;\n"
+"}\n"
+"\n"
+"#line     13        0 \n"
 "\n"
 "void main()\n"
 "{\n"
+"   compute_motion_vectors();\n"
+"\n"
 "   vec3 vfrag = vec3(0.5,0.5,0.5);\n"
 "\n"
 "   // ws modulation\n"
@@ -198,13 +232,14 @@ static struct vg_shader _shader_vblend = {
 "   vfrag = do_light_shadowing( vfrag );\n"
 "   vfrag = apply_fog( vfrag, fdist );\n"
 "\n"
-"   FragColor = vec4(vfrag, 1.0 );\n"
+"   oColour = vec4(vfrag, 1.0 );\n"
 "}\n"
 ""},
 };
 
 static GLuint _uniform_vblend_uMdl;
 static GLuint _uniform_vblend_uPv;
+static GLuint _uniform_vblend_uPvmPrev;
 static GLuint _uniform_vblend_uTexGarbage;
 static GLuint _uniform_vblend_uTexGradients;
 static GLuint _uniform_vblend_uCamera;
@@ -215,6 +250,9 @@ static void shader_vblend_uMdl(m4x3f m){
 static void shader_vblend_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_vblend_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_vblend_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_vblend_uPvmPrev,1,GL_FALSE,(float*)m);
+}
 static void shader_vblend_uTexGarbage(int i){
    glUniform1i(_uniform_vblend_uTexGarbage,i);
 }
@@ -234,6 +272,7 @@ static void shader_vblend_use(void){ glUseProgram(_shader_vblend.id); }
 static void shader_vblend_link(void){
    _uniform_vblend_uMdl = glGetUniformLocation( _shader_vblend.id, "uMdl" );
    _uniform_vblend_uPv = glGetUniformLocation( _shader_vblend.id, "uPv" );
+   _uniform_vblend_uPvmPrev = glGetUniformLocation( _shader_vblend.id, "uPvmPrev" );
    _uniform_vblend_uTexGarbage = glGetUniformLocation( _shader_vblend.id, "uTexGarbage" );
    _uniform_vblend_uTexGradients = glGetUniformLocation( _shader_vblend.id, "uTexGradients" );
    _uniform_vblend_uCamera = glGetUniformLocation( _shader_vblend.id, "uCamera" );
index 57edff5eda7dff0f81b491bf2dd948ce8b4aa05e..f7e0370a06aeaa2c73a93d63198d166cef711968 100644 (file)
@@ -1,5 +1,3 @@
-out vec4 FragColor;
-
 uniform sampler2D uTexMain;
 uniform vec3 uCamera;
 
@@ -10,9 +8,12 @@ in vec3 aCo;
 in vec3 aWorldCo;
 
 #include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
 
 void main()
 {
+   compute_motion_vectors();
+
    vec3 vfrag = texture( uTexMain, aUv ).rgb;
 
    // Lighting
@@ -28,5 +29,5 @@ void main()
    vfrag = apply_fog( vfrag, fdist );
 
    float opacity = clamp( fdist*fdist, 0.1, 1.0 );
-   FragColor = vec4(vfrag,opacity);
+   oColour = vec4(vfrag,opacity);
 }
index 21d98c06bf06cc93843795bfa9c418691e6d2a4a..20f33d38fbb8bb24e95b58c5c6f9802871270c0b 100644 (file)
@@ -16,8 +16,22 @@ static struct vg_shader _shader_viewchar = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4 uPv;\n"
+"\n"
+"// TODO: Send a previous transform matrix stack\n"
+"//\n"
 "uniform mat4x3 uTransforms[32];\n"
 "\n"
 "out vec4 aColour;\n"
@@ -45,13 +59,15 @@ static struct vg_shader _shader_viewchar = {
 "   aNorm = world_normal;\n"
 "   aCo = a_co;\n"
 "   aWorldCo = world_pos;\n"
+"\n"
+"   // TODO:\n"
+"   aMotionVec0 = vec3(1.0);\n"
+"   aMotionVec1 = vec3(1.0);\n"
 "}\n"
 ""},
    .fs = 
 {
 .static_src = 
-"out vec4 FragColor;\n"
-"\n"
 "uniform sampler2D uTexMain;\n"
 "uniform vec3 uCamera;\n"
 "\n"
@@ -62,6 +78,8 @@ static struct vg_shader _shader_viewchar = {
 "in vec3 aWorldCo;\n"
 "\n"
 "#line       1        1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
 "layout (std140) uniform ub_world_lighting\n"
 "{\n"
 "   vec4 g_light_colours[3];\n"
@@ -165,10 +183,27 @@ static struct vg_shader _shader_viewchar = {
 "   return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
 "}\n"
 "\n"
-"#line     13        0 \n"
+"#line     11        0 \n"
+"#line       1        2 \n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"   oMotionVec = vmotion1-vmotion0;\n"
+"}\n"
+"\n"
+"#line     12        0 \n"
 "\n"
 "void main()\n"
 "{\n"
+"   compute_motion_vectors();\n"
+"\n"
 "   vec3 vfrag = texture( uTexMain, aUv ).rgb;\n"
 "\n"
 "   // Lighting\n"
@@ -184,7 +219,7 @@ static struct vg_shader _shader_viewchar = {
 "   vfrag = apply_fog( vfrag, fdist );\n"
 "\n"
 "   float opacity = clamp( fdist*fdist, 0.1, 1.0 );\n"
-"   FragColor = vec4(vfrag,opacity);\n"
+"   oColour = vec4(vfrag,opacity);\n"
 "}\n"
 ""},
 };
index 938c6d1e04d04493226bdaa895d8bdf8a3990322..eced89aef82cb4e6eedc85f305bda45374a11202 100644 (file)
@@ -1,5 +1,3 @@
-out vec4 FragColor;
-
 uniform sampler2D uTexMain;
 uniform sampler2D uTexDudv;
 uniform sampler2D uTexBack;
@@ -19,6 +17,7 @@ in vec3 aCo;
 in vec3 aWorldCo;
 
 #include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
 
 vec4 water_surf( vec3 halfview, vec3 vnorm, float depthvalue, 
       vec4 beneath, vec4 above )
@@ -43,6 +42,8 @@ vec4 water_surf( vec3 halfview, vec3 vnorm, float depthvalue,
 
 void main()
 {
+   compute_motion_vectors();
+
    // Create texture coords
    vec2 ssuv = gl_FragCoord.xy*uInvRes;
    
@@ -74,5 +75,5 @@ void main()
    // Composite
    vec4 vsurface = water_surf( halfview, surfnorm, depthvalue, beneath, above );
    vsurface.a -= fdist;
-   FragColor = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );
+   oColour = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );
 }
index 6c76dfe26b11d5df1cc7708230d4caad78dbeb07..109f29dd5b11af7e38650924563de1689cb5719b 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_water = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
@@ -28,20 +40,23 @@ static struct vg_shader _shader_water = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
 {
 .static_src = 
-"out vec4 FragColor;\n"
-"\n"
 "uniform sampler2D uTexMain;\n"
 "uniform sampler2D uTexDudv;\n"
 "uniform sampler2D uTexBack;\n"
@@ -61,6 +76,8 @@ static struct vg_shader _shader_water = {
 "in vec3 aWorldCo;\n"
 "\n"
 "#line       1        1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
 "layout (std140) uniform ub_world_lighting\n"
 "{\n"
 "   vec4 g_light_colours[3];\n"
@@ -164,7 +181,22 @@ static struct vg_shader _shader_water = {
 "   return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
 "}\n"
 "\n"
-"#line     22        0 \n"
+"#line     20        0 \n"
+"#line       1        2 \n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"   oMotionVec = vmotion1-vmotion0;\n"
+"}\n"
+"\n"
+"#line     21        0 \n"
 "\n"
 "vec4 water_surf( vec3 halfview, vec3 vnorm, float depthvalue, \n"
 "      vec4 beneath, vec4 above )\n"
@@ -189,6 +221,8 @@ static struct vg_shader _shader_water = {
 "\n"
 "void main()\n"
 "{\n"
+"   compute_motion_vectors();\n"
+"\n"
 "   // Create texture coords\n"
 "   vec2 ssuv = gl_FragCoord.xy*uInvRes;\n"
 "   \n"
@@ -220,13 +254,14 @@ static struct vg_shader _shader_water = {
 "   // Composite\n"
 "   vec4 vsurface = water_surf( halfview, surfnorm, depthvalue, beneath, above );\n"
 "   vsurface.a -= fdist;\n"
-"   FragColor = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );\n"
+"   oColour = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );\n"
 "}\n"
 ""},
 };
 
 static GLuint _uniform_water_uMdl;
 static GLuint _uniform_water_uPv;
+static GLuint _uniform_water_uPvmPrev;
 static GLuint _uniform_water_uTexMain;
 static GLuint _uniform_water_uTexDudv;
 static GLuint _uniform_water_uTexBack;
@@ -243,6 +278,9 @@ static void shader_water_uMdl(m4x3f m){
 static void shader_water_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_water_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_water_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_water_uPvmPrev,1,GL_FALSE,(float*)m);
+}
 static void shader_water_uTexMain(int i){
    glUniform1i(_uniform_water_uTexMain,i);
 }
@@ -280,6 +318,7 @@ static void shader_water_use(void){ glUseProgram(_shader_water.id); }
 static void shader_water_link(void){
    _uniform_water_uMdl = glGetUniformLocation( _shader_water.id, "uMdl" );
    _uniform_water_uPv = glGetUniformLocation( _shader_water.id, "uPv" );
+   _uniform_water_uPvmPrev = glGetUniformLocation( _shader_water.id, "uPvmPrev" );
    _uniform_water_uTexMain = glGetUniformLocation( _shader_water.id, "uTexMain" );
    _uniform_water_uTexDudv = glGetUniformLocation( _shader_water.id, "uTexDudv" );
    _uniform_water_uTexBack = glGetUniformLocation( _shader_water.id, "uTexBack" );
index 2919e09ea415db95eab4e2a55b0983d44868e4c6..821e47f9269bbae32acf186f2b88238f210042b1 100644 (file)
@@ -1,5 +1,3 @@
-out vec4 FragColor;
-
 uniform sampler2D uTexDudv;
 
 uniform float uTime;
@@ -16,6 +14,7 @@ in vec3 aCo;
 in vec3 aWorldCo;
 
 #include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
 
 vec4 water_surf( vec3 halfview, vec3 vnorm, float depthvalue )
 {
@@ -32,6 +31,8 @@ vec4 water_surf( vec3 halfview, vec3 vnorm, float depthvalue )
 
 void main()
 {
+   compute_motion_vectors();
+
    // Surface colour composite
    float depthvalue = clamp( -world_depth_sample( aCo )*(1.0/25.0), 0.0, 1.0 );
 
@@ -56,5 +57,5 @@ void main()
    // Composite
    vec4 vsurface = water_surf( halfview, surfnorm, depthvalue );
    vsurface.a -= fdist;
-   FragColor = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );
+   oColour = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );
 }
index 8cc3f50a8406854b858f2d78d22842c4ad601f28..3da3db2a41d926b782ec57a83679fbdfe686b94b 100644 (file)
@@ -16,9 +16,21 @@ static struct vg_shader _shader_water_fast = {
 "layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "#line      2        0 \n"
+"#line       1        2 \n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+"   aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+"   aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line      3        0 \n"
 "\n"
 "uniform mat4x3 uMdl;\n"
 "uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec2 aUv;\n"
@@ -28,20 +40,23 @@ static struct vg_shader _shader_water_fast = {
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 world_pos = uMdl * vec4(a_co,1.0);\n"
-"   gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( a_co, 1.0 );\n"
+"   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+"   vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+"   gl_Position = vproj0;\n"
+"   aWorldCo = world_pos0;\n"
 "   aColour = a_colour;\n"
 "   aUv = a_uv;\n"
 "   aNorm = mat3(uMdl) * a_norm;\n"
 "   aCo = a_co;\n"
-"   aWorldCo = world_pos;\n"
 "}\n"
 ""},
    .fs = 
 {
 .static_src = 
-"out vec4 FragColor;\n"
-"\n"
 "uniform sampler2D uTexDudv;\n"
 "\n"
 "uniform float uTime;\n"
@@ -58,6 +73,8 @@ static struct vg_shader _shader_water_fast = {
 "in vec3 aWorldCo;\n"
 "\n"
 "#line       1        1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
 "layout (std140) uniform ub_world_lighting\n"
 "{\n"
 "   vec4 g_light_colours[3];\n"
@@ -161,7 +178,22 @@ static struct vg_shader _shader_water_fast = {
 "   return mix( vfrag, vec3(0.55,0.76,1.0), min( 1.0, dist ) );\n"
 "}\n"
 "\n"
-"#line     19        0 \n"
+"#line     17        0 \n"
+"#line       1        2 \n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+"   // Write motion vectors\n"
+"   vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+"   vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"   oMotionVec = vmotion1-vmotion0;\n"
+"}\n"
+"\n"
+"#line     18        0 \n"
 "\n"
 "vec4 water_surf( vec3 halfview, vec3 vnorm, float depthvalue )\n"
 "{\n"
@@ -178,6 +210,8 @@ static struct vg_shader _shader_water_fast = {
 "\n"
 "void main()\n"
 "{\n"
+"   compute_motion_vectors();\n"
+"\n"
 "   // Surface colour composite\n"
 "   float depthvalue = clamp( -world_depth_sample( aCo )*(1.0/25.0), 0.0, 1.0 );\n"
 "\n"
@@ -202,13 +236,14 @@ static struct vg_shader _shader_water_fast = {
 "   // Composite\n"
 "   vec4 vsurface = water_surf( halfview, surfnorm, depthvalue );\n"
 "   vsurface.a -= fdist;\n"
-"   FragColor = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );\n"
+"   oColour = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );\n"
 "}\n"
 ""},
 };
 
 static GLuint _uniform_water_fast_uMdl;
 static GLuint _uniform_water_fast_uPv;
+static GLuint _uniform_water_fast_uPvmPrev;
 static GLuint _uniform_water_fast_uTexDudv;
 static GLuint _uniform_water_fast_uTime;
 static GLuint _uniform_water_fast_uCamera;
@@ -222,6 +257,9 @@ static void shader_water_fast_uMdl(m4x3f m){
 static void shader_water_fast_uPv(m4x4f m){
    glUniformMatrix4fv(_uniform_water_fast_uPv,1,GL_FALSE,(float*)m);
 }
+static void shader_water_fast_uPvmPrev(m4x4f m){
+   glUniformMatrix4fv(_uniform_water_fast_uPvmPrev,1,GL_FALSE,(float*)m);
+}
 static void shader_water_fast_uTexDudv(int i){
    glUniform1i(_uniform_water_fast_uTexDudv,i);
 }
@@ -250,6 +288,7 @@ static void shader_water_fast_use(void){ glUseProgram(_shader_water_fast.id); }
 static void shader_water_fast_link(void){
    _uniform_water_fast_uMdl = glGetUniformLocation( _shader_water_fast.id, "uMdl" );
    _uniform_water_fast_uPv = glGetUniformLocation( _shader_water_fast.id, "uPv" );
+   _uniform_water_fast_uPvmPrev = glGetUniformLocation( _shader_water_fast.id, "uPvmPrev" );
    _uniform_water_fast_uTexDudv = glGetUniformLocation( _shader_water_fast.id, "uTexDudv" );
    _uniform_water_fast_uTime = glGetUniformLocation( _shader_water_fast.id, "uTime" );
    _uniform_water_fast_uCamera = glGetUniformLocation( _shader_water_fast.id, "uCamera" );
index 0b3310ab44781d01dc6ab747cb5c3ae3e8a0aef9..bb278ffa71726b4baf4e70c84fafed9d9c421f2b 100644 (file)
@@ -12,8 +12,8 @@
  */
 
 #define SR_NETWORKED
-
 #include "common.h"
+#include "conf.h"
 #include "steam.h"
 #include "render.h"
 #include "audio.h"
@@ -22,7 +22,8 @@
 #include "network.h"
 #include "menu.h"
 
-static int cl_ui     = 1;
+static int cl_ui      = 1,
+           cl_view_id = 0;
 
 int main( int argc, char *argv[] )
 {
@@ -45,20 +46,22 @@ VG_STATIC void vg_launch_opt(void)
 
 VG_STATIC void vg_preload(void)
 {
+   g_conf_init();
+
    vg_convar_push( (struct vg_convar){
       .name = "cl_ui",
       .data = &cl_ui,
       .data_type = k_convar_dtype_i32,
       .opt_i32 = { .min=0, .max=1, .clamp=1 },
-      .persistent = 1
+      .persistent = 0
    });
 
    vg_convar_push( (struct vg_convar){
-      .name = "cl_fov",
-      .data = &g_fov_option,
-      .data_type = k_convar_dtype_f32,
-      .opt_f32 = { .clamp = 0 },
-      .persistent = 1
+      .name = "cl_view_id",
+      .data = &cl_view_id,
+      .data_type = k_convar_dtype_i32,
+      .opt_i32 = { .min=0, .max=1, .clamp=1 },
+      .persistent = 0
    });
 
 vg_info(" Copyright  .        . .       -----, ,----- ,---.   .---.  \n" );
@@ -147,95 +150,121 @@ VG_STATIC void vg_framebuffer_resize( int w, int h )
    water_fb_resize();
 }
 
-VG_STATIC void render_main_game(void)
+VG_STATIC void present_view_with_post_processing(void)
 {
-   m4x4f world_4x4;
-   m4x3_expand( camera_mtx_inverse, world_4x4 );
+   glBindFramebuffer( GL_FRAMEBUFFER, 0 );
 
-   static float fov = 60.0f;
+   glEnable(GL_BLEND);
+   glDisable(GL_DEPTH_TEST);
+   glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
+   glBlendEquation(GL_FUNC_ADD);
 
-   float fov_target = vg_lerpf( 90.0f, 110.0f, g_fov_option );
+   shader_blitblur_use();
+   shader_blitblur_uTexMain( 0 );
+   shader_blitblur_uTexMotion( 1 );
+   shader_blitblur_uBlurStrength( cl_blur_strength );
+   glActiveTexture( GL_TEXTURE0 );
 
-   if( player.phys.on_board )
-      fov_target = vg_lerpf( 97.0f, 135.0f, g_fov_option );
+   if( cl_view_id == 0 )
+      glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
+   else if( cl_view_id == 1 )
+      glBindTexture( GL_TEXTURE_2D, gpipeline.mv_background );
+   else
+      glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
 
-   if( cl_menu )
-      fov_target = menu_fov_target;
+   glActiveTexture( GL_TEXTURE1 );
+   glBindTexture( GL_TEXTURE_2D, gpipeline.mv_background );
 
-   fov = vg_lerpf( fov, fov_target, vg.frame_delta * 2.0f );
+   render_fsquad();
+}
 
-   gpipeline.fov = freecam? 60.0f: fov; /* 120 */
-   m4x4_projection( vg.pv, gpipeline.fov, 
-         (float)vg.window_x / (float)vg.window_y, 
-         0.1f, 2100.0f );
+VG_STATIC void render_scene(void)
+{
+   glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_background );
+   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
 
-   m4x4_mul( vg.pv, world_4x4, vg.pv );
+   /* Draw world */
    glEnable( GL_DEPTH_TEST );
-   
-   /* 
-    * Draw world
-    */
 
-   int draw_solid = player.is_dead | freecam;
-   render_world( vg.pv, camera_mtx );
+   render_world( &main_camera );
+   render_water_texture( &main_camera );
+   glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_background );
+   render_water_surface( &main_camera );
+   render_world_gates( &main_camera );
+}
+
+VG_STATIC void render_menu(void)
+{
+   glClear( GL_DEPTH_BUFFER_BIT );
+   menu_render( &main_camera );
+}
 
-   if( draw_solid )
-      draw_player( camera_mtx );
+VG_STATIC void render_player_into_world(void)
+{
+   glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_background );
+   draw_player( &main_camera );
+}
+
+VG_STATIC void render_player_transparent(void)
+{
+   camera small_cam;
+   m4x3_copy( main_camera.transform, small_cam.transform );
 
-   render_water_texture( camera_mtx );
+   small_cam.fov = main_camera.fov;
+   small_cam.nearz = 0.05f;
+   small_cam.farz  = 60.0f;
+
+   camera_update_view( &small_cam );
+   camera_update_projection( &small_cam );
+   camera_finalize( &small_cam );
+
+   /* Draw player to window buffer and blend background ontop */
 
    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-   render_water_surface( vg.pv, camera_mtx );
-   render_world_gates( vg.pv, player.phys.rb.co, camera_mtx );
+   draw_player( &small_cam );
+}
 
+VG_STATIC void render_main_game(void)
+{
+   static float fov = 60.0f;
+   float fov_target = vg_lerpf( 90.0f, 110.0f, cl_fov );
+   if( player.phys.on_board )
+      fov_target = vg_lerpf( 97.0f, 135.0f, cl_fov );
    if( cl_menu )
-   {
-      glClear( GL_DEPTH_BUFFER_BIT );
-      menu_render( vg.pv );
-   }
-   
-   /* Copy the RGB of what we have into the background buffer */
-   glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
-   glBindFramebuffer( GL_DRAW_FRAMEBUFFER, gpipeline.fb_background );
-   glBlitFramebuffer( 0,0, vg.window_x, vg.window_y, 
-                      0,0, vg.window_x, vg.window_y,
-                      GL_COLOR_BUFFER_BIT,
-                      GL_LINEAR );
-   
-   /* Clear out the colour buffer, but keep depth */
-   glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-   glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
+      fov_target = menu_fov_target;
+   fov = vg_lerpf( fov, fov_target, vg.frame_delta * 2.0f );
+   fov = freecam? 60.0f: fov;
 
-   if( !player.is_dead )
-      glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
-   else
-      glClear( GL_COLOR_BUFFER_BIT );
+   main_camera.fov   = fov;
+   main_camera.nearz = 0.1f;
+   main_camera.farz  = 2100.0f;
+
+   camera_update_view( &main_camera );
+   camera_update_projection( &main_camera );
+   camera_finalize( &main_camera );
+
+   /* ========== Begin Frame ========== */
+
+   render_scene();
    
-   if( !draw_solid )
+   if( !cl_menu )
    {
-      m4x4_projection( vg.pv, gpipeline.fov, 
-            (float)vg.window_x / (float)vg.window_y, 
-            0.05f, 60.0f );
-      m4x4_mul( vg.pv, world_4x4, vg.pv );
-      draw_player( camera_mtx );
+      if( player.is_dead | freecam )
+         render_player_into_world();
+      else
+         render_player_transparent();
    }
 
-   /* Draw back in the background
-    *
-    * TODO: need to disable alpha write in the terrain shader so this works 
-    *       again.
-    */
-   glEnable(GL_BLEND);
-   glDisable(GL_DEPTH_TEST);
-   glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA);
-   glBlendEquation(GL_FUNC_ADD);
-   
-   shader_blit_use();
-   shader_blit_uTexMain( 0 );
-   glActiveTexture(GL_TEXTURE0);
-   glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background );
+   present_view_with_post_processing();
 
-   render_fsquad();
+   if( cl_menu ) 
+   {
+      render_menu();
+      render_player_transparent();
+   }
+
+   /* =========== End Frame =========== */
 }
 
 VG_STATIC void vg_render(void)
@@ -245,15 +274,15 @@ VG_STATIC void vg_render(void)
    glViewport( 0,0, vg.window_x, vg.window_y );
    glDisable( GL_DEPTH_TEST );
 
-   glClearColor( 0.11f, 0.35f, 0.37f, 1.0f );
-   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
+   glClearColor( 1.0f, 0.0f, 0.0f, 0.0f );
+   glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
 
    render_main_game();
    
    /* Other shite */
    glDisable(GL_BLEND);
    glDisable( GL_DEPTH_TEST );
-   vg_lines_drawall( (float *)vg.pv );
+   vg_lines_drawall( (float *)main_camera.mtx.pv );
    glViewport( 0,0, vg.window_x, vg.window_y );
 }
 
diff --git a/world.h b/world.h
index d3072785671a37955b62bcd75e10c1f13e0a5022..8ae85fcf2e4e689d56a11c9be6575bde243e2a12 100644 (file)
--- a/world.h
+++ b/world.h
@@ -436,10 +436,7 @@ VG_STATIC void world_init(void)
    vg_linear_clear( vg_mem.scratch );
    mdl_context *msky = mdl_load_full( vg_mem.scratch, "models/rs_skydome.mdl" );
 
-   mdl_node *nlower = mdl_node_from_name( msky, "dome_lower" ),
-            *nupper = mdl_node_from_name( msky, "dome_upper" );
-   
-   world.dome_lower = *mdl_node_submesh( msky, nlower, 0 );
+   mdl_node *nupper = mdl_node_from_name( msky, "dome_complete" );
    world.dome_upper = *mdl_node_submesh( msky, nupper, 0 );
 
    vg_acquire_thread_sync();
index b57c799fd33b68f31eb9a513fb8fc5f009253a52..004ee8ade1f44ae11ca48a09914e86a5578c61b5 100644 (file)
@@ -8,6 +8,7 @@
 #include "common.h"
 #include "model.h"
 #include "render.h"
+#include "camera.h"
 
 #include "shaders/gatelq.h"
 #include "world_water.h"
@@ -43,69 +44,70 @@ VG_STATIC void world_gates_init(void)
    vg_release_thread_sync();
 }
 
-VG_STATIC int render_gate( teleport_gate *gate, v3f viewpos, m4x3f camera )
+VG_STATIC int render_gate( teleport_gate *gate, camera *cam )
 {
    v3f viewdir, gatedir;
-   m3x3_mulv( camera, (v3f){0.0f,0.0f,-1.0f}, viewdir );
+   m3x3_mulv( cam->transform, (v3f){0.0f,0.0f,-1.0f}, viewdir );
    m3x3_mulv( gate->to_world, (v3f){0.0f,0.0f,-1.0f}, gatedir );
 
    v3f v0;
-   v3_sub( viewpos, gate->co[0], v0 );
+   v3_sub( cam->pos, gate->co[0], v0 );
    if( v3_dot(v0, gatedir) >= 0.0f )
       return 0;
 
-   if( v3_dist( viewpos, gate->co[0] ) > 100.0f )
+   if( v3_dist( cam->pos, gate->co[0] ) > 100.0f )
       return 0;
 
-   v3f a,b,c,d;
-
-   float sx = gate->dims[0],
-         sy = gate->dims[1];
-   m4x3_mulv( gate->to_world, (v3f){-sx,-sy,0.0f}, a );
-   m4x3_mulv( gate->to_world, (v3f){ sx,-sy,0.0f}, b );
-   m4x3_mulv( gate->to_world, (v3f){ sx, sy,0.0f}, c );
-   m4x3_mulv( gate->to_world, (v3f){-sx, sy,0.0f}, d );
+   {
+      v3f a,b,c,d;
 
-   vg_line( a,b, 0xffffa000 );
-   vg_line( b,c, 0xffffa000 );
-   vg_line( c,d, 0xffffa000 );
-   vg_line( d,a, 0xffffa000 );
+      float sx = gate->dims[0],
+            sy = gate->dims[1];
+      m4x3_mulv( gate->to_world, (v3f){-sx,-sy,0.0f}, a );
+      m4x3_mulv( gate->to_world, (v3f){ sx,-sy,0.0f}, b );
+      m4x3_mulv( gate->to_world, (v3f){ sx, sy,0.0f}, c );
+      m4x3_mulv( gate->to_world, (v3f){-sx, sy,0.0f}, d );
 
-   vg_line2( gate->co[0], gate->co[1], 0xff0000ff, 0x00000000 );
+      vg_line( a,b, 0xffffa000 );
+      vg_line( b,c, 0xffffa000 );
+      vg_line( c,d, 0xffffa000 );
+      vg_line( d,a, 0xffffa000 );
 
-   m4x3f cam_new;
-   m4x3_mul( gate->transport, camera, cam_new );
-   
-   vg_line_pt3( cam_new[3], 0.3f, 0xff00ff00 );
+      vg_line2( gate->co[0], gate->co[1], 0xff0000ff, 0x00000000 );
+   }
 
-   m4x3f gate_xform;
-   m4x3_copy( gate->to_world, gate_xform );
-   m4x3_scalev( gate_xform, (v3f){ gate->dims[0], gate->dims[1], 1.0f } );
-   
-   m4x3f inverse;
-   m4x3_invert_affine( cam_new, inverse );
+   /* update gate camera */
+   static camera gate_view;
+   gate_view.fov = cam->fov;
+   gate_view.nearz = 0.1f;
+   gate_view.farz  = 900.0f;
 
-   m4x4f view;
-   m4x3_expand( inverse, view );
+   m4x3_mul( gate->transport, cam->transform, gate_view.transform );
+   camera_update_view( &gate_view );
+   camera_update_projection( &gate_view );
 
+   /* Add special clipping plane to projection */
    v4f surface;
    m3x3_mulv( gate->recv_to_world, (v3f){0.0f,0.0f,-1.0f}, surface );
    surface[3] = v3_dot( surface, gate->co[1] );
-
-   m4x4f projection;
-   pipeline_projection( projection, 0.1f, 900.0f );
    
-   m4x3_mulp( inverse, surface, surface );
+   m4x3_mulp( gate_view.transform_inverse, surface, surface );
    surface[3] = -fabsf(surface[3]);
-   plane_clip_projection( projection, surface );
+   m4x4_clip_projection( gate_view.mtx.p, surface );
 
-   m4x4_mul( projection, view, projection );
+   /* Ready to draw with new camrea */
+   camera_finalize( &gate_view );
 
+   vg_line_pt3( gate_view.transform[3], 0.3f, 0xff00ff00 );
    {
+      m4x3f gate_xform;
+      m4x3_copy( gate->to_world, gate_xform );
+      m4x3_scalev( gate_xform, (v3f){ gate->dims[0], gate->dims[1], 1.0f } );
+   
       shader_gatelq_use();
-      shader_gatelq_uPv( vg.pv );
+      shader_gatelq_uPv( cam->mtx.pv );
       shader_gatelq_uMdl( gate_xform );
-      shader_gatelq_uCam( viewpos );
+      shader_gatelq_uCam( cam->pos );
       shader_gatelq_uTime( vg.time*0.25f );
       shader_gatelq_uInvRes( (v2f){
             1.0f / (float)vg.window_x,
@@ -124,16 +126,16 @@ VG_STATIC int render_gate( teleport_gate *gate, v3f viewpos, m4x3f camera )
       glStencilMask( 0x00 ); 
    }
 
-   render_world( projection, cam_new );
+   render_world( &gate_view );
 
    {
       glDisable( GL_STENCIL_TEST );
 
-      render_water_texture( cam_new );
+      render_water_texture( &gate_view );
       fb_use( NULL );
       glEnable( GL_STENCIL_TEST );
 
-      render_water_surface( projection, cam_new );
+      render_water_surface( &gate_view );
 
       glStencilMask( 0xFF );
       glStencilFunc( GL_ALWAYS, 1, 0xFF );
@@ -152,12 +154,16 @@ VG_STATIC int gate_intersect( teleport_gate *gate, v3f pos, v3f last )
    v3f v0, c, delta, p0;
    v3_sub( pos, last, v0 );
    float l = v3_length( v0 );
+
+   if( l == 0.0f )
+      return 0;
+
    v3_divs( v0, l, v0 );
 
    v3_muls( surface, surface[3], c );
    v3_sub( c, last, delta );
 
-   float d = v3_dot(surface, v0);
+   float d = v3_dot( surface, v0 );
 
    if( d > 0.00001f )
    {
index ee774bb7486fc63cd8488ec61c61c35c8931f803..d18c2c387e70680679ec95e1bc5bb1ad0e87d91e 100644 (file)
@@ -39,6 +39,8 @@ VG_STATIC void world_apply_procedural_foliage( struct world_material *mat )
    if( vg.quality_profile == k_quality_profile_low )
       return;
 
+   vg_info( "Applying foliage (%u)\n", mat->info.pstr_name );
+
    vg_linear_clear( vg_mem.scratch );
 
    mdl_context *mfoliage = 
@@ -461,13 +463,6 @@ VG_STATIC void world_generate(void)
 
    world.scene_no_collide = scene_init( world.dynamic_vgl, 200000, 500000 );
 
-#if 0
-   vg_info( "Applying foliage\n" );
-   srand(0);
-   world_apply_procedural_foliage();
-   scene_copy_slice( world.scene_no_collide, &world.sm_foliage_main );
-#endif
-
    for( int i=0; i<world.material_count; i++ )
    {
       struct world_material *mat = &world.materials[ i ];
@@ -524,8 +519,7 @@ VG_STATIC void world_post_process(void)
       /* 
        * Rendering the depth map
        */
-      m4x4f ortho;
-      m4x3f camera;
+      camera ortho;
 
       v3f extent;
       v3_sub( world.scene_geo->bbx[1], world.scene_geo->bbx[0], extent );
@@ -537,13 +531,15 @@ VG_STATIC void world_post_process(void)
             rl = 1.0f / (fr-fl),
             tb = 1.0f / (ft-fb);
 
-      m4x4_zero( ortho );
-      ortho[0][0] = 2.0f * rl;
-      ortho[2][1] = 2.0f * tb;
-      ortho[3][0] = (fr + fl) * -rl;
-      ortho[3][1] = (ft + fb) * -tb;
-      ortho[3][3] = 1.0f;
-      m4x3_identity( camera );
+      m4x4_zero( ortho.mtx.p );
+      ortho.mtx.p[0][0] = 2.0f * rl;
+      ortho.mtx.p[2][1] = 2.0f * tb;
+      ortho.mtx.p[3][0] = (fr + fl) * -rl;
+      ortho.mtx.p[3][1] = (ft + fb) * -tb;
+      ortho.mtx.p[3][3] = 1.0f;
+      m4x3_identity( ortho.transform );
+      camera_update_view( &ortho );
+      camera_finalize( &ortho );
 
       glDisable(GL_DEPTH_TEST);
       glDisable(GL_BLEND);
@@ -558,12 +554,12 @@ VG_STATIC void world_post_process(void)
       glEnable(GL_BLEND);
       glBlendFunc(GL_ONE, GL_ONE);
       glBlendEquation(GL_MAX);
-      render_world_depth( ortho, camera );
+
+      render_world_depth( &ortho );
       glDisable(GL_BLEND);
       glEnable(GL_DEPTH_TEST);
       glBindFramebuffer( GL_FRAMEBUFFER, 0 );
 
-
       /* 
        * TODO: World settings entity
        */
index ae9399bf8e02d711484159672c0384bd8aaabc9b..68c0ceb91a88efe8cd22635d158fc7d00a6118c3 100644 (file)
@@ -5,6 +5,7 @@
 #ifndef WORLD_RENDER_H
 #define WORLD_RENDER_H
 
+#include "camera.h"
 #include "world.h"
 
 vg_tex2d tex_terrain_noise = { .path = "textures/garbage.qoi",
@@ -21,7 +22,7 @@ VG_STATIC void world_render_init(void)
    vg_release_thread_sync();
 }
 
-VG_STATIC void render_world_depth( m4x4f projection, m4x3f camera );
+VG_STATIC void render_world_depth( camera *cam );
 
 /*
  * Rendering
@@ -74,7 +75,7 @@ VG_STATIC void bindpoint_diffuse_texture1( struct world_material *mat )
    glBindTexture( GL_TEXTURE_2D, world.textures[ mat->info.tex_diffuse ] );
 }
 
-VG_STATIC void render_world_vb( m4x4f projection, v3f camera )
+VG_STATIC void render_world_vb( camera *cam )
 {
    m4x3f identity_matrix;
    m4x3_identity( identity_matrix );
@@ -85,15 +86,16 @@ VG_STATIC void render_world_vb( m4x4f projection, v3f camera )
    shader_link_standard_ub( _shader_vblend.id, 2 );
    vg_tex2d_bind( &tex_terrain_noise, 0 );
 
-   shader_vblend_uPv( projection );
+   shader_vblend_uPv( cam->mtx.pv );
+   shader_vblend_uPvmPrev( cam->mtx_prev.pv );
    shader_vblend_uMdl( identity_matrix );
-   shader_vblend_uCamera( camera );
+   shader_vblend_uCamera( cam->transform[3] );
 
    world_render_both_stages( k_shader_standard_vertex_blend, 
                              bindpoint_diffuse_texture1 );
 }
 
-VG_STATIC void render_world_standard( m4x4f projection, v3f camera )
+VG_STATIC void render_world_standard( camera *cam )
 {
    m4x3f identity_matrix;
    m4x3_identity( identity_matrix );
@@ -101,18 +103,19 @@ VG_STATIC void render_world_standard( m4x4f projection, v3f camera )
    shader_standard_use();
    shader_standard_uTexGarbage(0);
    shader_standard_uTexMain(1);
+   shader_standard_uPv( cam->mtx.pv );
+   shader_standard_uPvmPrev( cam->mtx_prev.pv );
    shader_link_standard_ub( _shader_standard.id, 2 );
    bind_terrain_noise();
 
-   shader_standard_uPv( projection );
    shader_standard_uMdl( identity_matrix );
-   shader_standard_uCamera( camera );
+   shader_standard_uCamera( cam->transform[3] );
    
    world_render_both_stages( k_shader_standard,
                              bindpoint_diffuse_texture1 );
 }
 
-VG_STATIC void render_world_alphatest( m4x4f projection, v3f camera )
+VG_STATIC void render_world_alphatest( camera *cam )
 {
    m4x3f identity_matrix;
    m4x3_identity( identity_matrix );
@@ -120,12 +123,13 @@ VG_STATIC void render_world_alphatest( m4x4f projection, v3f camera )
    shader_alphatest_use();
    shader_alphatest_uTexGarbage(0);
    shader_alphatest_uTexMain(1);
+   shader_alphatest_uPv( cam->mtx.pv );
+   shader_alphatest_uPvmPrev( cam->mtx_prev.pv );
    shader_link_standard_ub( _shader_alphatest.id, 2 );
    bind_terrain_noise();
 
-   shader_alphatest_uPv( projection );
    shader_alphatest_uMdl( identity_matrix );
-   shader_alphatest_uCamera( camera );
+   shader_alphatest_uCamera( cam->transform[3] );
 
    glDisable(GL_CULL_FACE);
    
@@ -144,7 +148,7 @@ VG_STATIC void bindpoint_terrain( struct world_material *mat )
    shader_terrain_uBlendOffset( mat->info.colour1 );
 }
 
-VG_STATIC void render_terrain( m4x4f projection, v3f camera )
+VG_STATIC void render_terrain( camera *cam )
 {
    m4x3f identity_matrix;
    m4x3_identity( identity_matrix );
@@ -156,53 +160,48 @@ VG_STATIC void render_terrain( m4x4f projection, v3f camera )
 
    vg_tex2d_bind( &tex_terrain_noise, 0 );
 
-   shader_terrain_uPv( projection );
+   shader_terrain_uPv( cam->mtx.pv );
+   shader_terrain_uPvmPrev( cam->mtx_prev.pv );
+
    shader_terrain_uMdl( identity_matrix );
-   shader_terrain_uCamera( camera );
+   shader_terrain_uCamera( cam->transform[3] );
 
    world_render_both_stages( k_shader_terrain_blend, bindpoint_terrain );
 }
 
-VG_STATIC void render_lowerdome( m4x3f camera )
-{
-   m4x4f projection, full;
-   pipeline_projection( projection, 0.4f, 1000.0f );
-
-   m4x3f inverse;
-   m3x3_transpose( camera, inverse );
-   v3_copy((v3f){0.0f,0.0f,0.0f}, inverse[3]);
-   m4x3_expand( inverse, full );
-   m4x4_mul( projection, full, full );
-
-   m4x3f identity_matrix;
-   m4x3_identity( identity_matrix );
-   
-   shader_planeinf_use();
-   shader_planeinf_uMdl(identity_matrix);
-   shader_planeinf_uPv(full);
-   shader_planeinf_uCamera(camera[3]);
-   shader_planeinf_uPlane( (v4f){0.0f,1.0f,0.0f,0.0f} );
-   
-   mdl_draw_submesh( &world.dome_lower );
-}
-
-VG_STATIC void render_sky(m4x3f camera)
+VG_STATIC void render_sky( camera *cam )
 {
-   m4x4f projection, full;
-   pipeline_projection( projection, 0.4f, 1000.0f );
-
-   m4x3f inverse;
-   m3x3_transpose( camera, inverse );
-   v3_copy((v3f){0.0f,0.0f,0.0f}, inverse[3]);
-   m4x3_expand( inverse, full );
-   m4x4_mul( projection, full, full );
+   /* 
+    * Modify matrix to remove clipping and view translation
+    */
+   m4x4f v,
+         v_prev,
+         pv,
+         pv_prev;
+
+   m4x4_copy( cam->mtx.v, v );
+   m4x4_copy( cam->mtx_prev.v, v_prev );
+   v3_zero( v[3] );
+   v3_zero( v_prev[3] );
+
+   m4x4_copy( cam->mtx.p,      pv );
+   m4x4_copy( cam->mtx_prev.p, pv_prev );
+   m4x4_reset_clipping( pv,      cam->farz, cam->nearz );
+   m4x4_reset_clipping( pv_prev, cam->farz, cam->nearz );
+
+   m4x4_mul( pv,      v,      pv );
+   m4x4_mul( pv_prev, v_prev, pv_prev );
 
    m4x3f identity_matrix;
    m4x3_identity( identity_matrix );
    
+   /*
+    * Draw
+    */
    shader_sky_use();
-   shader_sky_uMdl(identity_matrix);
-   shader_sky_uPv(full);
+   shader_sky_uMdl( identity_matrix );
+   shader_sky_uPv( pv );
+   shader_sky_uPvmPrev( pv_prev );
    shader_sky_uTexGarbage(0);
    shader_sky_uTime( world.sky_time );
 
@@ -218,7 +217,7 @@ VG_STATIC void render_sky(m4x3f camera)
    glDepthMask( GL_TRUE );
 }
 
-VG_STATIC void render_world_gates( m4x4f projection, v3f playerco, m4x3f camera )
+VG_STATIC void render_world_gates( camera *cam )
 {
    if( !world.gate_count )
       return;
@@ -229,7 +228,7 @@ VG_STATIC void render_world_gates( m4x4f projection, v3f playerco, m4x3f camera
    for( int i=0; i<world.gate_count; i++ )
    {
       struct route_gate *rg = &world.gates[i];
-      float dist = v3_dist2( rg->gate.co[0], camera[3] );
+      float dist = v3_dist2( rg->gate.co[0], cam->transform[3] );
 
       if( dist < closest )
       {
@@ -238,22 +237,24 @@ VG_STATIC void render_world_gates( m4x4f projection, v3f playerco, m4x3f camera
       }
    }
 
-   render_gate( &world.gates[id].gate, playerco, camera );
+   render_gate( &world.gates[id].gate, cam );
    v3_lerp( world.render_gate_pos, 
             world.gates[id].gate.co[0],
             1.0f,
             world.render_gate_pos );
 }
 
-VG_STATIC void render_world( m4x4f projection, m4x3f camera )
+VG_STATIC void render_world( camera *cam )
 {
-   render_sky( camera );
-   render_world_routes( projection, camera[3] );
-   render_world_standard( projection, camera[3] );
-   render_world_vb( projection, camera[3] );
-   render_world_alphatest( projection, camera[3] );
-   render_terrain( projection, camera[3] );
+   render_sky( cam );
+
+   render_world_routes( cam );
+   render_world_standard( cam );
+   render_world_vb( cam );
+   render_world_alphatest( cam );
+   render_terrain( cam );
 
+   /* Render SFD's */
    int closest = 0;
    float min_dist = INFINITY;
 
@@ -262,8 +263,7 @@ VG_STATIC void render_world( m4x4f projection, m4x3f camera )
 
    for( int i=0; i<world.route_count; i++ )
    {
-      float dist = v3_dist2( world.routes[i].scoreboard_transform[3],
-                              camera[3] );
+      float dist = v3_dist2(world.routes[i].scoreboard_transform[3], cam->pos);
 
       if( dist < min_dist )
       {
@@ -272,18 +272,18 @@ VG_STATIC void render_world( m4x4f projection, m4x3f camera )
       }
    }
 
-   sfd_render( projection, camera[3], 
-               world.routes[closest].scoreboard_transform );
+   sfd_render( cam, world.routes[closest].scoreboard_transform );
 }
 
-VG_STATIC void render_world_depth( m4x4f projection, m4x3f camera )
+VG_STATIC void render_world_depth( camera *cam )
 {
    m4x3f identity_matrix;
    m4x3_identity( identity_matrix );
 
    shader_gpos_use();
-   shader_gpos_uCamera( camera[3] );
-   shader_gpos_uPv( projection );
+   shader_gpos_uCamera( cam->transform[3] );
+   shader_gpos_uPv( cam->mtx.pv );
+   shader_gpos_uPvmPrev( cam->mtx_prev.pv );
    shader_gpos_uMdl( identity_matrix );
    
    mesh_bind( &world.mesh_geo );
index 795f57b9f3eae6143abb3eb520c589b1c05943e8..7d4ef7c7778b8fd53cf17622595d9371aea05dd8 100644 (file)
@@ -1132,7 +1132,7 @@ VG_STATIC void world_routes_update(void)
 }
 
 VG_STATIC void bind_terrain_noise(void);
-VG_STATIC void render_world_routes( m4x4f projection, v3f camera )
+VG_STATIC void render_world_routes( camera *cam )
 {
    m4x3f identity_matrix;
    m4x3_identity( identity_matrix );
@@ -1142,9 +1142,10 @@ VG_STATIC void render_world_routes( m4x4f projection, v3f camera )
    shader_link_standard_ub( _shader_route.id, 2 );
    bind_terrain_noise();
 
-   shader_route_uPv( projection );
+   shader_route_uPv( cam->mtx.pv );
+   shader_route_uPvmPrev( cam->mtx_prev.pv );
    shader_route_uMdl( identity_matrix );
-   shader_route_uCamera( camera );
+   shader_route_uCamera( cam->transform[3] );
 
    mesh_bind( &world.mesh_route_lines );
 
index 3f94c4ed86fae271a5948d20c521179ccf395c65..9f41992bc84de7d43e42634797bd9d22038cc7a1 100644 (file)
@@ -102,7 +102,7 @@ VG_STATIC void sfd_update(void)
 }
 
 VG_STATIC void bind_terrain_noise(void);
-VG_STATIC void sfd_render( m4x4f projection, v3f camera, m4x3f transform )
+VG_STATIC void sfd_render( camera *cam, m4x3f transform )
 {
    mesh_bind( &world.sfd.mesh_display );
 
@@ -113,9 +113,14 @@ VG_STATIC void sfd_render( m4x4f projection, v3f camera, m4x3f transform )
    bind_terrain_noise();
    vg_tex2d_bind( &tex_scoretext, 1 );
 
-   shader_scoretext_uPv( projection );
+   m4x4f pvm_prev;
+   m4x3_expand( transform, pvm_prev );
+   m4x4_mul( cam->mtx_prev.pv, pvm_prev, pvm_prev );
+
+   shader_scoretext_uPv( cam->mtx.pv );
+   shader_scoretext_uPvmPrev( pvm_prev );
    shader_scoretext_uMdl( transform );
-   shader_scoretext_uCamera( camera );
+   shader_scoretext_uCamera( cam->transform[3] );
 
    for( int y=0;y<world.sfd.h; y++ )
    {
@@ -134,9 +139,11 @@ VG_STATIC void sfd_render( m4x4f projection, v3f camera, m4x3f transform )
    bind_terrain_noise();
    vg_tex2d_bind( &tex_scoretext, 1 );
 
-   shader_vblend_uPv( projection );
+   shader_vblend_uPv( cam->mtx.pv );
+   shader_vblend_uPvmPrev( pvm_prev );
+
    shader_vblend_uMdl( transform );
-   shader_vblend_uCamera( camera );
+   shader_vblend_uCamera( cam->transform[3] );
    
    mesh_bind( &world.sfd.mesh_base );
    mesh_draw( &world.sfd.mesh_base );
index 4281981c5549376742e930e0883eb2ee22b5b240..e054a111a788dea8440d06be1e8ac473f5e03227 100644 (file)
@@ -51,7 +51,10 @@ VG_STATIC void water_set_surface( float height )
    v4_copy( (v4f){ 0.0f, 1.0f, 0.0f, height }, world.water.plane );
 }
 
-VG_STATIC void render_water_texture( m4x3f camera )
+/*
+ * Does not write motion vectors
+ */
+VG_STATIC void render_water_texture( camera *cam )
 {
    if( !world.water.enabled || (vg.quality_profile == k_quality_profile_low) )
       return;
@@ -60,69 +63,66 @@ VG_STATIC void render_water_texture( m4x3f camera )
    fb_use( &world.water.fbreflect );
    glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
 
-   m4x3f new_cam, inverse;
-   v3_copy( camera[3], new_cam[3] );
-   new_cam[3][1] -= 2.0f * (camera[3][1] - world.water.height);
+   /* 
+    * Create flipped view matrix. Don't care about motion vectors
+    */
+   float cam_height = cam->transform[3][1] - world.water.height;
+
+   camera water_cam;
+   v3_copy( cam->transform[3], water_cam.transform[3] );
+   water_cam.transform[3][1] -= 2.0f * cam_height;
 
    m3x3f flip;
    m3x3_identity( flip );
    flip[1][1] = -1.0f;
-   m3x3_mul( flip, camera, new_cam );
-
-
-   v3f p0;
-   m3x3_mulv( new_cam, (v3f){0.0f,0.0f,-1.0f}, p0 );
-   v3_add( new_cam[3], p0, p0 );
-   vg_line( new_cam[3], p0, 0xffffffff );
-
-   m4x4f view;
-   vg_line_pt3( new_cam[3], 0.3f, 0xff00ffff );
+   m3x3_mul( flip, cam->transform, water_cam.transform );
 
-   m4x3_invert_affine( new_cam, inverse );
-   m4x3_expand( inverse, view );
+   camera_update_view( &water_cam );
 
+   /* 
+    * Create clipped projection 
+    */
    v4f clippa = { 0.0f, 1.0f, 0.0f, world.water.height-0.1f };
-   m4x3_mulp( inverse, clippa, clippa );
+   m4x3_mulp( water_cam.transform_inverse, clippa, clippa );
    clippa[3] *= -1.0f;
 
-   m4x4f projection;
-   m4x4_projection( projection,
-         gpipeline.fov,
-         (float)vg.window_x / (float)vg.window_y, 
-         0.1f, 900.0f );
-   plane_clip_projection( projection, clippa );
-   m4x4_mul( projection, view, projection );
+   m4x4_copy( cam->mtx.p, water_cam.mtx.p );
+   m4x4_clip_projection( water_cam.mtx.p, clippa );
 
+   camera_finalize( &water_cam );
+
+   /*
+    * Draw world
+    */
    glCullFace( GL_FRONT );
-   render_world( projection, new_cam );
+   render_world( &water_cam );
    glCullFace( GL_BACK );
-
-
-   /* Draw beneath texture */
+   
+   /*
+    * Create beneath view matrix
+    */
+   camera beneath_cam;
    fb_use( &world.water.fbdepth );
    glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
 
-   m4x3_invert_affine( camera, inverse );
-   m4x3_expand( inverse, view );
+   m4x3_copy( cam->transform, beneath_cam.transform );
+   camera_update_view( &beneath_cam );
+
+   float bias = -(cam->transform[3][1]-world.water.height)*0.1f;
 
-   float bias = -(camera[3][1]-world.water.height)*0.1f;
    v4f clippb = { 0.0f, -1.0f, 0.0f, -(world.water.height) + bias };
-   m4x3_mulp( inverse, clippb, clippb );
+   m4x3_mulp( beneath_cam.transform_inverse, clippb, clippb );
    clippb[3] *= -1.0f;
 
-   m4x4_projection( projection,
-         gpipeline.fov,
-         (float)vg.window_x / (float)vg.window_y, 
-         0.1f, 900.0f );
+   m4x4_copy( cam->mtx.p, beneath_cam.mtx.p );
+   m4x4_clip_projection( beneath_cam.mtx.p, clippb );
+   camera_finalize( &beneath_cam );
 
-   plane_clip_projection( projection, clippb );
-   m4x4_mul( projection, view, projection );
-   render_world_depth( projection, camera );
-   
+   render_world_depth( &beneath_cam );
    glViewport( 0, 0, vg.window_x, vg.window_y );
 }
 
-VG_STATIC void render_water_surface( m4x4f pv, m4x3f camera )
+VG_STATIC void render_water_surface( camera *cam )
 {
    if( !world.water.enabled )
       return;
@@ -146,10 +146,11 @@ VG_STATIC void render_water_surface( m4x4f pv, m4x3f camera )
       fb_bindtex( &world.water.fbdepth, 3 );
       shader_water_uTexBack( 3 );
       shader_water_uTime( world.time );
-      shader_water_uCamera( camera[3] );
+      shader_water_uCamera( cam->transform[3] );
       shader_water_uSurfaceY( world.water.height );
 
-      shader_water_uPv( pv );
+      shader_water_uPv( cam->mtx.pv );
+      shader_water_uPvmPrev( cam->mtx_prev.pv );
 
       m4x3f full;
       m4x3_identity( full );
@@ -183,14 +184,15 @@ VG_STATIC void render_water_surface( m4x4f pv, m4x3f camera )
       vg_tex2d_bind( &tex_water_surf, 1 );
       shader_water_fast_uTexDudv( 1 );
       shader_water_fast_uTime( world.time );
-      shader_water_fast_uCamera( camera[3] );
+      shader_water_fast_uCamera( cam->transform[3] );
       shader_water_fast_uSurfaceY( world.water.height );
       shader_link_standard_ub( _shader_water_fast.id, 2 );
 
       m4x3f full;
       m4x3_identity( full );
       shader_water_fast_uMdl( full );
-      shader_water_fast_uPv( pv );
+      shader_water_fast_uPv( cam->mtx.pv );
+      shader_water_fast_uPvmPrev( cam->mtx_prev.pv );
 
       glEnable(GL_BLEND);
       glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);