renderergl2: allow DDS fallback when r_ext_compressed_textures=0

R_LoadImage now tries .dds as a final fallback when compressed textures are disabled.

This allows assets to ship as DDS-only without requiring duplicate PNG/TGA for every texture.

Fixes #583.
This commit is contained in:
Lojjik Braughler 2025-11-01 12:53:31 +00:00 committed by Tim Angus
parent 453705553b
commit 4f9e3b96e0

View File

@ -2410,7 +2410,9 @@ void R_LoadImage( const char *name, byte **pic, int *width, int *height, GLenum
qboolean orgNameFailed = qfalse; qboolean orgNameFailed = qfalse;
int orgLoader = -1; int orgLoader = -1;
int i; int i;
char base[ MAX_QPATH ];
char localName[ MAX_QPATH ]; char localName[ MAX_QPATH ];
char ddsName[ MAX_QPATH ];
const char *ext; const char *ext;
char *altName; char *altName;
@ -2420,80 +2422,83 @@ void R_LoadImage( const char *name, byte **pic, int *width, int *height, GLenum
*picFormat = GL_RGBA8; *picFormat = GL_RGBA8;
*numMips = 0; *numMips = 0;
Q_strncpyz( localName, name, MAX_QPATH ); Q_strncpyz(localName, name, sizeof(localName));
ext = COM_GetExtension(localName);
COM_StripExtension(name, base, sizeof(base));
ext = COM_GetExtension( localName ); // Build DDS name
Q_strncpyz(ddsName, base, sizeof(ddsName));
// If compressed textures are enabled, try loading a DDS first, it'll load fastest Q_strcat(ddsName, sizeof(ddsName), ".dds");
if (r_ext_compressed_textures->integer)
{
char ddsName[MAX_QPATH];
COM_StripExtension(name, ddsName, MAX_QPATH);
Q_strcat(ddsName, MAX_QPATH, ".dds");
if (r_ext_compressed_textures->integer) {
// Try DDS first
R_LoadDDS(ddsName, pic, width, height, picFormat, numMips); R_LoadDDS(ddsName, pic, width, height, picFormat, numMips);
if (*pic) return;
// If loaded, we're done. // Then try explicitly requested extension (if not DDS)
if (*pic) if (ext && *ext && Q_stricmp(ext, "dds")) {
return; for (i = 0; i < numImageLoaders; i++) {
} if (!Q_stricmp(ext, imageLoaders[i].ext)) {
imageLoaders[i].ImageLoader(localName, pic, width, height);
if( *ext ) if (*pic) return;
{ orgNameFailed = qtrue;
// Look for the correct loader and use it orgLoader = i;
for( i = 0; i < numImageLoaders; i++ ) break;
{ }
if( !Q_stricmp( ext, imageLoaders[ i ].ext ) )
{
// Load
imageLoaders[ i ].ImageLoader( localName, pic, width, height );
break;
} }
COM_StripExtension(name, localName, sizeof(localName));
} }
// A loader was found // Then probe all supported formats except the failed one
if( i < numImageLoaders ) for (i = 0; i < numImageLoaders; i++) {
{ if (i == orgLoader)
if( *pic == NULL ) continue;
{ altName = va("%s.%s", localName, imageLoaders[i].ext);
// Loader failed, most likely because the file isn't there; imageLoaders[i].ImageLoader(altName, pic, width, height);
// try again without the extension if (*pic) {
orgNameFailed = qtrue; if (orgNameFailed)
orgLoader = i; ri.Printf(PRINT_DEVELOPER, "WARNING: %s not present, using %s instead\n", name, altName);
COM_StripExtension( name, localName, MAX_QPATH );
}
else
{
// Something loaded
return; return;
} }
} }
return;
} }
// Try and find a suitable match using all // Explicit non-dds extension requested, so try its image loader
// the image formats supported if (ext && *ext && Q_stricmp(ext, "dds")) {
for( i = 0; i < numImageLoaders; i++ ) for (i = 0; i < numImageLoaders; i++) {
{ if (!Q_stricmp(ext, imageLoaders[i].ext)) {
imageLoaders[i].ImageLoader(localName, pic, width, height);
if (*pic) return;
orgNameFailed = qtrue;
orgLoader = i;
break;
}
}
COM_StripExtension(name, localName, sizeof(localName));
}
// Try all other uncompressed formats
for (i = 0; i < numImageLoaders; i++) {
if (i == orgLoader) if (i == orgLoader)
continue; continue;
if (!Q_stricmp(imageLoaders[i].ext, "dds"))
altName = va( "%s.%s", localName, imageLoaders[ i ].ext ); continue;
altName = va("%s.%s", localName, imageLoaders[i].ext);
// Load imageLoaders[i].ImageLoader(altName, pic, width, height);
imageLoaders[ i ].ImageLoader( altName, pic, width, height ); if (*pic) {
if (orgNameFailed)
if( *pic ) ri.Printf(PRINT_DEVELOPER, "WARNING: %s not present, using %s instead\n", name, altName);
{ return;
if( orgNameFailed )
{
ri.Printf( PRINT_DEVELOPER, "WARNING: %s not present, using %s instead\n",
name, altName );
}
break;
} }
} }
// Finally, allow DDS fallback even when compressed textures are off
if (!*pic) {
R_LoadDDS(ddsName, pic, width, height, picFormat, numMips);
if (*pic) ri.Printf(PRINT_DEVELOPER, "WARNING: falling back to compressed texture %s when r_ext_compressed_textures=0\n", ddsName);
}
} }