Closed LiamKarlMitchell closed 3 years ago
Thank you for the test case and the resources. I can confirm the bug. I may mull over potential solutions for a bit. Seems at the very least, Dxt1 will need to change it's image format at decode time from Rgb24 to something else (or always use Rgba32 like you suggest)
I thought about changing at decode time. It could allocate the extra bytes with PIXEL_DEPTH = 4 have a private variable for the real ImageFormat. If a transparent part is found, then set it to Rgba32 Otherwise Rgb24 and truncate the Dds bytes returned to remove the excess.
But this could be messy with mip maps have not looked yet at how that is done.
https://www.khronos.org/opengl/wiki/S3_Texture_Compression Actually gave me the way to get it in clear English,
DXT1 with 1-bit Alpha
There is a form of DXT1 available that provides a simple on/off alpha value. This format therefore uses an RGBA base format. To get this format, use the GL_COMPRESSED_RGBA_S3TC_DXT1_EXT internal format.
The format of the data is identical to the above case, which is why this is still DXT1 compression. The interpretation differs slightly. You always get an alpha value of 1 unless the pixel uses the code for Black in the above table. In that case, you get an alpha value of 0.
Note that this means that the RGB colors will also be 0 on any pixel with a 0 alpha. This also means that bilinear filtering between neighboring texels will result in colors combined with black. If you are using premultipled alpha blending, this is what you want. If you aren't, then it almost certainly is not what you want.
The filtering thing can be handled by adjusting the alpha cut off value.
This write up has an example of the black line issue when rendering with filtering. http://www.reedbeta.com/blog/understanding-bcn-texture-compression-formats/
if (color0 <= color1 && ((rowVal >> j) & 0x3) == 3)
{
data[dataIndex++] = 0x00;
}
else
{
data[dataIndex++] = 0xFF;
}
I'm sure it could be done nicer, I would assume that just using Rgba32 format would be faster as there would not be a constant setting of the format.
Hi @nickbabcock ,
Thank you very much for implementing this I had neglected to the mip map information. Suggest you use an alternative sample image MIT license etc.
Just made this one up with some transparent radio gradients. It has different sizes of transparent blocks and colors.
Please see attached. dxt1-alpha.zip
Thank you, this actually uncovered another bug where no floor was applied to mipmaps (ie: the last entry could have a height / width of 0). This will be fixed in #73 as well as your requested image change
DXT1 can contain alpha.
RGB 5:6:5 RGBA 5:5:5:1
When a DDS DXT1 is loaded into Paint.Net, Window Texture Viewer, Photoshop, previewed in explorer with the DDS extension etc it has a transparency.
When loading with Pfim this alpha is not available.
Screenshot showing Paint.Net and Pfim Viewer.
Sample dds attached. 0004a283.zip
References: https://docs.microsoft.com/en-gb/windows/win32/direct3d9/opaque-and-1-bit-alpha-textures?redirectedfrom=MSDN https://stackoverflow.com/questions/19448/in-a-dds-file-can-you-detect-textures-with-0-1-alpha-bits https://www.buckarooshangar.com/flightgear/tut_dds.html https://www.khronos.org/registry/DataFormat/specs/1.1/dataformat.1.1.html#_bc1_with_alpha https://en.wikipedia.org/wiki/S3_Texture_Compression#DXT1
Paint.Net plugin for loading DDS. https://github.com/0xC0000054/pdn-ddsfiletype-plus/tree/master/3rdParty/DirectXTex/DirectXTex
Dxt1Dds changes: Change DIV_SIZE to 4.
Change image format to Rgba32
And writing out an alpha byte after the rgb. The part I am stuck on at the moment how to get out the correct alpha bit for each pixel.