X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_render.c;h=ce3fa5a6a527463c99aada84fc8ee1735fd0a6be;hb=67928190c66b05bd48b6b515278e930974d25cd2;hp=ab8942207366aa30d30a435e009b997d0c5c62d5;hpb=1b522daa02f28128498b04def4d60b63e590d1f3;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_render.c b/player_render.c index ab89422..ce3fa5a 100644 --- a/player_render.c +++ b/player_render.c @@ -5,9 +5,12 @@ #include "player_render.h" #include "camera.h" #include "player_model.h" +#include "ent_skateshop.h" +#include "audio.h" #include "shaders/model_character_view.h" #include "shaders/model_board_view.h" +#include "shaders/model_entity.h" VG_STATIC void player_avatar_load( struct player_avatar *av, const char *path ) { @@ -36,89 +39,54 @@ VG_STATIC void player_avatar_load( struct player_avatar *av, const char *path ) /* TODO: Standard model load */ -VG_STATIC void player_model_load( struct player_model *mdl, const char *path ) +VG_STATIC void dynamic_model_load( mdl_context *ctx, + struct dynamic_model_1texture *mdl, + const char *path ) { - vg_linear_clear( vg_mem.scratch ); - - mdl_context ctx; - mdl_open( &ctx, path, vg_mem.scratch ); - mdl_load_metadata_block( &ctx, vg_mem.scratch ); - mdl_load_mesh_block( &ctx, vg_mem.scratch ); + if( !mdl_arrcount( &ctx->textures ) ) + vg_fatal_error( "No texture in model" ); - if( !mdl_arrcount( &ctx.textures ) ) - vg_fatal_exit_loop( "No texture in player model" ); - - mdl_texture *tex0 = mdl_arritm( &ctx.textures, 0 ); + mdl_texture *tex0 = mdl_arritm( &ctx->textures, 0 ); void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size ); - mdl_fread_pack_file( &ctx, &tex0->file, data ); - - vg_acquire_thread_sync(); - { - mdl_unpack_glmesh( &ctx, &mdl->mesh ); + mdl_fread_pack_file( ctx, &tex0->file, data ); - /* upload first texture */ - mdl->texture = vg_tex2d_new(); + vg_tex2d_load_qoi_async( data, tex0->file.pack_size, + VG_TEX2D_NEAREST|VG_TEX2D_CLAMP, + &mdl->texture ); - vg_tex2d_set_error(); - vg_tex2d_qoi( data, tex0->file.pack_size, - mdl_pstr( &ctx, tex0->file.pstr_path )); - vg_tex2d_nearest(); - vg_tex2d_clamp(); - } - vg_release_thread_sync(); + mdl_async_load_glmesh( ctx, &mdl->mesh ); +} - mdl_close( &ctx ); +VG_STATIC void dynamic_model_unload( struct dynamic_model_1texture *mdl ){ + mesh_free( &mdl->mesh ); + glDeleteTextures( 1, &mdl->texture ); } -VG_STATIC void player_board_load( struct player_board *mdl, const char *path ) -{ +/* TODO: allow error handling */ +VG_STATIC void player_board_load( struct player_board *board, + const char *path ){ + vg_linear_clear( vg_mem.scratch ); mdl_context ctx; mdl_open( &ctx, path, vg_mem.scratch ); mdl_load_metadata_block( &ctx, vg_mem.scratch ); - mdl_load_mesh_block( &ctx, vg_mem.scratch ); + + dynamic_model_load( &ctx, &board->mdl, path ); mdl_array_ptr markers; mdl_load_array( &ctx, &markers, "ent_marker", vg_mem.scratch ); - if( !mdl_arrcount( &ctx.textures ) ) - vg_fatal_exit_loop( "No texture in board model" ); - - mdl_texture *tex0 = mdl_arritm( &ctx.textures, 0 ); - void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size ); - mdl_fread_pack_file( &ctx, &tex0->file, data ); - - vg_acquire_thread_sync(); - { - mdl_unpack_glmesh( &ctx, &mdl->mesh ); - - /* upload first texture */ - mdl->texture = vg_tex2d_new(); - - vg_tex2d_set_error(); - vg_tex2d_qoi( data, tex0->file.pack_size, - mdl_pstr( &ctx, tex0->file.pstr_path )); - vg_tex2d_nearest(); - vg_tex2d_clamp(); - } - vg_release_thread_sync(); - - mdl_close( &ctx ); - + /* TODO: you get put into a new section, the above is standard mdl loads. */ for( int i=0; i<4; i++ ) - mdl->wheels[i].indice_count = 0; + board->wheels[i].indice_count = 0; for( int i=0; i<2; i++ ) - mdl->trucks[i].indice_count = 0; - mdl->board.indice_count = 0; + board->trucks[i].indice_count = 0; + board->board.indice_count = 0; for( u32 i=0; ientity_id, - mdl_entity_id_type( mesh->entity_id ), - mdl_entity_id_id( mesh->entity_id ) ); - if( mdl_entity_id_type( mesh->entity_id ) != k_ent_marker ) continue; @@ -133,18 +101,40 @@ VG_STATIC void player_board_load( struct player_board *mdl, const char *path ) if( !strcmp( alias, "wheel" ) ){ u32 id = fb<<1 | lr; - mdl->wheels[ id ] = *sm0; - v3_copy( marker->transform.co, mdl->wheel_positions[ id ] ); + board->wheels[ id ] = *sm0; + v3_copy( marker->transform.co, board->wheel_positions[ id ] ); } else if( !strcmp( alias, "board" ) ){ - mdl->board = *sm0; - v3_copy( marker->transform.co, mdl->board_position ); + board->board = *sm0; + v3_copy( marker->transform.co, board->board_position ); } else if( !strcmp( alias, "truck" ) ){ - mdl->trucks[ fb ] = *sm0; - v3_copy( marker->transform.co, mdl->truck_positions[ fb ] ); + board->trucks[ fb ] = *sm0; + v3_copy( marker->transform.co, board->truck_positions[ fb ] ); } } + + mdl_close( &ctx ); +} + +VG_STATIC void player_board_unload( struct player_board *board ){ + dynamic_model_unload( &board->mdl ); +} + +VG_STATIC void player_model_load( struct player_model *board, const char *path){ + vg_linear_clear( vg_mem.scratch ); + + mdl_context ctx; + mdl_open( &ctx, path, vg_mem.scratch ); + mdl_load_metadata_block( &ctx, vg_mem.scratch ); + + dynamic_model_load( &ctx, &board->mdl, path ); + + mdl_close( &ctx ); +} + +VG_STATIC void player_model_unload( struct player_model *board ){ + dynamic_model_unload( &board->mdl ); } VG_STATIC void player__pre_render( player_instance *player ) @@ -178,14 +168,30 @@ VG_STATIC void player__pre_render( player_instance *player ) _player_post_animate[ player->subsystem ]( player ); struct player_avatar *av = player->playeravatar; + struct player_board *board = + addon_cache_item_if_loaded( k_addon_type_board, + player->board_view_slot ); - v3f vp0 = {0.0f,0.1f, player->playerboard->truck_positions[0][2]}, - vp1 = {0.0f,0.1f, player->playerboard->truck_positions[1][2]}; + v3f vp0, vp1; + + if( board ){ + v3_copy((v3f){0.0f,0.1f, board->truck_positions[0][2]}, vp0 ); + v3_copy((v3f){0.0f,0.1f, board->truck_positions[1][2]}, vp1 ); + } + else{ + v3_zero( vp0 ); + v3_zero( vp1 ); + } - struct ub_world_lighting *ubo = &get_active_world()->ub_lighting; + struct ub_world_lighting *ubo = &world_current_instance()->ub_lighting; m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp0, ubo->g_board_0 ); m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp1, ubo->g_board_1 ); + if( player->immobile ){ + player__cam_iterate( player ); + return; + } + if( player->rewinding ){ if( player->rewind_time <= 0.0f ){ double taken = vg.time - player->rewind_start; @@ -197,11 +203,11 @@ VG_STATIC void player__pre_render( player_instance *player ) player->rewind_length = 1; player->rewind_total_length = 0.0f; player->rewind_accum = 0.0f; - world_global.sky_target_rate = 1.0; - world_global.time = world_global.last_use; + world_render.sky_target_rate = 1.0; + world_static.time = world_static.last_use; } else{ - world_global.sky_target_rate = -100.0; + world_render.sky_target_rate = -100.0; float budget = vg.time_delta, overall_length = player->rewind_length; @@ -274,6 +280,7 @@ VG_STATIC void player__pre_render( player_instance *player ) vg_alerpf( fr->ang[0], fr1->ang[0], sub ); player->cam_override_angles[1] = vg_lerpf ( fr->ang[1], fr1->ang[1], sub ); + player->cam_override_fov = player->cam.fov; float blend = player->rewind_time * 0.25f; player->cam_override_strength = vg_clampf( blend, 0.0f, 1.0f ); @@ -284,82 +291,91 @@ VG_STATIC void player__pre_render( player_instance *player ) player__cam_iterate( player ); } -PLAYER_API void player__render( camera *cam, player_instance *player ) +VG_STATIC void render_board( camera *cam, world_instance *world, + struct player_board *board, m4x3f root, + struct board_pose *pose, + enum board_shader shader ) { - shader_model_character_view_use(); + if( !board ) return; - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, player->playermodel->texture ); - shader_model_character_view_uTexMain( 0 ); - shader_model_character_view_uCamera( cam->transform[3] ); - shader_model_character_view_uPv( cam->mtx.pv ); - shader_model_character_view_uTexSceneDepth( 1 ); - render_fb_bind_texture( gpipeline.fb_main, 2, 1 ); v3f inverse; - render_fb_inverse_ratio( gpipeline.fb_main, inverse ); - inverse[2] = main_camera.farz-main_camera.nearz; - - shader_model_character_view_uInverseRatioDepth( inverse ); - render_fb_inverse_ratio( NULL, inverse ); - inverse[2] = cam->farz-cam->nearz; - shader_model_character_view_uInverseRatioMain( inverse ); - - world_instance *world = get_active_world(); - world_link_lighting_ub( world, _shader_model_character_view.id ); - world_bind_position_texture( world, _shader_model_character_view.id, - _uniform_model_character_view_g_world_depth, 2 ); - world_bind_light_array( world, _shader_model_character_view.id, - _uniform_model_character_view_uLightsArray, 3 ); - world_bind_light_index( world, _shader_model_character_view.id, - _uniform_model_character_view_uLightsIndex, 4 ); - glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms, - player->playeravatar->sk.bone_count, - 0, - (float *)player->playeravatar->sk.final_mtx ); - - mesh_bind( &player->playermodel->mesh ); - mesh_draw( &player->playermodel->mesh ); + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, board->mdl.texture ); + + if( shader == k_board_shader_player ){ + shader_model_board_view_use(); + shader_model_board_view_uTexMain( 0 ); + shader_model_board_view_uCamera( cam->transform[3] ); + shader_model_board_view_uPv( cam->mtx.pv ); + shader_model_board_view_uTexSceneDepth( 1 ); + render_fb_bind_texture( gpipeline.fb_main, 2, 1 ); + + render_fb_inverse_ratio( gpipeline.fb_main, inverse ); + + inverse[2] = main_camera.farz-main_camera.nearz; + + shader_model_board_view_uInverseRatioDepth( inverse ); + render_fb_inverse_ratio( NULL, inverse ); + inverse[2] = cam->farz-cam->nearz; + shader_model_board_view_uInverseRatioMain( inverse ); + + world_link_lighting_ub( world, _shader_model_board_view.id ); + world_bind_position_texture( world, _shader_model_board_view.id, + _uniform_model_board_view_g_world_depth, 2 ); + world_bind_light_array( world, _shader_model_board_view.id, + _uniform_model_board_view_uLightsArray, 3 ); + world_bind_light_index( world, _shader_model_board_view.id, + _uniform_model_board_view_uLightsIndex, 4 ); + } + else if( shader == k_board_shader_entity ){ + shader_model_entity_use(); + shader_model_entity_uTexMain( 0 ); + shader_model_entity_uCamera( cam->transform[3] ); + shader_model_entity_uPv( cam->mtx.pv ); + + world_link_lighting_ub( world, _shader_model_entity.id ); + world_bind_position_texture( world, _shader_model_entity.id, + _uniform_model_entity_g_world_depth, 2 ); + world_bind_light_array( world, _shader_model_entity.id, + _uniform_model_entity_uLightsArray, 3 ); + world_bind_light_index( world, _shader_model_entity.id, + _uniform_model_entity_uLightsIndex, 4 ); + } - /* draw skateboard */ - shader_model_board_view_use(); - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, player->playerboard->texture ); - shader_model_board_view_uTexMain( 0 ); - shader_model_board_view_uCamera( cam->transform[3] ); - shader_model_board_view_uPv( cam->mtx.pv ); - shader_model_board_view_uTexSceneDepth( 1 ); + mesh_bind( &board->mdl.mesh ); - render_fb_inverse_ratio( gpipeline.fb_main, inverse ); - inverse[2] = main_camera.farz-main_camera.nearz; + m4x4f m4mdl; - shader_model_board_view_uInverseRatioDepth( inverse ); - render_fb_inverse_ratio( NULL, inverse ); - inverse[2] = cam->farz-cam->nearz; - shader_model_board_view_uInverseRatioMain( inverse ); + if( board->board.indice_count ){ + m4x3f mlocal; + m3x3_identity( mlocal ); - world_link_lighting_ub( world, _shader_model_board_view.id ); - world_bind_position_texture( world, _shader_model_board_view.id, - _uniform_model_board_view_g_world_depth, 2 ); - world_bind_light_array( world, _shader_model_board_view.id, - _uniform_model_board_view_uLightsArray, 3 ); - world_bind_light_index( world, _shader_model_board_view.id, - _uniform_model_board_view_uLightsIndex, 4 ); + mdl_keyframe kf; + v3_zero( kf.co ); + q_identity( kf.q ); + v3_zero( kf.s ); - m4x3f root; - m4x3_copy( player->playeravatar->sk.final_mtx[player->playeravatar->id_board] - , root ); + v4f qroll; + q_axis_angle( qroll, (v3f){0.0f,0.0f,1.0f}, pose->lean * 0.6f ); + keyframe_rotate_around( &kf, (v3f){0.0f,0.11f,0.0f}, + (v3f){0.0f,0.0f,0.0f}, qroll ); - struct player_board *board = player->playerboard; - mesh_bind( &board->mesh ); + v3_add( board->board_position, kf.co, mlocal[3] ); + q_m3x3( kf.q, mlocal ); - if( board->board.indice_count ){ - m4x3f mlocal; - m3x3_identity( mlocal ); - v3_copy( board->board_position, mlocal[3] ); m4x3_mul( root, mlocal, mlocal ); - shader_model_board_view_uMdl( mlocal ); + if( shader == k_board_shader_entity ){ + /* TODO: provide a way to supply previous mdl mtx? */ + m4x3_expand( mlocal, m4mdl ); + m4x4_mul( cam->mtx_prev.pv, m4mdl, m4mdl ); + shader_model_entity_uPvmPrev( m4mdl ); + shader_model_entity_uMdl( mlocal ); + } + else + shader_model_board_view_uMdl( mlocal ); + mdl_draw_submesh( &board->board ); } @@ -372,7 +388,15 @@ PLAYER_API void player__render( camera *cam, player_instance *player ) v3_copy( board->truck_positions[i], mlocal[3] ); m4x3_mul( root, mlocal, mlocal ); - shader_model_board_view_uMdl( mlocal ); + if( shader == k_board_shader_entity ){ + m4x3_expand( mlocal, m4mdl ); + m4x4_mul( cam->mtx_prev.pv, m4mdl, m4mdl ); + shader_model_entity_uPvmPrev( m4mdl ); + shader_model_entity_uMdl( mlocal ); + } + else + shader_model_board_view_uMdl( mlocal ); + mdl_draw_submesh( &board->trucks[i] ); } @@ -385,9 +409,81 @@ PLAYER_API void player__render( camera *cam, player_instance *player ) v3_copy( board->wheel_positions[i], mlocal[3] ); m4x3_mul( root, mlocal, mlocal ); - shader_model_board_view_uMdl( mlocal ); + if( shader == k_board_shader_entity ){ + m4x3_expand( mlocal, m4mdl ); + m4x4_mul( cam->mtx_prev.pv, m4mdl, m4mdl ); + shader_model_entity_uPvmPrev( m4mdl ); + shader_model_entity_uMdl( mlocal ); + } + else + shader_model_board_view_uMdl( mlocal ); + mdl_draw_submesh( &board->wheels[i] ); } } +VG_STATIC void render_playermodel( camera *cam, world_instance *world, + struct player_model *model, + struct skeleton *skeleton ){ + if( !model ) return; + + shader_model_character_view_use(); + + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, model->mdl.texture ); + shader_model_character_view_uTexMain( 0 ); + shader_model_character_view_uCamera( cam->transform[3] ); + shader_model_character_view_uPv( cam->mtx.pv ); + shader_model_character_view_uTexSceneDepth( 1 ); + render_fb_bind_texture( gpipeline.fb_main, 2, 1 ); + v3f inverse; + render_fb_inverse_ratio( gpipeline.fb_main, inverse ); + inverse[2] = main_camera.farz-main_camera.nearz; + + shader_model_character_view_uInverseRatioDepth( inverse ); + render_fb_inverse_ratio( NULL, inverse ); + inverse[2] = cam->farz-cam->nearz; + shader_model_character_view_uInverseRatioMain( inverse ); + + world_link_lighting_ub( world, _shader_model_character_view.id ); + world_bind_position_texture( world, _shader_model_character_view.id, + _uniform_model_character_view_g_world_depth, 2 ); + world_bind_light_array( world, _shader_model_character_view.id, + _uniform_model_character_view_uLightsArray, 3 ); + world_bind_light_index( world, _shader_model_character_view.id, + _uniform_model_character_view_uLightsIndex, 4 ); + + glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms, + skeleton->bone_count, + 0, + (float *)skeleton->final_mtx ); + + mesh_bind( &model->mdl.mesh ); + mesh_draw( &model->mdl.mesh ); +} + +PLAYER_API void player__render( camera *cam, player_instance *player ) +{ + world_instance *world = world_current_instance(); + SDL_AtomicLock( &addon_system.sl_cache_using_resources ); + + struct player_model *model = + addon_cache_item_if_loaded( k_addon_type_player, + player->playermodel_view_slot ); + + if( !model ) model = &player->fallback_model; + render_playermodel( cam, world, model, &player->playeravatar->sk ); + + struct player_board *board = + addon_cache_item_if_loaded( k_addon_type_board, + player->board_view_slot ); + + render_board( cam, world, board, player->playeravatar->sk.final_mtx[ + player->playeravatar->id_board], + &player->board_pose, + k_board_shader_player ); + + SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); +} + #endif /* PLAYER_RENDER_C */