Hi All, I have been investigating issues with handling of .dds image files that contain DXT1 compressed RGB data, with some of these files being picked out as being RGBA because they have a black pixel within them. I've looked at what documentation on DXT1 I can find on the web and have what looks to be a conflict/ambiguity between Microsfts online docs on DXT1:
http://msdn.microsoft.com/en-us/library/bb204843(v=VS.85).aspx http://msdn.microsoft.com/en-us/library/bb147243(v=VS.85).aspx And the GL spec for the S3TC compressed texture extension: http://www.opengl.org/registry/specs/EXT/texture_compression_dxt1.txt To me it looks like the MS docs refer to what is effectively the GL_COMPRESSED_RGBA_S3TC_DXT1_EXT pixel format, and there is no equivilant to the GL_COMPRESSED_RGB_S3TC_DXT1_EXT. On the GL side the only difference between the RGBA and RGB versions of DXT1 is that RGBA interprets a alpha of 0 while RGB interprets black for the same bit setting in the data format. Problems arise because the dds format doesn't explictly distinguish between the RGB and RGBA versions of DXT1 so you are left to guess which is intended. Frustratingly the dds format does have bits in the header for specifying alpha in the pixel format but the 3rd party generated dds files I have the alpha bit is only looks to be properly set when using uncompressed RGB vs RGBA. Our dds writer does actually set the alpha bit when writing out GL_COMPRESSED_RGBA_S3TC_DXT1_EXT so our dds reader has all the info it needs to reliably distinguish between the two, but alas.. it's the 3rd party data that most users will be dealing with. Up till now the dds plugin has been addressing the ambuguity by checking the presense of 0 alpha entries in the DXT1 pixel blocks, however, this check is invalid if black has been encoded as part of a GL_COMPRESSED_RGB_S3TC_DXT1_EXT compressed image. All these checks do is assume that the format is GL_COMPRESSED_RGBA_S3TC_DXT1_EXT and check for the presense of any 0 alpha entries, and if so set the format to GL_COMPRESSED_RGBA_S3TC_DXT1_EXT otherwise set it to GL_COMPRESSED_RGB_S3TC_DXT1_EXT. Given this checks are not robust, I don't think we should be relying upon them, particularily in the default implementation in plugin. >From what I can work out MS's docs describe the GL_COMPRESSED_RGBA_S3TC_DXT1_EXT format, so if one follows this onto the dds format perhaps one should just default to GL_COMPRESSED_RGBA_S3TC_DXT1_EXT. However, in general documentation on DXT that I've seen on the web suggests using DXT1 for RGB data and DXT3 or DXT5 for RGBA data, and only in special cases where 0 or 1 alpha is acceptable might you consided DXT1a (RGBA version of DXT1). Given this perhaps we should be assuming GL_COMPRESSED_RGB_S3TC_DXT1_EXT. Another complication has that some applications and other other OSG plugins use the pixel format information to tell whether a texture and stateset associated with them should be classified as transparent so should have blending and dropped into the transparent bin for depth sorting. There is an osg::Image::isImageTranslucent() method that helps this process, but it previously didn't handle the DXT formats at all. Yesterday I added support for DXT1 into the isImageTranslucent() method, and simplified the dds DXT1 RGBvsRGBA detection code to use this, this provides a little more general functionality as well as make the code in the dds DXT1 RGBvsRGBA detection code in the dds plugin clearer. However, the new DXT1 RGBvsRGBA detection code is no more robust than original code - it still wrongly tags DXT1 RGB with black pixels as being RGBA. There isn't any way to make this detection code robust - the ambiguity is built into the format, so it's not a case of just needing to fix a bug, but a case of deciding on what policy to take when dealing with this ambuiguity - hence this email, giving the community a chance to discuss the options and what the defaults should be going forward. The options I can see are: 1) Keep the current assumption of DXT1 RGBA encoding and use the DXT1 RGBvsRGBA detection code to switch back to RGB when no 0 alpha pixels are found. This does wrongly identify DXT1 RGB encoded images with black pixels as being RGBA. 2) Always assume DXT1 RGBA encoding for dds files. Let applications reset to RGB if they know the image to RGB encoded. 3) Always assume DXT1 RGB encoding for dds files. Let applications reset to RGBA if they know the image to RGBA encoded. 4) Use an osgDB::Option setting to set what on the above behaviour should be. Now Option 4 is what I'm actually about to implement... but... it doesn't resolve what the default setting should be, Option 1 would keep the status quo as it is, which will work OK for some apps, but fail for others. Options 2 and 3 won't be perfect for all apps either. So what are end users experiences with DXT1 RGB and RGBA encoded images? Do you use DXT1 for only RGB, only for RGBA, or both? What 3rd party tools do you use for generating your DXT1 dds files? What issues have you found when using DXT1 in your apps? Of the above options what default would you perfer? I look forward to your thoughts. Robert. _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org