From 9b3e02f4e95ce9e09966f484817c6c8b18868744 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Nov 2009 15:48:57 +0000 Subject: [PATCH] From Jason Daly, "The DDS reader test for DXT1 images with 1-bit alpha wasn't thorough enough. It performed the first check (color_0 <= color_1), but it didn't actually scan the texel block to see if the transparent color (0x03) was there. As a result, DXT1 files without any alpha were getting switched to RGBA format (instead of being left just RGB). The attached code fixes this problem." --- src/osgPlugins/dds/ReaderWriterDDS.cpp | 34 +++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/osgPlugins/dds/ReaderWriterDDS.cpp b/src/osgPlugins/dds/ReaderWriterDDS.cpp index e79123147..7dbe3005e 100644 --- a/src/osgPlugins/dds/ReaderWriterDDS.cpp +++ b/src/osgPlugins/dds/ReaderWriterDDS.cpp @@ -660,16 +660,38 @@ osg::Image* ReadDDSFile(std::istream& _istream) { const DXT1TexelsBlock *texelsBlock = reinterpret_cast(imageData); - // Only do the check on the first mipmap level - for ( int i = size / sizeof( DXT1TexelsBlock ); i>0; --i, ++texelsBlock ) + // Only do the check on the first mipmap level, and stop when we + // see the first alpha texel + int i = size / sizeof(DXT1TexelsBlock); + bool foundAlpha = false; + while ((!foundAlpha) && (i>0)) { + // See if this block might contain transparent texels if (texelsBlock->color_0<=texelsBlock->color_1) { - // Texture is using the 1-bit alpha encoding, so we need to update the assumed pixel format - internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - break; + // Scan the texels block for the '11' bit pattern that + // indicates a transparent texel + int j = 0; + while ((!foundAlpha) && (j < 32)) + { + // Check for the '11' bit pattern on this texel + if ( ((texelsBlock->texels4x4 >> j) & 0x03) == 0x03) + { + // Texture is using the 1-bit alpha encoding, so we + // need to update the assumed pixel format + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + pixelFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + foundAlpha = true; + } + + // Next texel + j += 2; + } } + + // Next block + --i; + ++texelsBlock; } }