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 );
}
{
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" );
}
#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 */
};
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
--- /dev/null
+#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 */
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 );
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
{
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;
}
{
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 );
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}
},
};
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;
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();
}
}
-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() )
{
/* 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;
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);
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++ )
#define PLAYER_REWIND_FRAMES 60*4
+#include "conf.h"
#include "audio.h"
#include "common.h"
#include "world.h"
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;
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,
/* 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 )
{
player.rewind_sound_wait = 0;
}
}
-
-
}
int i0 = floorf( player.rewind_time ),
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();
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,
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 );
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++ )
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) );
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 };
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;
#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
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
}
};
-/*
- * 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
*/
{
if( !fb )
{
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_background );
glViewport( 0, 0, vg.window_x, vg.window_y );
}
else
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 );
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();
}
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 );
"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"
"\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"
"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"
" 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"
" 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;
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);
}
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" );
out vec4 FragColor;
uniform sampler2D uTexMain;
+uniform sampler2D uTexMotion;
+uniform float uBlurStrength;
+uniform float uBlurExponent;
in vec2 aUv;
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;
}
.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"
"\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 */
--- /dev/null
+#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 */
+layout (location = 0) out vec4 oColour;
+
layout (std140) uniform ub_world_lighting
{
vec4 g_light_colours[3];
"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"
"\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 =
"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"
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){
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);
}
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" );
}
"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"
"\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 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){
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);
}
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" );
}
--- /dev/null
+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;
+}
--- /dev/null
+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 );
+}
"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 =
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){
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);
}
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" );
}
-out vec4 FragColor;
-
uniform sampler2D uTexGarbage;
uniform sampler2D uTexGradients;
uniform vec3 uCamera;
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
vfrag = do_light_shadowing( vfrag );
vfrag = apply_fog( vfrag, fdist );
- FragColor = vec4(vfrag, 1.0 );
+ oColour = vec4(vfrag, 1.0 );
}
"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"
"\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"
"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"
" 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"
" 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;
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);
}
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" );
"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"
" 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"
.fs =
{
.static_src =
-"out vec4 FragColor;\n"
-"\n"
"uniform sampler2D uTexGarbage;\n"
"uniform sampler2D uTexGradients;\n"
"uniform vec3 uCamera;\n"
"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"
" 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"
" 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);
}
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" );
#include "vertex_standard.glsl"
+#include "motion_vectors_vs.glsl"
-uniform mat4 uPv;
uniform mat4x3 uMdl;
+uniform mat4 uPv;
+uniform mat4 uPvmPrev;
uniform vec3 uInfo;
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;
-out vec4 FragColor;
+layout (location = 0) out vec4 oColour;
uniform vec4 uColour;
uniform sampler2D uTexGarbage;
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 );
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);
}
"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"
"\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"
"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"
" 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;
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);
}
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" );
-out vec4 FragColor;
-
uniform sampler2D uTexGarbage;
uniform sampler2D uTexMain;
uniform vec3 uCamera;
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);
vfrag = do_light_shadowing( vfrag );
vfrag = apply_fog( vfrag, fdist );
- FragColor = vec4(vfrag, 1.0);
+ oColour = vec4(vfrag, 1.0);
}
"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"
"\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"
"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"
" 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"
" 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;
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);
}
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" );
#include "vertex_standard.glsl"
+#include "motion_vectors_vs.glsl"
uniform mat4x3 uMdl;
uniform mat4 uPv;
+uniform mat4 uPvmPrev;
out vec4 aColour;
out vec2 aUv;
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;
}
#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;
aNorm = world_normal;
aCo = a_co;
aWorldCo = world_pos;
+
+ // TODO:
+ aMotionVec0 = vec3(1.0);
+ aMotionVec1 = vec3(1.0);
}
-out vec4 FragColor;
-
uniform sampler2D uTexGarbage;
uniform sampler2D uTexMain;
uniform vec3 uCamera;
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);
vfrag = do_light_shadowing( vfrag );
vfrag = apply_fog( vfrag, fdist );
- FragColor = vec4(vfrag, 1.0);
+ oColour = vec4(vfrag, 1.0);
}
-out vec4 FragColor;
-
uniform sampler2D uTexGarbage;
uniform sampler2D uTexGradients;
uniform vec3 uCamera;
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
vfrag = do_light_shadowing( vfrag );
vfrag = apply_fog( vfrag, fdist );
- FragColor = vec4(vfrag, 1.0 );
+ oColour = vec4(vfrag, 1.0 );
}
"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"
"\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"
"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"
" 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"
" 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;
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);
}
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" );
-out vec4 FragColor;
-
uniform sampler2D uTexGarbage;
uniform sampler2D uTexGradients;
uniform vec3 uCamera;
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
vfrag = do_light_shadowing( vfrag );
vfrag = apply_fog( vfrag, fdist );
- FragColor = vec4(vfrag, 1.0 );
+ oColour = vec4(vfrag, 1.0 );
}
"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"
"\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"
"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"
" 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"
" 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;
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);
}
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" );
-out vec4 FragColor;
-
uniform sampler2D uTexMain;
uniform vec3 uCamera;
in vec3 aWorldCo;
#include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
void main()
{
+ compute_motion_vectors();
+
vec3 vfrag = texture( uTexMain, aUv ).rgb;
// Lighting
vfrag = apply_fog( vfrag, fdist );
float opacity = clamp( fdist*fdist, 0.1, 1.0 );
- FragColor = vec4(vfrag,opacity);
+ oColour = vec4(vfrag,opacity);
}
"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"
" 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"
"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"
" 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"
" 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"
""},
};
-out vec4 FragColor;
-
uniform sampler2D uTexMain;
uniform sampler2D uTexDudv;
uniform sampler2D uTexBack;
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 )
void main()
{
+ compute_motion_vectors();
+
// Create texture coords
vec2 ssuv = gl_FragCoord.xy*uInvRes;
// 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 );
}
"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"
"\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"
"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"
" 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"
"\n"
"void main()\n"
"{\n"
+" compute_motion_vectors();\n"
+"\n"
" // Create texture coords\n"
" vec2 ssuv = gl_FragCoord.xy*uInvRes;\n"
" \n"
" // 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;
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);
}
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" );
-out vec4 FragColor;
-
uniform sampler2D uTexDudv;
uniform float uTime;
in vec3 aWorldCo;
#include "common_world.glsl"
+#include "motion_vectors_fs.glsl"
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 );
// 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 );
}
"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"
"\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"
"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"
" 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"
"\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"
" // 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;
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);
}
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" );
*/
#define SR_NETWORKED
-
#include "common.h"
+#include "conf.h"
#include "steam.h"
#include "render.h"
#include "audio.h"
#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[] )
{
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" );
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)
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 );
}
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();
#include "common.h"
#include "model.h"
#include "render.h"
+#include "camera.h"
#include "shaders/gatelq.h"
#include "world_water.h"
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,
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 );
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 )
{
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 =
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 ];
/*
* 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 );
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);
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
*/
#ifndef WORLD_RENDER_H
#define WORLD_RENDER_H
+#include "camera.h"
#include "world.h"
vg_tex2d tex_terrain_noise = { .path = "textures/garbage.qoi",
vg_release_thread_sync();
}
-VG_STATIC void render_world_depth( m4x4f projection, m4x3f camera );
+VG_STATIC void render_world_depth( camera *cam );
/*
* Rendering
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 );
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 );
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 );
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);
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 );
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 );
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;
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 )
{
}
}
- 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;
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 )
{
}
}
- 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 );
}
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 );
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 );
}
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 );
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++ )
{
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 );
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;
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;
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 );
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);