From: hgn Date: Mon, 20 Nov 2023 10:02:40 +0000 (+0000) Subject: chaos pt 2 X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=d171c9ad5de05c9ac8563fcf9f23760b93fb50f8;p=carveJwlIkooP6JGAAIwe30JlM.git chaos pt 2 --- diff --git a/build.c b/build.c index 4cf3b34..0470a3b 100644 --- a/build.c +++ b/build.c @@ -275,5 +275,6 @@ void build_shaders(void){ _S( "blit", "blit.vs", "blit.fs" ); _S( "blitblur", "blit.vs", "blitblur.fs" ); _S( "blitcolour","blit.vs", "colour.fs" ); + _S( "blit_transition", "blit.vs", "blit_transition.fs" ); _S( "routeui", "routeui.vs", "routeui.fs" ); } diff --git a/camera.h b/camera.h index c1744d8..7bd14e6 100644 --- a/camera.h +++ b/camera.h @@ -29,11 +29,10 @@ static void camera_lerp_angles( v3f a, v3f b, float t, v3f d ){ d[2] = vg_lerpf( a[2], b[2], t ); } +/* lerp position, fov, and angles */ static void camera_lerp( camera *a, camera *b, float t, camera *d ){ v3_lerp( a->pos, b->pos, t, d->pos ); - d->angles[0] = vg_alerpf( a->angles[0], b->angles[0], t ); - d->angles[1] = vg_lerpf( a->angles[1], b->angles[1], t ); - d->angles[2] = vg_lerpf( a->angles[2], b->angles[2], t ); + camera_lerp_angles( a->angles, b->angles, t, d->angles ); d->fov = vg_lerpf( a->fov, b->fov, t ); } @@ -43,6 +42,16 @@ static void camera_copy( camera *a, camera *d ){ d->fov = a->fov; } +static void m4x3_transform_camera( m4x3f m, camera *cam ){ + m4x3_mulv( m, cam->pos, cam->pos ); + + v3f v0; + v3_angles_vector( cam->angles, v0 ); + m3x3_mulv( m, v0, v0 ); + v3_normalize( v0 ); + v3_angles( v0, cam->angles ); +} + /* * 1) [angles, pos] -> transform */ diff --git a/ent_miniworld.c b/ent_miniworld.c index cd79b45..9c439c7 100644 --- a/ent_miniworld.c +++ b/ent_miniworld.c @@ -13,14 +13,10 @@ static void ent_miniworld_call( world_instance *world, ent_call *call ){ const char *uid = mdl_pstr( &world->meta, miniworld->pstr_world ); skaterift_load_world_command( 1, (const char *[]){ uid } ); - global_miniworld.active_id = call->id; + global_miniworld.active = miniworld; } else if( call->function == 1 ){ - - if( global_miniworld.active_id == call->id ) - global_miniworld.active_id = 0; - else - vg_warn( "bad call\n" ); + global_miniworld.active = NULL; if( miniworld->proxy ){ ent_prop *prop = mdl_arritm( &world->ent_prop, @@ -30,17 +26,19 @@ static void ent_miniworld_call( world_instance *world, ent_call *call ){ } } -static void ent_miniworld_render( world_instance *host_world ){ - u32 entity_id = global_miniworld.active_id; +static void ent_miniworld_render( world_instance *host_world, camera *cam ){ + if( host_world != &world_static.instances[k_world_purpose_hub] ) + return; + + ent_miniworld *miniworld = global_miniworld.active; - if( !entity_id ) + if( !miniworld ) return; - - ent_miniworld *miniworld = mdl_arritm( &host_world->ent_miniworld, - mdl_entity_id_id(entity_id) ); + + world_instance *dest_world = &world_static.instances[k_world_purpose_client]; int rendering = 1; - if( miniworld->purpose == k_world_purpose_invalid ) + if( dest_world->status != k_world_status_loaded ) rendering = 0; if( miniworld->proxy ){ @@ -52,24 +50,48 @@ static void ent_miniworld_render( world_instance *host_world ){ prop->flags |= 0x1; } + if( !rendering ) return; - world_instance *dest_world = &world_static.instances[miniworld->purpose]; - - m4x3f mmdl; mdl_transform_m4x3( &miniworld->transform, mmdl ); - render_world_override( dest_world, host_world, mmdl ); - + render_world_override( dest_world, host_world, mmdl, cam ); //render_world_routes( , &skaterift.cam, 1 ); } static void ent_miniworld_preupdate(void){ - if( !global_miniworld.active_id ) + if( world_static.active_instance == k_world_purpose_client ){ + if( button_down(k_srbind_mleft) ){ + global_miniworld.transition = -1; + global_miniworld.t = 1.0f; + + global_miniworld.cam = skaterift.cam; + m4x3_transform_camera( global_miniworld.mmdl, &global_miniworld.cam ); + world_switch_instance(0); + } + } + + ent_miniworld *miniworld = global_miniworld.active; + if( !miniworld ) return; - if( button_down( k_srbind_use ) ){ - + world_instance *world = world_current_instance(); + + if( global_miniworld.transition ){ + } + else { + int rendering = 1; + if( world_static.instances[k_world_purpose_client].status + == k_world_status_loaded ){ + if( button_down( k_srbind_mright ) ){ + global_miniworld.transition = 1; + global_miniworld.t = 0.0f; + global_miniworld.cam = skaterift.cam; + + mdl_transform_m4x3( &miniworld->transform, global_miniworld.mmdl ); + world_switch_instance(1); + } + } } } diff --git a/ent_miniworld.h b/ent_miniworld.h index 73b660e..2be6141 100644 --- a/ent_miniworld.h +++ b/ent_miniworld.h @@ -4,10 +4,16 @@ #include "entity.h" struct { - u32 active_id; + ent_miniworld *active; + int transition; + f32 t; + + m4x3f mmdl; + camera cam; } static global_miniworld; static void ent_miniworld_call( world_instance *world, ent_call *call ); +static void ent_miniworld_render( world_instance *host_world, camera *cam ); #endif /* ENT_MINIWORLD_H */ diff --git a/entity.h b/entity.h index bdb69f8..7cfce58 100644 --- a/entity.h +++ b/entity.h @@ -505,7 +505,7 @@ struct ent_miniworld { mdl_transform transform; u32 pstr_world; - i32 purpose; + i32 purpose_DELTED; u32 proxy; }; diff --git a/player.c b/player.c index 23cb5fc..3084828 100644 --- a/player.c +++ b/player.c @@ -15,7 +15,7 @@ static int localplayer_cmd_respawn( int argc, const char *argv[] ){ ent_spawn *rp = NULL, *r; - world_instance *world = localplayer.viewable_world; + world_instance *world = world_current_instance(); if( argc == 1 ){ rp = world_find_spawn_by_name( world, argv[0] ); @@ -236,7 +236,6 @@ static void player__reset(void){ localplayer.immobile = 0; localplayer.gate_waiting = NULL; - localplayer.viewable_world = world_current_instance(); world_static.challenge_target = NULL; world_static.challenge_timer = 0.0f; @@ -253,6 +252,8 @@ static void player__reset(void){ world_routes_clear( instance ); } } + + v3_copy( localplayer.rb.co, localplayer.cam_control.tpv_lpf ); } static void player__spawn( ent_spawn *rp ){ diff --git a/player.h b/player.h index cd6bca5..63cd302 100644 --- a/player.h +++ b/player.h @@ -76,8 +76,8 @@ struct { #if 0 v4f qbasis; m3x3f basis, invbasis, basis_gate; -#endif world_instance *viewable_world; +#endif /* * Camera management diff --git a/player_common.c b/player_common.c index 8ea57a4..d1e8fc6 100644 --- a/player_common.c +++ b/player_common.c @@ -27,7 +27,6 @@ static void player_camera_portal_correction(void){ vg_success( "Plane cleared\n" ); player_apply_transport_to_cam( localplayer.gate_waiting->transport ); localplayer.gate_waiting = NULL; - localplayer.viewable_world = world_current_instance(); } else{ /* de-transform camera and player back */ @@ -220,7 +219,7 @@ static void player__cam_iterate(void){ ent_camera *cam = NULL; f32 min_dist = k_cinema; - world_instance *world = localplayer.viewable_world; + world_instance *world = world_current_instance(); for( u32 i=0; ient_camera); i++ ){ ent_camera *c = mdl_arritm(&world->ent_camera,i); diff --git a/render.h b/render.h index ea88ecc..8310ca5 100644 --- a/render.h +++ b/render.h @@ -10,6 +10,7 @@ #include "shaders/blit.h" #include "shaders/blitblur.h" #include "shaders/blitcolour.h" +#include "shaders/blit_transition.h" #define WORKSHOP_PREVIEW_WIDTH 504 #define WORKSHOP_PREVIEW_HEIGHT 336 @@ -597,6 +598,7 @@ static void render_init(void) shader_blit_register(); shader_blitblur_register(); shader_blitcolour_register(); + shader_blit_transition_register(); vg_async_call( async_render_init, NULL, 0 ); } diff --git a/respawn.c b/respawn.c index 084844d..f7be930 100644 --- a/respawn.c +++ b/respawn.c @@ -101,8 +101,6 @@ static void respawn_chooser_pre_update(void){ if( respawn_chooser.spawn ){ world_static.active_instance = respawn_chooser.world_id; - localplayer.viewable_world = - &world_static.instances[ respawn_chooser.world_id ]; player__spawn( respawn_chooser.spawn ); } return; diff --git a/shaders/blit_transition.fs b/shaders/blit_transition.fs new file mode 100644 index 0000000..1f73abd --- /dev/null +++ b/shaders/blit_transition.fs @@ -0,0 +1,15 @@ +out vec4 FragColor; +in vec2 aUv; +uniform float uT; + +void main(){ + float d = uT + distance( aUv, vec2(0.5,0.5) ); + + vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), gl_FragCoord.xy) ); + float dither = fract( vDither.g / 71.0 ) - 0.5; + + if( d+dither < -0.5 ) + discard; + + FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); +} diff --git a/shaders/blit_transition.h b/shaders/blit_transition.h new file mode 100644 index 0000000..f5f3049 --- /dev/null +++ b/shaders/blit_transition.h @@ -0,0 +1,61 @@ +#ifndef SHADER_blit_transition_H +#define SHADER_blit_transition_H +static void shader_blit_transition_link(void); +static void shader_blit_transition_register(void); +static struct vg_shader _shader_blit_transition = { + .name = "blit_transition", + .link = shader_blit_transition_link, + .vs = +{ +.orig_file = "shaders/blit.vs", +.static_src = +"layout (location=0) in vec2 a_co;\n" +"out vec2 aUv;\n" +"\n" +"uniform vec2 uInverseRatio;\n" +"\n" +"void main()\n" +"{\n" +" gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n" +" aUv = a_co * uInverseRatio;\n" +"}\n" +""}, + .fs = +{ +.orig_file = "shaders/blit_transition.fs", +.static_src = +"out vec4 FragColor;\n" +"in vec2 aUv;\n" +"uniform float uT;\n" +"\n" +"void main(){\n" +" float d = uT + distance( aUv, vec2(0.5,0.5) );\n" +"\n" +" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), gl_FragCoord.xy) );\n" +" float dither = fract( vDither.g / 71.0 ) - 0.5;\n" +"\n" +" if( d+dither < -0.5 )\n" +" discard;\n" +"\n" +" FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n" +"}\n" +""}, +}; + +static GLuint _uniform_blit_transition_uInverseRatio; +static GLuint _uniform_blit_transition_uT; +static void shader_blit_transition_uInverseRatio(v2f v){ + glUniform2fv(_uniform_blit_transition_uInverseRatio,1,v); +} +static void shader_blit_transition_uT(float f){ + glUniform1f(_uniform_blit_transition_uT,f); +} +static void shader_blit_transition_register(void){ + vg_shader_register( &_shader_blit_transition ); +} +static void shader_blit_transition_use(void){ glUseProgram(_shader_blit_transition.id); } +static void shader_blit_transition_link(void){ + _uniform_blit_transition_uInverseRatio = glGetUniformLocation( _shader_blit_transition.id, "uInverseRatio" ); + _uniform_blit_transition_uT = glGetUniformLocation( _shader_blit_transition.id, "uT" ); +} +#endif /* SHADER_blit_transition_H */ diff --git a/skaterift.c b/skaterift.c index 24c39a8..254c80d 100644 --- a/skaterift.c +++ b/skaterift.c @@ -333,11 +333,11 @@ static void vg_pre_update(void){ vg.time_rate = vg_smoothstepf( skaterift.time_rate ); /* TODO: how can we compress this? */ + ent_miniworld_preupdate(); player__pre_update(); world_entity_focus_preupdate(); skaterift_replay_pre_update(); remote_sfx_pre_update(); - ent_miniworld_preupdate(); world_update( world_current_instance(), localplayer.rb.co ); audio_ambient_sprites_update( world_current_instance(), localplayer.rb.co ); @@ -477,53 +477,47 @@ static void render_scene(void){ /* Draw world */ glEnable( GL_DEPTH_TEST ); - world_instance *view_world = localplayer.viewable_world; - - if( view_world == NULL ){ - glClearColor( 0.25f, 0.25f, 0.0f, 1.0f ); - glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT ); - return; - } - for( u32 i=0; istatus != k_world_status_loaded ) + return; -static void render_scene_gate_subview(void){ - render_fb_bind( gpipeline.fb_main, 1 ); - world_instance *view_world = localplayer.viewable_world; - if( !view_world ) return; /* ??? */ - if( skaterift.activity == k_skaterift_respawning ) return; + t = vg_smoothstepf( t ); + + glEnable( GL_STENCIL_TEST ); + glDisable( GL_DEPTH_TEST ); + glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); + glStencilFunc( GL_ALWAYS, 1, 0xFF ); + glStencilMask( 0xFF ); - int depth = 1; - if( localplayer.gate_waiting ) depth = 0; - render_world_gates( view_world, &skaterift.cam, depth ); + shader_blit_transition_use(); + shader_blit_transition_uInverseRatio( (v2f){1.0f,1.0f} ); + shader_blit_transition_uT( -(sqrtf(2)+0.5f) * t ); + + render_fsquad(); + render_world( holdout_world, &global_miniworld.cam, 1, 0, 1, 1 ); + } } static void skaterift_composite_maincamera(void){ @@ -537,6 +531,20 @@ static void skaterift_composite_maincamera(void){ skaterift.cam.nearz = 0.1f; skaterift.cam.farz = 2100.0f; + if( global_miniworld.transition ){ + f32 dt = vg.time_frame_delta / 2.0f, + s = vg_signf( global_miniworld.transition ); + global_miniworld.t += s * dt; + + if( (global_miniworld.t > 1.0f) || (global_miniworld.t < 0.0f) ){ + /* TODO: maybe next frame! */ + global_miniworld.t = vg_clampf( global_miniworld.t, 0.0f, 1.0f ); + global_miniworld.transition = 0; + } + else { + } + } + if( skaterift.activity == k_skaterift_respawning ){ camera_copy( &respawn_chooser.cam, &skaterift.cam ); skaterift.cam.nearz = 4.0f; @@ -544,20 +552,6 @@ static void skaterift_composite_maincamera(void){ } camera_update_transform( &skaterift.cam ); - -#if 0 - if( skaterift.activity != k_skaterift_respawning ){ - if( localplayer.gate_waiting ){ - m3x3_mul( localplayer.basis_gate, skaterift.cam.transform, - skaterift.cam.transform ); - } - else{ - m3x3_mul( localplayer.basis, skaterift.cam.transform, - skaterift.cam.transform ); - } - } -#endif - camera_update_view( &skaterift.cam ); camera_update_projection( &skaterift.cam ); camera_finalize( &skaterift.cam ); @@ -577,11 +571,7 @@ static void render_main_game(void){ skaterift_composite_maincamera(); /* --------------------------------------------------------------------- */ - - world_instance *view_world = localplayer.viewable_world; - if( (view_world != NULL) && (skaterift.activity != k_skaterift_respawning) ){ - render_world_cubemaps( view_world ); - } + render_world_cubemaps( world_current_instance() ); /* variable res target */ render_fb_bind( gpipeline.fb_main, 1 ); @@ -600,7 +590,10 @@ static void render_main_game(void){ portals */ /* continue with variable rate */ - render_scene_gate_subview(); + if( !global_miniworld.transition ){ + render_fb_bind( gpipeline.fb_main, 1 ); + render_world_gates( world_current_instance(), &skaterift.cam ); + } /* composite */ present_view_with_post_processing(); diff --git a/workshop.c b/workshop.c index d8f15ed..c074e15 100644 --- a/workshop.c +++ b/workshop.c @@ -857,7 +857,7 @@ static void workshop_render_world_preview(void){ glEnable( GL_DEPTH_TEST ); glDisable( GL_BLEND ); - render_world( localplayer.viewable_world, &skaterift.cam, 1 ); + render_world( world_current_instance(), &skaterift.cam, 0, 0, 1, 1 ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glViewport( 0,0, vg.window_x, vg.window_y ); @@ -910,9 +910,8 @@ static void workshop_render_player_preview(void){ camera_update_projection( &cam ); camera_finalize( &cam ); - world_instance *world = localplayer.viewable_world; - render_playermodel( &cam, world, 0, &workshop_form.player_model, sk, - localplayer.final_mtx ); + render_playermodel( &cam, world_current_instance(), 0, + &workshop_form.player_model, sk, localplayer.final_mtx ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glViewport( 0,0, vg.window_x, vg.window_y ); @@ -1001,7 +1000,7 @@ static void workshop_render_board_preview(void){ glBufferSubData( GL_UNIFORM_BUFFER, 0, sizeof(struct ub_world_lighting), &world->ub_lighting ); - render_world( world, &cam, 1 ); + render_world( world, &cam, 0, 0, 1, 1 ); struct player_board_pose pose = {0}; render_board( &cam, world, board, mmdl, &pose, k_board_shader_entity ); render_board( &cam, world, board, mmdl1, &pose, k_board_shader_entity ); diff --git a/world.c b/world.c index ad03723..4f8cda2 100644 --- a/world.c +++ b/world.c @@ -44,29 +44,9 @@ static void world_switch_instance( u32 index ){ world_instance *current = &world_static.instances[ world_static.active_instance ]; - if( index != world_static.active_instance ){ + if( index != world_static.active_instance ) v3_copy( localplayer.rb.co, current->player_co ); - v3_copy( localplayer.angles, current->player_angles ); - v3_copy( localplayer.cam.pos, current->cam_co ); - current->player_angles[3] = player_get_heading_yaw(); - } - v3_copy( new->player_co, localplayer.rb.co ); - v3_copy( new->player_angles, localplayer.angles ); - v3_copy( new->cam_co, localplayer.cam.pos ); - q_axis_angle( localplayer.rb.q, (v3f){0,1,0}, new->player_angles[3] ); - - /* run exit events on triggers */ - for( u32 i=0; ient_volume, idx ); - - ent_call basecall; - basecall.function = k_ent_function_trigger_leave; - basecall.id = mdl_entity_id( k_ent_volume, idx ); - basecall.data = NULL; - entity_call( current, &basecall ); - } world_static.active_instance = index; diff --git a/world.h b/world.h index 0efe185..0a67abf 100644 --- a/world.h +++ b/world.h @@ -63,8 +63,7 @@ struct world_instance { * ------------------------------------------------------- */ - v4f player_co, player_angles; - v3f cam_co; + v4f player_co; void *heap; enum world_status{ diff --git a/world_entity.c b/world_entity.c index a12e071..d34ed6e 100644 --- a/world_entity.c +++ b/world_entity.c @@ -605,6 +605,7 @@ static void world_entity_start( world_instance *world, vg_msg *sav ){ } } +#if 0 /* * used for relinking multi-world data. ran anytime the world setup changes */ @@ -634,6 +635,7 @@ static void world_entity_relink( world_instance *world ){ } } } +#endif static void world_entity_serialize( world_instance *world, vg_msg *sav ){ for( u32 i=0; ient_challenge); i++ ){ diff --git a/world_entity.h b/world_entity.h index fc66d74..1e5e70c 100644 --- a/world_entity.h +++ b/world_entity.h @@ -13,7 +13,6 @@ static ent_spawn *world_find_spawn_by_name( world_instance *world, static ent_spawn *world_find_closest_spawn( world_instance *world, v3f position ); static void world_entity_start( world_instance *world, vg_msg *sav ); -static void world_entity_relink( world_instance *world ); static void world_entity_serialize( world_instance *world, vg_msg *sav ); static void ent_volume_call( world_instance *world, ent_call *call ); diff --git a/world_gate.c b/world_gate.c index 96317c1..bc21e95 100644 --- a/world_gate.c +++ b/world_gate.c @@ -86,8 +86,7 @@ static void ent_gate_get_mdl_mtx( ent_gate *gate, m4x3f mmdl ){ * Render the view through a gate */ static int render_gate( world_instance *world, world_instance *world_inside, - ent_gate *gate, camera *cam, int layer_depth ) -{ + ent_gate *gate, camera *cam ){ v3f viewdir, gatedir; m3x3_mulv( cam->transform, (v3f){0.0f,0.0f,-1.0f}, viewdir ); q_mulv( gate->q[0], (v3f){0.0f,0.0f,-1.0f}, gatedir ); @@ -145,63 +144,42 @@ static int render_gate( world_instance *world, world_instance *world_inside, camera_finalize( &world_gates.cam ); vg_line_point( world_gates.cam.transform[3], 0.3f, 0xff00ff00 ); - { - shader_model_gate_use(); - shader_model_gate_uPv( cam->mtx.pv ); - shader_model_gate_uCam( cam->pos ); - shader_model_gate_uColour( (v4f){0.0f,1.0f,0.0f,0.0f} ); - shader_model_gate_uTime( vg.time*0.25f ); - shader_model_gate_uInvRes( (v2f){ - 1.0f / (float)vg.window_x, - 1.0f / (float)vg.window_y }); - - glEnable( GL_STENCIL_TEST ); - glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); - glStencilFunc( GL_ALWAYS, 1, 0xFF ); - glStencilMask( 0xFF ); - glDisable( GL_CULL_FACE ); - - m4x3f mmdl; - ent_gate_get_mdl_mtx( gate, mmdl ); - shader_model_gate_uMdl( mmdl ); - - if( gate->flags & k_ent_gate_custom_mesh ){ - mesh_bind( &world->mesh_no_collide ); - for( u32 i=0; isubmesh_count; i++ ){ - mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, - gate->submesh_start+i ); - mdl_draw_submesh( sm ); - } - } - else { - mesh_bind( &world_gates.mesh ); - mdl_draw_submesh( &world_gates.sm_surface ); - } - glClear( GL_DEPTH_BUFFER_BIT ); - glStencilFunc( GL_EQUAL, 1, 0xFF ); - glStencilMask( 0x00 ); - glEnable( GL_CULL_FACE ); + shader_model_gate_use(); + shader_model_gate_uPv( cam->mtx.pv ); + shader_model_gate_uCam( cam->pos ); + shader_model_gate_uColour( (v4f){0.0f,1.0f,0.0f,0.0f} ); + shader_model_gate_uTime( vg.time*0.25f ); + shader_model_gate_uInvRes( (v2f){ + 1.0f / (float)vg.window_x, + 1.0f / (float)vg.window_y }); + + glEnable( GL_STENCIL_TEST ); + glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); + glStencilFunc( GL_ALWAYS, 1, 0xFF ); + glStencilMask( 0xFF ); + glDisable( GL_CULL_FACE ); + + m4x3f mmdl; + ent_gate_get_mdl_mtx( gate, mmdl ); + shader_model_gate_uMdl( mmdl ); + + if( gate->flags & k_ent_gate_custom_mesh ){ + mesh_bind( &world->mesh_no_collide ); + for( u32 i=0; isubmesh_count; i++ ){ + mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, + gate->submesh_start+i ); + mdl_draw_submesh( sm ); + } } - - render_world( world_inside, &world_gates.cam, layer_depth ); - render_remote_players( world_inside, &world_gates.cam ); - - { - glDisable( GL_STENCIL_TEST ); - - render_water_texture( world_inside, &world_gates.cam, layer_depth ); - render_fb_bind( gpipeline.fb_main, 1 ); - - glEnable( GL_STENCIL_TEST ); - - render_water_surface( world_inside, &world_gates.cam ); - - glStencilMask( 0xFF ); - glStencilFunc( GL_ALWAYS, 1, 0xFF ); - glDisable( GL_STENCIL_TEST ); + else { + mesh_bind( &world_gates.mesh ); + mdl_draw_submesh( &world_gates.sm_surface ); } + render_world( world_inside, &world_gates.cam, + 1, !localplayer.gate_waiting, 1, 1 ); + return 1; } diff --git a/world_gate.h b/world_gate.h index 201187c..a8decac 100644 --- a/world_gate.h +++ b/world_gate.h @@ -21,7 +21,7 @@ static world_gates; static void world_gates_init(void); static void gate_transform_update( ent_gate *gate ); static int render_gate( world_instance *world, world_instance *world_inside, - ent_gate *gate, camera *cam, int layer_depth ); + ent_gate *gate, camera *cam ); static int gate_intersect( ent_gate *gate, v3f pos, v3f last ); static u32 world_intersect_gates( world_instance *world, v3f pos, v3f last ); diff --git a/world_load.c b/world_load.c index 6378e9b..50a882c 100644 --- a/world_load.c +++ b/world_load.c @@ -107,7 +107,6 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){ /* init player position. * - this is overriden by the save state when(if) it loads */ - v3_zero( world->player_angles ); ent_spawn *rp = world_find_spawn_by_name( world, "start" ); if( !rp ) rp = world_find_closest_spawn( world, (v3f){0.0f,0.0f,0.0f} ); @@ -147,13 +146,6 @@ static void skaterift_world_load_done( void *payload, u32 size ){ world_entity_start( world, &sav ); world->status = k_world_status_loaded; world_static.load_state = k_world_loader_none; - - for( int i=0; istatus == k_world_status_loaded ) - world_entity_relink( wi ); - } } struct world_load_args { @@ -313,8 +305,6 @@ static void skaterift_change_world_start( addon_reg *reg ){ } } - world_entity_relink( &world_static.instances[k_world_purpose_hub] ); - world_static.instance_addons[ k_world_purpose_client ] = reg; network_send_item( k_netmsg_playeritem_world1 ); relink_all_remote_player_worlds(); diff --git a/world_render.c b/world_render.c index 1d2256b..cdbe37e 100644 --- a/world_render.c +++ b/world_render.c @@ -10,6 +10,8 @@ #include "font.h" #include "gui.h" #include "respawn.h" +#include "ent_miniworld.h" +#include "player_remote.h" static int ccmd_set_time( int argc, const char *argv[] ){ world_instance *world = world_current_instance(); @@ -364,11 +366,11 @@ static void render_world_standard( world_instance *world, camera *cam ){ } static void render_world_cubemapped( world_instance *world, camera *cam, - int layer_depth ){ + int enabled ){ if( !mdl_arrcount( &world->ent_cubemap ) ) return; - if( layer_depth == -1 ){ + if( !enabled ){ world_shader_standard_bind( world, cam ); struct world_pass pass = { @@ -448,7 +450,7 @@ static void render_world_alphatest( world_instance *world, camera *cam ){ static void world_render_challenges( world_instance *world, struct world_pass *pass, - v3f pos, int layer_depth ){ + v3f pos ){ if( !world ) return; if( skaterift.activity == k_skaterift_replay ) return; if( world != world_current_instance() ) return; @@ -608,8 +610,7 @@ void world_render_challenges( world_instance *world, struct world_pass *pass, } } -static void render_world_fxglow( world_instance *world, camera *cam, - int layer_depth ){ +static void render_world_fxglow( world_instance *world, camera *cam ){ shader_scene_fxglow_use(); shader_scene_fxglow_uUvOffset( (v2f){ 0.0f, 0.0f } ); shader_scene_fxglow_uTexMain(1); @@ -635,7 +636,7 @@ static void render_world_fxglow( world_instance *world, camera *cam, }; world_render_both_stages( world, &pass ); - world_render_challenges( world, &pass, cam->pos, layer_depth ); + world_render_challenges( world, &pass, cam->pos ); glEnable(GL_CULL_FACE); } @@ -696,13 +697,18 @@ static void render_sky( world_instance *world, camera *cam ){ m4x4_copy( cam->mtx.v, v ); m4x4_copy( cam->mtx_prev.v, v_prev ); + + for( int i=0; i<3; i++ ){ + v3_normalize(v[i]); + v3_normalize(v_prev[i]); + } 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_reset_clipping( pv, 100.0f, 0.1f ); + m4x4_reset_clipping( pv_prev, 100.0f, 0.1f ); m4x4_mul( pv, v, pv ); m4x4_mul( pv_prev, v_prev, pv_prev ); @@ -750,9 +756,7 @@ static void render_sky( world_instance *world, camera *cam ){ glDepthMask( GL_TRUE ); } -static void render_world_gates( world_instance *world, camera *cam, - int layer_depth ) -{ +static void render_world_gates( world_instance *world, camera *cam ){ float closest = INFINITY; struct ent_gate *gate = NULL; @@ -775,7 +779,7 @@ static void render_world_gates( world_instance *world, camera *cam, world->rendering_gate = gate; if( gate ) - render_gate( world, world, gate, cam, layer_depth ); + render_gate( world, world, gate, cam ); } static void world_prerender( world_instance *world ){ @@ -826,20 +830,32 @@ static void world_prerender( world_instance *world ){ } static void render_world( world_instance *world, camera *cam, - int layer_depth ) -{ + int stenciled, int viewing_from_gate, + int with_water, int with_cubemaps ){ + if( stenciled ){ + glClear( GL_DEPTH_BUFFER_BIT ); + glStencilFunc( GL_EQUAL, 1, 0xFF ); + glStencilMask( 0x00 ); + glEnable( GL_CULL_FACE ); + glEnable( GL_STENCIL_TEST ); + } + else { + glStencilMask( 0xFF ); + glStencilFunc( GL_ALWAYS, 1, 0xFF ); + glDisable( GL_STENCIL_TEST ); + } + render_sky( world, cam ); - render_world_routes( world, cam, layer_depth ); + render_world_routes( world, cam, viewing_from_gate ); render_world_standard( world, cam ); - render_world_cubemapped( world, cam, layer_depth ); + render_world_cubemapped( world, cam, with_cubemaps ); render_world_vb( world, cam ); render_world_alphatest( world, cam ); render_terrain( world, cam ); - if( layer_depth == -1 ) return; - if( layer_depth == 0 ){ + if( !viewing_from_gate ){ world_entity_focus_render(); /* Render SFD's */ @@ -862,30 +878,57 @@ static void render_world( world_instance *world, camera *cam, } } - f32 greyout = 0.0f; - if( mdl_entity_id_type(world_static.focused_entity) == k_ent_challenge ) - greyout = world_static.focus_strength; - - if( greyout > 0.0f ){ - glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); - glEnable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBlendEquation(GL_FUNC_ADD); - - shader_blitcolour_use(); - shader_blitcolour_uColour( (v4f){ 0.5f, 0.5f, 0.5f, greyout*0.56f } ); - render_fsquad(); - - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); - glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1 } ); + if( !viewing_from_gate ){ + f32 greyout = 0.0f; + if( mdl_entity_id_type(world_static.focused_entity) == k_ent_challenge ) + greyout = world_static.focus_strength; + + if( greyout > 0.0f ){ + glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + + shader_blitcolour_use(); + shader_blitcolour_uColour( (v4f){ 0.5f, 0.5f, 0.5f, greyout*0.56f } ); + render_fsquad(); + + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1 } ); + } + + render_world_fxglow( world, cam ); } + + if( with_water ){ + render_water_texture( world, cam ); + render_fb_bind( gpipeline.fb_main, 1 ); + } + + if( stenciled ){ + glStencilFunc( GL_EQUAL, 1, 0xFF ); + glStencilMask( 0x00 ); + glEnable( GL_CULL_FACE ); + glEnable( GL_STENCIL_TEST ); + } + + if( with_water ){ + render_water_surface( world, cam ); + } + + render_remote_players( world, cam ); + ent_miniworld_render( world, cam ); - render_world_fxglow( world, cam, layer_depth ); + if( stenciled ){ + glStencilMask( 0xFF ); + glStencilFunc( GL_ALWAYS, 1, 0xFF ); + glDisable( GL_STENCIL_TEST ); + } } @@ -917,9 +960,10 @@ static void render_world_override_pass( world_instance *world, static void render_world_override( world_instance *world, world_instance *lighting_source, - m4x3f mmdl ){ + m4x3f mmdl, + camera *cam ){ struct world_pass pass = { - .cam = &skaterift.cam, + .cam = cam, .fn_bind_textures = bindpoint_override, .fn_set_mdl = shader_scene_override_uMdl, .fn_set_uPvmPrev = shader_scene_override_uPvmPrev, @@ -942,7 +986,7 @@ static void render_world_override( world_instance *world, m4x4f mpvm_prev; m4x3_expand( mmdl, mpvm_prev ); - m4x4_mul( skaterift.cam.mtx_prev.pv, mpvm_prev, mpvm_prev ); + m4x4_mul( cam->mtx_prev.pv, mpvm_prev, mpvm_prev ); m3x3f mnormal; m3x3_inv( mmdl, mnormal ); @@ -972,7 +1016,6 @@ static void render_world_override( world_instance *world, shader_scene_override_uSpawnPos( uSpawnPos ); - glDisable( GL_CULL_FACE ); mesh_bind( &world->mesh_geo ); pass.geo_type = k_world_geo_type_solid; @@ -1026,7 +1069,7 @@ static void render_cubemap_side( world_instance *world, ent_cubemap *cm, camera_finalize( &cam ); camera_finalize( &cam ); - render_world( world, &cam, -1 ); + render_world( world, &cam, 0, 1, 1, 0 ); } static void render_world_cubemaps( world_instance *world ){ diff --git a/world_render.h b/world_render.h index d7ea519..3837068 100644 --- a/world_render.h +++ b/world_render.h @@ -75,13 +75,15 @@ static void world_bind_light_index( world_instance *world, int slot ); static void render_world_position( world_instance *world, camera *cam ); static void render_world_depth( world_instance *world, camera *cam ); -static void render_world( world_instance *world, camera *cam, - int layer_depth ); +static void render_world( world_instance *world, camera *cam, + int stenciled, int viewing_from_gate, + int with_water, int with_cubemaps ); static void render_world_cubemaps( world_instance *world ); static void bind_terrain_noise(void); static void render_world_override( world_instance *world, world_instance *lighting_source, - m4x3f mmdl ); + m4x3f mmdl, + camera *cam ); #define WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( WORLD, SHADER ) \ world_link_lighting_ub( WORLD, _shader_##SHADER.id ); \ diff --git a/world_routes.c b/world_routes.c index 9dc678e..e4b444a 100644 --- a/world_routes.c +++ b/world_routes.c @@ -865,7 +865,7 @@ static void render_gate_markers( int run_id, ent_gate *gate ){ } static void render_world_routes( world_instance *world, camera *cam, - int layer_depth ){ + int viewing_from_gate ){ m4x3f identity_matrix; m4x3_identity( identity_matrix ); @@ -900,7 +900,7 @@ static void render_world_routes( world_instance *world, camera *cam, /* timers * ---------------------------------------------------- */ - if( layer_depth == 0 ){ + if( !viewing_from_gate ){ font3d_bind( &gui.font, k_font_shader_default, 0, world, cam ); for( u32 i=0; iactive_checkpoint+1+layer_depth; + u32 next = route->active_checkpoint+1+viewing_from_gate; next = next % route->checkpoints_count; next += route->checkpoints_start; diff --git a/world_water.c b/world_water.c index 980ae02..085e252 100644 --- a/world_water.c +++ b/world_water.c @@ -43,8 +43,7 @@ static void world_bind_light_index( world_instance *world, /* * Does not write motion vectors */ -static void render_water_texture( world_instance *world, camera *cam, - int layer_depth ){ +static void render_water_texture( world_instance *world, camera *cam ){ if( !world->water.enabled || (vg.quality_profile == k_quality_profile_low) ) return; @@ -88,7 +87,7 @@ static void render_water_texture( world_instance *world, camera *cam, glEnable( GL_DEPTH_TEST ); glDisable( GL_BLEND ); glCullFace( GL_FRONT ); - render_world( world, &water_cam, layer_depth ); + render_world( world, &water_cam, 0, 1, 0, 1 ); glCullFace( GL_BACK ); /* diff --git a/world_water.h b/world_water.h index 6681460..b45ee3a 100644 --- a/world_water.h +++ b/world_water.h @@ -14,8 +14,7 @@ static world_water; static void world_water_init(void); static void water_set_surface( world_instance *world, float height ); -static void render_water_texture( world_instance *world, camera *cam, - int layer_depth ); +static void render_water_texture( world_instance *world, camera *cam ); static void render_water_surface( world_instance *world, camera *cam ); #endif /* WATER_H */