diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index 5d5675ac..448247ba 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -1226,7 +1226,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite, else { Con_Reportf( S_ERROR "Could not load HUD sprite %s\n", szSpriteName ); - ref.dllFuncs.Mod_UnloadModel( m_pSprite ); + Mod_FreeModel( m_pSprite ); return false; } } @@ -1242,7 +1242,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite, if( !loaded ) { - ref.dllFuncs.Mod_UnloadModel( m_pSprite ); + Mod_FreeModel( m_pSprite ); return false; } diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 1c215795..f4ecabaf 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -1561,7 +1561,7 @@ void CL_RegisterResources( sizebuf_t *msg ) for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ ) { if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name )) - ref.dllFuncs.Mod_UnloadModel( mod ); + Mod_FreeModel( mod ); } Mod_FreeUnused (); @@ -3145,7 +3145,7 @@ void CL_LegacyPrecache_f( void ) for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ ) { if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name )) - ref.dllFuncs.Mod_UnloadModel( mod ); + Mod_FreeModel( mod ); } // Mod_FreeUnused (); diff --git a/engine/client/ref_common.c b/engine/client/ref_common.c index fa5da53e..2f991b97 100644 --- a/engine/client/ref_common.c +++ b/engine/client/ref_common.c @@ -403,6 +403,7 @@ static void R_UnloadProgs( void ) ref.hInstance = NULL; memset( &refState, 0, sizeof( refState )); + memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs )); Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG ); Cmd_Unlink( CMD_REFDLL ); @@ -507,10 +508,13 @@ void R_Shutdown( void ) for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ ) { if( !mod->name[0] ) continue; - Mod_UnloadSpriteModel( mod ); + Mod_FreeModel( mod ); } memset( clgame.sprites, 0, sizeof( clgame.sprites )); + // correctly free all models before render unload + // change this if need add online render changing + Mod_FreeAll(); R_UnloadProgs(); ref.initialized = false; } diff --git a/engine/common/mod_bmodel.c b/engine/common/mod_bmodel.c index ffd027c6..f9edf7b5 100644 --- a/engine/common/mod_bmodel.c +++ b/engine/common/mod_bmodel.c @@ -2797,42 +2797,6 @@ void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded ) if( loaded ) *loaded = true; // all done } -/* -================= -Mod_UnloadBrushModel - -Release all uploaded textures -================= -*/ -void Mod_UnloadBrushModel( model_t *mod ) -{ - texture_t *tx; - int i; - - Assert( mod != NULL ); - - if( mod->type != mod_brush ) - return; // not a bmodel - - if( mod->name[0] != '*' ) - { -#ifndef XASH_DEDICATED - for( i = 0; i < mod->numtextures; i++ ) - { - tx = mod->textures[i]; - if( !tx || tx->gl_texturenum == ref.dllFuncs.R_GetBuiltinTexture( REF_DEFAULT_TEXTURE ) ) - continue; // free slot - - ref.dllFuncs.GL_FreeTexture( tx->gl_texturenum ); // main texture - ref.dllFuncs.GL_FreeTexture( tx->fb_texturenum ); // luma texture - } -#endif - Mem_FreePool( &mod->mempool ); - } - - memset( mod, 0, sizeof( *mod )); -} - /* ================== Mod_CheckLump diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index 521e9686..2ef00134 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -118,6 +118,7 @@ extern convar_t *r_showhull; // model.c // void Mod_Init( void ); +void Mod_FreeModel( model_t *mod ); void Mod_FreeAll( void ); void Mod_Shutdown( void ); void Mod_ClearUserData( void ); @@ -189,7 +190,6 @@ void Mod_ClearStudioCache( void ); // mod_sprite.c // void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags ); -void Mod_UnloadSpriteModel( model_t *mod ); #endif #endif//MOD_LOCAL_H diff --git a/engine/common/mod_sprite.c b/engine/common/mod_sprite.c index 07364684..396ecfd8 100644 --- a/engine/common/mod_sprite.c +++ b/engine/common/mod_sprite.c @@ -113,29 +113,3 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui ref.dllFuncs.Mod_LoadModel( mod_sprite, mod, buffer, loaded, texFlags ); #endif } - -/* -==================== -Mod_UnloadSpriteModel - -release sprite model and frames -==================== -*/ -void Mod_UnloadSpriteModel( model_t *mod ) -{ - Assert( mod != NULL ); - - if( mod->type == mod_sprite ) - { -#ifndef XASH_DEDICATED - if( host.type != HOST_DEDICATED ) - { - ref.dllFuncs.Mod_UnloadModel( mod ); - } -#endif - - Mem_FreePool( &mod->mempool ); - memset( mod, 0, sizeof( *mod )); - } - -} diff --git a/engine/common/mod_studio.c b/engine/common/mod_studio.c index 50302b85..8f6fd9fd 100644 --- a/engine/common/mod_studio.c +++ b/engine/common/mod_studio.c @@ -1139,25 +1139,6 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ) if( loaded ) *loaded = true; } -/* -================= -Mod_UnloadStudioModel -================= -*/ -void Mod_UnloadStudioModel( model_t *mod ) -{ - Assert( mod != NULL ); - - if( mod->type != mod_studio ) - return; // not a studio - - if( Host_IsDedicated() ) - ref.dllFuncs.Mod_StudioUnloadTextures( mod->cache.data ); - - Mem_FreePool( &mod->mempool ); - memset( mod, 0, sizeof( *mod )); -} - static sv_blending_interface_t gBlendAPI = { SV_BLENDING_INTERFACE_VERSION, diff --git a/engine/common/model.c b/engine/common/model.c index 55324b83..761e04bb 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -102,37 +102,21 @@ static void Mod_FreeUserData( model_t *mod ) Mod_FreeModel ================ */ -static void Mod_FreeModel( model_t *mod ) +void Mod_FreeModel( model_t *mod ) { // already freed? if( !mod || !mod->name[0] ) return; - if( mod->name[0] != '*' ) - Mod_FreeUserData( mod ); - - // notify renderer about unloading - if( ref.dllFuncs.Mod_UnloadModel ) - ref.dllFuncs.Mod_UnloadModel( mod ); - - switch( mod->type ) + if( mod->type != mod_brush || mod->name[0] != '*' ) { - case mod_studio: - Mod_UnloadStudioModel( mod ); - break; - case mod_alias: - // REFTODO: - // Mod_UnloadAliasModel( mod ); - break; - case mod_sprite: - Mod_UnloadSpriteModel( mod ); - break; - case mod_brush: - Mod_UnloadBrushModel( mod ); - break; + Mod_FreeUserData( mod ); +#ifndef XASH_DEDICATED + ref.dllFuncs.Mod_UnloadTextures( mod ); +#endif + Mem_FreePool( &mod->mempool ); } - memset( mod, 0, sizeof( *mod )); } diff --git a/engine/ref_api.h b/engine/ref_api.h index 0ed30257..e0f72807 100644 --- a/engine/ref_api.h +++ b/engine/ref_api.h @@ -520,9 +520,8 @@ typedef struct ref_interface_s // flags ignored for everything except spritemodels void (*Mod_LoadModel)( modtype_t desiredType, model_t *mod, const byte *buf, qboolean *loaded, int flags ); void (*Mod_LoadMapSprite)( struct model_s *mod, const void *buffer, size_t size, qboolean *loaded ); - void (*Mod_UnloadModel)( model_t *mod ); + void (*Mod_UnloadTextures)( model_t *mod ); void (*Mod_StudioLoadTextures)( model_t *mod, void *data ); - void (*Mod_StudioUnloadTextures)( void *data ); // efx implementation void (*CL_DrawParticles)( double frametime, particle_t *particles, float partsize ); diff --git a/ref_gl/gl_alias.c b/ref_gl/gl_alias.c index 64c8d0d8..e06c207f 100644 --- a/ref_gl/gl_alias.c +++ b/ref_gl/gl_alias.c @@ -729,22 +729,12 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded ) if( loaded ) *loaded = true; // done } -/* -================= -Mod_UnloadAliasModel -================= -*/ -void Mod_UnloadAliasModel( model_t *mod ) +void Mod_AliasUnloadTextures( void *data ) { aliashdr_t *palias; int i, j; - Assert( mod != NULL ); - - if( mod->type != mod_alias ) - return; // not an alias - - palias = mod->cache.data; + palias = data; if( !palias ) return; // already freed for( i = 0; i < MAX_SKINS; i++ ) @@ -758,9 +748,6 @@ void Mod_UnloadAliasModel( model_t *mod ) GL_FreeTexture( palias->fb_texturenum[i][j] ); } } - - Mem_FreePool( &mod->mempool ); - memset( mod, 0, sizeof( *mod )); } /* diff --git a/ref_gl/gl_context.c b/ref_gl/gl_context.c index 2ee1f1e5..f722d2c5 100644 --- a/ref_gl/gl_context.c +++ b/ref_gl/gl_context.c @@ -164,26 +164,6 @@ static void Mod_LoadModel( modtype_t desiredType, model_t *mod, const byte *buf, } } -static void Mod_UnloadModel( model_t *mod ) -{ - switch( mod->type ) - { - case mod_studio: - // Mod_UnloadStudioModel( mod ); - break; - case mod_alias: - Mod_UnloadAliasModel( mod ); - break; - case mod_brush: - // Mod_UnloadBrushModel( mod ); - break; - case mod_sprite: - Mod_UnloadSpriteModel( mod ); - break; - default: gEngfuncs.Host_Error( "Mod_UnloadModel: unsupported type %d\n", mod->type ); - } -} - static int GL_RenderGetParm( int parm, int arg ) { gl_texture_t *glt; @@ -320,6 +300,45 @@ const byte *GL_TextureData( unsigned int texnum ) return NULL; } +void Mod_BrushUnloadTextures( model_t *mod ) +{ + int i; + + for( i = 0; i < mod->numtextures; i++ ) + { + texture_t *tx = mod->textures[i]; + if( !tx || tx->gl_texturenum == tr.defaultTexture ) + continue; // free slot + + GL_FreeTexture( tx->gl_texturenum ); // main texture + GL_FreeTexture( tx->fb_texturenum ); // luma texture + } +} + +void Mod_UnloadTextures( model_t *mod ) +{ + int i, j; + + Assert( mod != NULL ); + + switch( mod->type ) + { + case mod_studio: + Mod_StudioUnloadTextures( mod->cache.data ); + break; + case mod_alias: + Mod_AliasUnloadTextures( mod->cache.data ); + break; + case mod_brush: + Mod_BrushUnloadTextures( mod ); + break; + case mod_sprite: + Mod_SpriteUnloadTextures( mod->cache.data ); + break; + default: gEngfuncs.Host_Error( "Mod_UnloadModel: unsupported type %d\n", mod->type ); + } +} + ref_interface_t gReffuncs = { R_Init, @@ -390,9 +409,8 @@ ref_interface_t gReffuncs = Mod_LoadModel, Mod_LoadMapSprite, - Mod_UnloadModel, + Mod_UnloadTextures, Mod_StudioLoadTextures, - Mod_StudioUnloadTextures, CL_DrawParticles, CL_DrawTracers, diff --git a/ref_gl/gl_local.h b/ref_gl/gl_local.h index 2a6cc27d..3f7ff709 100644 --- a/ref_gl/gl_local.h +++ b/ref_gl/gl_local.h @@ -541,10 +541,9 @@ int R_WorldToScreen( const vec3_t point, vec3_t screen ); void R_ScreenToWorld( const vec3_t screen, vec3_t point ); qboolean R_AddEntity( struct cl_entity_s *pRefEntity, int entityType ); void Mod_LoadMapSprite( struct model_s *mod, const void *buffer, size_t size, qboolean *loaded ); -void Mod_UnloadSpriteModel( struct model_s *mod ); -void Mod_UnloadStudioModel( struct model_s *mod ); -void Mod_UnloadBrushModel( struct model_s *mod ); +void Mod_SpriteUnloadTextures( void *data ); void Mod_UnloadAliasModel( struct model_s *mod ); +void Mod_AliasUnloadTextures( void *data ); void GL_SetRenderMode( int mode ); void R_RunViewmodelEvents( void ); void R_DrawViewModel( void ); diff --git a/ref_gl/gl_sprite.c b/ref_gl/gl_sprite.c index 014133cd..89aac7bb 100644 --- a/ref_gl/gl_sprite.c +++ b/ref_gl/gl_sprite.c @@ -356,14 +356,14 @@ Mod_UnloadSpriteModel release sprite model and frames ==================== */ -void Mod_UnloadSpriteModel( model_t *mod ) +void Mod_SpriteUnloadTextures( void *data ) { msprite_t *psprite; mspritegroup_t *pspritegroup; mspriteframe_t *pspriteframe; int i, j; - psprite = mod->cache.data; + psprite = data; if( psprite ) { diff --git a/ref_gl/gl_studio.c b/ref_gl/gl_studio.c index 2cf01a48..94d99b0e 100644 --- a/ref_gl/gl_studio.c +++ b/ref_gl/gl_studio.c @@ -3584,7 +3584,7 @@ void Mod_StudioLoadTextures( model_t *mod, void *data ) /* ================= -Mod_StudioLoadTextures +Mod_StudioUnloadTextures ================= */ void Mod_StudioUnloadTextures( void *data )