engine: mod_bmodel: optimize loading wad textures by directly loading it from the archive through new filesystem functions

This commit is contained in:
Alibek Omarov 2024-11-23 15:02:49 +03:00
parent bf6a9cb0e7
commit 23b410ccb0

View file

@ -405,7 +405,7 @@ static mip_t *Mod_GetMipTexForTexture( dbspmodel_t *bmod, int i )
} }
// Returns index of WAD that texture was found in, or -1 if not found. // Returns index of WAD that texture was found in, or -1 if not found.
static int Mod_FindTextureInWadList( wadlist_t *list, const char *name, char *dst, size_t size ) static int Mod_LoadTextureFromWadList( wadlist_t *list, const char *name, rgbdata_t **pic, char *texpath, size_t texpathlen )
{ {
int i; int i;
@ -415,16 +415,38 @@ static int Mod_FindTextureInWadList( wadlist_t *list, const char *name, char *ds
// check wads in reverse order // check wads in reverse order
for( i = list->count - 1; i >= 0; i-- ) for( i = list->count - 1; i >= 0; i-- )
{ {
char path[MAX_VA_STRING]; searchpath_t *sp = NULL;
Q_snprintf( path, sizeof( path ), "%s/%s.mip", list->wadnames[i], name ); while(( sp = g_fsapi.GetArchiveByName( list->wadnames[i], sp )))
if( FS_FileExists( path, false ))
{ {
if( dst && size > 0 ) fs_offset_t len;
Q_strncpy( dst, path, size ); byte *buf;
char file[MAX_VA_STRING];
int pack_ind;
return i; Q_snprintf( file, sizeof( file ), "%s.mip", name );
pack_ind = g_fsapi.FindFileInArchive( sp, file, NULL, 0 );
if( pack_ind < 0 )
continue;
if( texpath != NULL )
Q_snprintf( texpath, texpathlen, "%s/%s.mip", list->wadnames[i], name );
if( pic == NULL )
return i; // dedicated server don't want to load the textures (why?)
if( !( buf = g_fsapi.LoadFileFromArchive( sp, file, pack_ind, &len, false )))
{
*pic = NULL;
return i; // corrupted file, don't ignore it
}
// tell imagelib to directly load this texture to save time
Q_snprintf( file, sizeof( file ), "#%s/%s.mip", list->wadnames[i], name );
*pic = FS_LoadImage( file, buf, len );
Mem_Free( buf );
return i; // if file is corrupted, it's fine, we want to tell the user about it
} }
} }
@ -2460,13 +2482,17 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
// Try WAD texture (force while r_wadtextures is 1) // Try WAD texture (force while r_wadtextures is 1)
if( !texture->gl_texturenum && (( r_wadtextures.value && world.wadlist.count > 0 ) || mipTex->offsets[0] <= 0 )) if( !texture->gl_texturenum && (( r_wadtextures.value && world.wadlist.count > 0 ) || mipTex->offsets[0] <= 0 ))
{ {
int wadIndex = Mod_FindTextureInWadList( &world.wadlist, mipTex->name, texpath, sizeof( texpath )); rgbdata_t *pic = NULL;
int wadIndex = Mod_LoadTextureFromWadList( &world.wadlist, mipTex->name, Host_IsDedicated() ? NULL : &pic, texpath, sizeof( texpath ));
if( wadIndex >= 0 ) if( wadIndex >= 0 )
{ {
#if !XASH_DEDICATED #if !XASH_DEDICATED
if( !Host_IsDedicated( )) if( !Host_IsDedicated( ) && pic != NULL )
texture->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, txFlags ); {
texture->gl_texturenum = ref.dllFuncs.GL_LoadTextureFromBuffer( texpath, pic, txFlags, false );
FS_FreeImage( pic );
}
#endif // !XASH_DEDICATED #endif // !XASH_DEDICATED
world.wadlist.wadusage[wadIndex]++; world.wadlist.wadusage[wadIndex]++;
} }
@ -2517,28 +2543,21 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
} }
else else
{ {
char texpath[MAX_VA_STRING];
int wadIndex; int wadIndex;
fs_offset_t srcSize = 0; rgbdata_t *pic = NULL;
byte* src = NULL;
// NOTE: We can't load the _luma texture from the WAD as normal because it // NOTE: We can't load the _luma texture from the WAD as normal because it
// doesn't exist there. The original texture is already loaded, but cannot be modified. // doesn't exist there. The original texture is already loaded, but cannot be modified.
// Instead, load the original texture again and convert it to luma. // Instead, load the original texture again and convert it to luma.
wadIndex = Mod_LoadTextureFromWadList( &world.wadlist, texture->name, &pic, NULL, 0 );
wadIndex = Mod_FindTextureInWadList( &world.wadlist, texture->name, texpath, sizeof( texpath )); if( wadIndex >= 0 && pic != NULL )
if( wadIndex >= 0 )
{ {
src = FS_LoadFile( texpath, &srcSize, false ); // OK, loading it from wad or hi-res(??) version
texture->fb_texturenum = ref.dllFuncs.GL_LoadTextureFromBuffer( texName, pic, TF_MAKELUMA, false );
FS_FreeImage( pic );
world.wadlist.wadusage[wadIndex]++; world.wadlist.wadusage[wadIndex]++;
} }
// OK, loading it from wad or hi-res version
texture->fb_texturenum = ref.dllFuncs.GL_LoadTexture( texName, src, srcSize, TF_MAKELUMA );
if( src )
Mem_Free( src );
} }
} }
#endif // !XASH_DEDICATED #endif // !XASH_DEDICATED