From 60a975d05d7ded4489a910819a840531e1e9d3f7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Nov 2006 09:23:57 +0000 Subject: [PATCH] =?UTF-8?q?From=20Andr=C3=A9=20Garneau,=20"The=20file=20su?= =?UTF-8?q?bmitted=20includes=20a=20fix=20to=20properly=20support=20DDS=20?= =?UTF-8?q?textures=20compressed=20under=20the=20DXT-1=20format=20when=20t?= =?UTF-8?q?hey=20contain=20alpha=20information.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under this mode, each 4x4 texel block can selectively use an alpha component or none. When alpha-enabled blocks are present, this is not reported in the DDPF_ALPHAPIXELS bit in the pixel format flags causing the reader-writer to report the file as a 3-components file (GL_COMPRESSED_RGB_S3TC_DXT1_EXT). The fix requires looking at each 4x4 texel block to detect the presence of 1-bit alpha encoding. When such a block is found, the internal & pixel formats are reported as GL_COMPRESSED_RGBA_S3TC_DXT1_EXT instead. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/Opaque_and_1_Bit_Alpha_Textures.asp for more information." --- src/osgPlugins/dds/ReaderWriterDDS.cpp | 41 ++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/osgPlugins/dds/ReaderWriterDDS.cpp b/src/osgPlugins/dds/ReaderWriterDDS.cpp index 54e485c93..00d55c977 100644 --- a/src/osgPlugins/dds/ReaderWriterDDS.cpp +++ b/src/osgPlugins/dds/ReaderWriterDDS.cpp @@ -155,7 +155,18 @@ struct DDSURFACEDESC2 DDPIXELFORMAT ddpfPixelFormat; DDSCAPS2 ddsCaps; UI32 dwTextureStage; -}; +}; + +// +// Structure of a DXT-1 compressed texture block +// see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/Opaque_and_1_Bit_Alpha_Textures.asp +// +struct DXT1TexelsBlock +{ + unsigned short color_0; // colors at their + unsigned short color_1; // extreme + unsigned int texels4x4; // interpolated colors (2 bits per texel) +}; // // DDSURFACEDESC2 flags that mark the validity of the struct data @@ -259,6 +270,7 @@ osg::Image* ReadDDSFile(std::istream& _istream) // while compressed formats will use DDPF_FOURCC with a four-character code. bool usingAlpha = ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS; + bool checkIfUsingOneBitAlpha = false; // Uncompressed formats. if(ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB) @@ -304,6 +316,7 @@ osg::Image* ReadDDSFile(std::istream& _istream) { internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; pixelFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + checkIfUsingOneBitAlpha = true; } break; case FOURCC_DXT3: @@ -431,13 +444,29 @@ osg::Image* ReadDDSFile(std::istream& _istream) // Read image data _istream.read((char*)imageData, size); + // Check if alpha information embedded in the 8-byte encoding blocks + if (checkIfUsingOneBitAlpha) + { + const DXT1TexelsBlock *texelsBlock = reinterpret_cast(imageData); + + // Only do the check on the first mipmap level + unsigned int numBlocks = mipmaps.size()>0 ? mipmaps[0] / 8 : size / 8; + + for (int i=numBlocks; i>0; --i, ++texelsBlock) + { + 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; + } + } + } + osgImage->setImage(s,t,r, internalFormat, pixelFormat, dataType, imageData, osg::Image::USE_NEW_DELETE); if (mipmaps.size()>0) osgImage->setMipmapLevels(mipmaps); - - - - - + // Return Image. return osgImage.release(); }