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:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user