From André Garneau, "The file submitted includes a fix to properly support DDS textures compressed under the DXT-1 format when they contain alpha information.

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."
This commit is contained in:
Robert Osfield
2006-11-27 09:23:57 +00:00
parent 4ab9c6f5f4
commit 60a975d05d

View File

@@ -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<const DXT1TexelsBlock*>(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();
}