From 8fd317ab4c7ebdeb5783d3d8767bc5c2748116aa Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Wed, 5 Mar 2025 18:22:10 +0100 Subject: [PATCH] Fix loading of DDS textures with incomplete mipmaps Apparently OpenGL (or at least nvidias driver?) is unhappy if the smallest mipmaplevel isn't 1x1 pixels. It doesn't show any error in debug messages, but it's just set to black. This can be worked around by setting GL_TEXTURE_MAX_LEVEL --- neo/renderer/Image_load.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/neo/renderer/Image_load.cpp b/neo/renderer/Image_load.cpp index 4a4a8ad4..a2eb4b8d 100644 --- a/neo/renderer/Image_load.cpp +++ b/neo/renderer/Image_load.cpp @@ -1536,6 +1536,7 @@ void idImage::UploadPrecompressedImage( byte *data, int len ) { int uw = uploadWidth; int uh = uploadHeight; + int lastUW = uw, lastUH = uh; // We may skip some mip maps if we are downsizing int skipMip = 0; @@ -1561,6 +1562,8 @@ void idImage::UploadPrecompressedImage( byte *data, int len ) { qglTexImage2D( GL_TEXTURE_2D, i - skipMip, internalFormat, uw, uh, 0, externalFormat, GL_UNSIGNED_BYTE, imagedata ); } } + lastUW = uw; + lastUH = uh; imagedata += size; uw /= 2; @@ -1572,6 +1575,19 @@ void idImage::UploadPrecompressedImage( byte *data, int len ) { uh = 1; } } + // in case the mipmap chain is incomplete (doesn't go down to 1x1 pixel) + // the texture may be shown as black unless GL_TEXTURE_MAX_LEVEL is set accordingly + if ( lastUW > 1 || lastUH > 1 ) { + numMipmaps -= skipMip; + if ( numMipmaps == 1 ) { + // if there is only one mipmap, just don't use mipmapping for this texture + if ( filter == TF_DEFAULT ) { + filter = TF_LINEAR; + } + } else { + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, numMipmaps - 1 ); + } + } SetImageFilterAndRepeat(); }