diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-03-12 07:08:09 -0500 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-03-12 07:08:09 -0500 |
| commit | 755698f1adceef55f52c8e44c9746537885c9bf7 (patch) | |
| tree | 23d1a9fea936805708eeccf2ac2684620565d328 /libs/preview_dds_native/src/ddsformat.cpp | |
| parent | 019870ffd8308d94289d72d45abeb3db39ccde92 (diff) | |
Replace Python plugins with native C++ .so, remove bundled Python (~95MB)
- Add native plugins: form43_checker, script_extender_checker, preview_dds,
basic_games (75 game defs via IPluginProxy pattern with Steam/GOG detection)
- Remove portable Python from Dockerfile and build-inner.sh
- Add Python settings tab with venv support (system python3 + PyQt6)
- Skip loading plugin_python.so when Python disabled (default: off)
- Update pythonrunner.cpp to use venv at ~/.local/share/fluorine/python-venv/
- Preserve real file permissions in FUSE VFS (fixes native executable +x bits)
- Add FUSE_SET_ATTR_MODE handler so chmod works through VFS
- Fix desktop shortcut Exec= to use fluorine-manager launcher, not bare binary
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/preview_dds_native/src/ddsformat.cpp')
| -rw-r--r-- | libs/preview_dds_native/src/ddsformat.cpp | 619 |
1 files changed, 619 insertions, 0 deletions
diff --git a/libs/preview_dds_native/src/ddsformat.cpp b/libs/preview_dds_native/src/ddsformat.cpp new file mode 100644 index 0000000..b56db91 --- /dev/null +++ b/libs/preview_dds_native/src/ddsformat.cpp @@ -0,0 +1,619 @@ +#include "ddsformat.h" + +#include <QOpenGLFunctions> +#include <QString> + +#include <algorithm> +#include <cstring> + +// GL compressed format constants not always in headers +#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#endif +#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif +#ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#endif +#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif +#ifndef GL_COMPRESSED_RED_RGTC1 +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#endif +#ifndef GL_COMPRESSED_SIGNED_RED_RGTC1 +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#endif +#ifndef GL_COMPRESSED_RG_RGTC2 +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#endif +#ifndef GL_COMPRESSED_SIGNED_RG_RGTC2 +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#endif +#ifndef GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#endif +#ifndef GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#endif +#ifndef GL_COMPRESSED_RGBA_BPTC_UNORM +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#endif +#ifndef GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#endif +#ifndef GL_COMPRESSED_SRGB_S3TC_DXT1_EXT +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#endif +#ifndef GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#endif +#ifndef GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#endif +#ifndef GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif + +static GLFormatInfo dxgiToGL(DXGIFormat fmt) +{ + GLFormatInfo info; + info.valid = true; + + switch (fmt) { + // BC1 (DXT1) + case DXGIFormat::BC1_UNORM: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + break; + case DXGIFormat::BC1_UNORM_SRGB: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + break; + // BC2 (DXT3) + case DXGIFormat::BC2_UNORM: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + case DXGIFormat::BC2_UNORM_SRGB: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + break; + // BC3 (DXT5) + case DXGIFormat::BC3_UNORM: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + case DXGIFormat::BC3_UNORM_SRGB: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + break; + // BC4 + case DXGIFormat::BC4_UNORM: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_RED_RGTC1; + break; + case DXGIFormat::BC4_SNORM: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_SIGNED_RED_RGTC1; + break; + // BC5 + case DXGIFormat::BC5_UNORM: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_RG_RGTC2; + break; + case DXGIFormat::BC5_SNORM: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_SIGNED_RG_RGTC2; + break; + // BC6H + case DXGIFormat::BC6H_UF16: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; + break; + case DXGIFormat::BC6H_SF16: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT; + break; + // BC7 + case DXGIFormat::BC7_UNORM: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_RGBA_BPTC_UNORM; + break; + case DXGIFormat::BC7_UNORM_SRGB: + info.compressed = true; + info.internalFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM; + break; + + // Uncompressed RGBA + case DXGIFormat::R8G8B8A8_UNORM: + case DXGIFormat::R8G8B8A8_UNORM_SRGB: + info.internalFormat = GL_RGBA8; + info.format = GL_RGBA; + info.type = GL_UNSIGNED_BYTE; + break; + case DXGIFormat::R8G8B8A8_UINT: + info.internalFormat = GL_RGBA8UI; + info.format = GL_RGBA_INTEGER; + info.type = GL_UNSIGNED_BYTE; + info.sampler = SamplerType::UInt; + break; + case DXGIFormat::R8G8B8A8_SNORM: + info.internalFormat = GL_RGBA8_SNORM; + info.format = GL_RGBA; + info.type = GL_BYTE; + break; + case DXGIFormat::R8G8B8A8_SINT: + info.internalFormat = GL_RGBA8I; + info.format = GL_RGBA_INTEGER; + info.type = GL_BYTE; + info.sampler = SamplerType::SInt; + break; + + // BGRA + case DXGIFormat::B8G8R8A8_UNORM: + case DXGIFormat::B8G8R8A8_UNORM_SRGB: + info.internalFormat = GL_RGBA8; + info.format = GL_BGRA; + info.type = GL_UNSIGNED_BYTE; + break; + case DXGIFormat::B8G8R8X8_UNORM: + case DXGIFormat::B8G8R8X8_UNORM_SRGB: + info.internalFormat = GL_RGBA8; + info.format = GL_BGRA; + info.type = GL_UNSIGNED_BYTE; + break; + + // 16-bit float + case DXGIFormat::R16G16B16A16_FLOAT: + info.internalFormat = GL_RGBA16F; + info.format = GL_RGBA; + info.type = GL_HALF_FLOAT; + break; + case DXGIFormat::R16G16B16A16_UNORM: + info.internalFormat = GL_RGBA16; + info.format = GL_RGBA; + info.type = GL_UNSIGNED_SHORT; + break; + case DXGIFormat::R16G16B16A16_UINT: + info.internalFormat = GL_RGBA16UI; + info.format = GL_RGBA_INTEGER; + info.type = GL_UNSIGNED_SHORT; + info.sampler = SamplerType::UInt; + break; + case DXGIFormat::R16G16B16A16_SNORM: + info.internalFormat = GL_RGBA16_SNORM; + info.format = GL_RGBA; + info.type = GL_SHORT; + break; + case DXGIFormat::R16G16B16A16_SINT: + info.internalFormat = GL_RGBA16I; + info.format = GL_RGBA_INTEGER; + info.type = GL_SHORT; + info.sampler = SamplerType::SInt; + break; + + // 32-bit float + case DXGIFormat::R32G32B32A32_FLOAT: + info.internalFormat = GL_RGBA32F; + info.format = GL_RGBA; + info.type = GL_FLOAT; + break; + case DXGIFormat::R32G32B32_FLOAT: + info.internalFormat = GL_RGB32F; + info.format = GL_RGB; + info.type = GL_FLOAT; + break; + + // RG formats + case DXGIFormat::R8G8_UNORM: + info.internalFormat = GL_RG8; + info.format = GL_RG; + info.type = GL_UNSIGNED_BYTE; + break; + case DXGIFormat::R16G16_FLOAT: + info.internalFormat = GL_RG16F; + info.format = GL_RG; + info.type = GL_HALF_FLOAT; + break; + case DXGIFormat::R16G16_UNORM: + info.internalFormat = GL_RG16; + info.format = GL_RG; + info.type = GL_UNSIGNED_SHORT; + break; + case DXGIFormat::R32G32_FLOAT: + info.internalFormat = GL_RG32F; + info.format = GL_RG; + info.type = GL_FLOAT; + break; + + // R formats + case DXGIFormat::R8_UNORM: + info.internalFormat = GL_R8; + info.format = GL_RED; + info.type = GL_UNSIGNED_BYTE; + break; + case DXGIFormat::R16_FLOAT: + info.internalFormat = GL_R16F; + info.format = GL_RED; + info.type = GL_HALF_FLOAT; + break; + case DXGIFormat::R16_UNORM: + info.internalFormat = GL_R16; + info.format = GL_RED; + info.type = GL_UNSIGNED_SHORT; + break; + case DXGIFormat::R32_FLOAT: + info.internalFormat = GL_R32F; + info.format = GL_RED; + info.type = GL_FLOAT; + break; + case DXGIFormat::A8_UNORM: + info.internalFormat = GL_R8; + info.format = GL_RED; + info.type = GL_UNSIGNED_BYTE; + break; + + // Packed formats + case DXGIFormat::R10G10B10A2_UNORM: + info.internalFormat = GL_RGB10_A2; + info.format = GL_RGBA; + info.type = GL_UNSIGNED_INT_2_10_10_10_REV; + break; + case DXGIFormat::R11G11B10_FLOAT: + info.internalFormat = GL_R11F_G11F_B10F; + info.format = GL_RGB; + info.type = GL_UNSIGNED_INT_10F_11F_11F_REV; + break; + case DXGIFormat::B5G6R5_UNORM: + info.internalFormat = GL_RGB565; + info.format = GL_RGB; + info.type = GL_UNSIGNED_SHORT_5_6_5; + break; + case DXGIFormat::B5G5R5A1_UNORM: + info.internalFormat = GL_RGB5_A1; + info.format = GL_BGRA; + info.type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + case DXGIFormat::B4G4R4A4_UNORM: + info.internalFormat = GL_RGBA4; + info.format = GL_BGRA; + info.type = GL_UNSIGNED_SHORT_4_4_4_4_REV; + break; + + default: + info.valid = false; + break; + } + + return info; +} + +DXGIFormat fourCCToDXGI(uint32_t fourCC) +{ + if (fourCC == makeFourCC('D', 'X', 'T', '1')) + return DXGIFormat::BC1_UNORM; + if (fourCC == makeFourCC('D', 'X', 'T', '3')) + return DXGIFormat::BC2_UNORM; + if (fourCC == makeFourCC('D', 'X', 'T', '5')) + return DXGIFormat::BC3_UNORM; + if (fourCC == makeFourCC('B', 'C', '4', 'U') || + fourCC == makeFourCC('A', 'T', 'I', '1')) + return DXGIFormat::BC4_UNORM; + if (fourCC == makeFourCC('B', 'C', '4', 'S')) + return DXGIFormat::BC4_SNORM; + if (fourCC == makeFourCC('A', 'T', 'I', '2') || + fourCC == makeFourCC('B', 'C', '5', 'U')) + return DXGIFormat::BC5_UNORM; + if (fourCC == makeFourCC('B', 'C', '5', 'S')) + return DXGIFormat::BC5_SNORM; + + // Numeric FourCC codes for float/half-float formats + switch (fourCC) { + case 36: + return DXGIFormat::R16G16B16A16_UNORM; + case 110: + return DXGIFormat::R16G16B16A16_SNORM; + case 111: + return DXGIFormat::R16_FLOAT; + case 112: + return DXGIFormat::R16G16_FLOAT; + case 113: + return DXGIFormat::R16G16B16A16_FLOAT; + case 114: + return DXGIFormat::R32_FLOAT; + case 115: + return DXGIFormat::R32G32_FLOAT; + case 116: + return DXGIFormat::R32G32B32A32_FLOAT; + default: + return DXGIFormat::UNKNOWN; + } +} + +// Helper: count trailing zeros / bit shift for a mask +static int maskShift(uint32_t mask) +{ + if (mask == 0) + return 0; + int shift = 0; + while ((mask & 1) == 0) { + mask >>= 1; + ++shift; + } + return shift; +} + +static int maskBits(uint32_t mask) +{ + int count = 0; + while (mask) { + count += mask & 1; + mask >>= 1; + } + return count; +} + +// Build a converter for arbitrary bitmask pixel formats +static GLFormatInfo buildBitmaskFormat(const DDSPixelFormat& pf) +{ + GLFormatInfo info; + info.valid = true; + + int rShift = maskShift(pf.dwRBitMask); + int gShift = maskShift(pf.dwGBitMask); + int bShift = maskShift(pf.dwBBitMask); + int aShift = maskShift(pf.dwABitMask); + int rBits = maskBits(pf.dwRBitMask); + int gBits = maskBits(pf.dwGBitMask); + int bBits = maskBits(pf.dwBBitMask); + int aBits = maskBits(pf.dwABitMask); + int bpp = pf.dwRGBBitCount; + + // Try to match common uncompressed formats directly + if (bpp == 32 && pf.dwRBitMask == 0x000000FF && pf.dwGBitMask == 0x0000FF00 && + pf.dwBBitMask == 0x00FF0000 && + (pf.dwABitMask == 0xFF000000 || pf.dwABitMask == 0)) { + info.internalFormat = GL_RGBA8; + info.format = GL_RGBA; + info.type = GL_UNSIGNED_BYTE; + return info; + } + if (bpp == 32 && pf.dwRBitMask == 0x00FF0000 && pf.dwGBitMask == 0x0000FF00 && + pf.dwBBitMask == 0x000000FF) { + info.internalFormat = GL_RGBA8; + info.format = GL_BGRA; + info.type = GL_UNSIGNED_BYTE; + return info; + } + + // Generic converter: extract channels and pack into RGBA8 + uint32_t rMask = pf.dwRBitMask; + uint32_t gMask = pf.dwGBitMask; + uint32_t bMask = pf.dwBBitMask; + uint32_t aMask = pf.dwABitMask; + bool hasAlpha = (pf.dwFlags & DDPF_ALPHAPIXELS) && aMask != 0; + int bytesPerPixel = bpp / 8; + + info.internalFormat = GL_RGBA8; + info.format = GL_RGBA; + info.type = GL_UNSIGNED_BYTE; + info.converter = [=](const QByteArray& data, int w, int h) -> QByteArray { + QByteArray result(w * h * 4, '\0'); + const uint8_t* src = reinterpret_cast<const uint8_t*>(data.constData()); + uint8_t* dst = reinterpret_cast<uint8_t*>(result.data()); + + for (int i = 0; i < w * h; ++i) { + uint32_t pixel = 0; + std::memcpy(&pixel, src + i * bytesPerPixel, + std::min(bytesPerPixel, 4)); + + int r = rBits > 0 ? ((pixel & rMask) >> rShift) * 255 / ((1 << rBits) - 1) : 0; + int g = gBits > 0 ? ((pixel & gMask) >> gShift) * 255 / ((1 << gBits) - 1) : 0; + int b = bBits > 0 ? ((pixel & bMask) >> bShift) * 255 / ((1 << bBits) - 1) : 0; + int a = hasAlpha && aBits > 0 + ? ((pixel & aMask) >> aShift) * 255 / ((1 << aBits) - 1) + : 255; + + dst[i * 4 + 0] = static_cast<uint8_t>(r); + dst[i * 4 + 1] = static_cast<uint8_t>(g); + dst[i * 4 + 2] = static_cast<uint8_t>(b); + dst[i * 4 + 3] = static_cast<uint8_t>(a); + } + return result; + }; + + return info; +} + +GLFormatInfo getGLFormat(const DDSPixelFormat& pf, const DDSHeaderDXT10* dxt10) +{ + // DX10 extended header takes priority + if (dxt10) { + return dxgiToGL(dxt10->dxgiFormat); + } + + // FourCC compressed or float formats + if (pf.dwFlags & DDPF_FOURCC) { + DXGIFormat dxgi = fourCCToDXGI(pf.dwFourCC); + if (dxgi != DXGIFormat::UNKNOWN) { + return dxgiToGL(dxgi); + } + GLFormatInfo info; + info.valid = false; + return info; + } + + // Uncompressed with bitmasks + if (pf.dwFlags & (DDPF_RGB | DDPF_LUMINANCE | DDPF_YUV | DDPF_ALPHA)) { + return buildBitmaskFormat(pf); + } + + GLFormatInfo info; + info.valid = false; + return info; +} + +static bool isBlockCompressed(DXGIFormat fmt) +{ + switch (fmt) { + case DXGIFormat::BC1_UNORM: + case DXGIFormat::BC1_UNORM_SRGB: + case DXGIFormat::BC2_UNORM: + case DXGIFormat::BC2_UNORM_SRGB: + case DXGIFormat::BC3_UNORM: + case DXGIFormat::BC3_UNORM_SRGB: + case DXGIFormat::BC4_UNORM: + case DXGIFormat::BC4_SNORM: + case DXGIFormat::BC5_UNORM: + case DXGIFormat::BC5_SNORM: + case DXGIFormat::BC6H_UF16: + case DXGIFormat::BC6H_SF16: + case DXGIFormat::BC7_UNORM: + case DXGIFormat::BC7_UNORM_SRGB: + return true; + default: + return false; + } +} + +static int blockSize(DXGIFormat fmt) +{ + switch (fmt) { + case DXGIFormat::BC1_UNORM: + case DXGIFormat::BC1_UNORM_SRGB: + case DXGIFormat::BC4_UNORM: + case DXGIFormat::BC4_SNORM: + return 8; + default: + return 16; + } +} + +uint32_t mipDataSize(DXGIFormat fmt, const DDSPixelFormat& pf, + uint32_t width, uint32_t height) +{ + if (isBlockCompressed(fmt)) { + uint32_t blocksW = std::max(1u, (width + 3) / 4); + uint32_t blocksH = std::max(1u, (height + 3) / 4); + return blocksW * blocksH * blockSize(fmt); + } + + // Uncompressed: use bits per pixel + uint32_t bpp = pf.dwRGBBitCount; + if (bpp == 0) { + // Estimate from DXGI format for non-bitmask formats + switch (fmt) { + case DXGIFormat::R32G32B32A32_FLOAT: + bpp = 128; + break; + case DXGIFormat::R32G32B32_FLOAT: + bpp = 96; + break; + case DXGIFormat::R16G16B16A16_FLOAT: + case DXGIFormat::R16G16B16A16_UNORM: + case DXGIFormat::R16G16B16A16_SNORM: + case DXGIFormat::R32G32_FLOAT: + bpp = 64; + break; + case DXGIFormat::R8G8B8A8_UNORM: + case DXGIFormat::R8G8B8A8_UNORM_SRGB: + case DXGIFormat::B8G8R8A8_UNORM: + case DXGIFormat::B8G8R8X8_UNORM: + case DXGIFormat::R16G16_FLOAT: + case DXGIFormat::R16G16_UNORM: + case DXGIFormat::R32_FLOAT: + case DXGIFormat::R10G10B10A2_UNORM: + case DXGIFormat::R11G11B10_FLOAT: + bpp = 32; + break; + case DXGIFormat::R8G8_UNORM: + case DXGIFormat::R16_FLOAT: + case DXGIFormat::R16_UNORM: + case DXGIFormat::B5G6R5_UNORM: + case DXGIFormat::B5G5R5A1_UNORM: + case DXGIFormat::B4G4R4A4_UNORM: + bpp = 16; + break; + case DXGIFormat::R8_UNORM: + case DXGIFormat::A8_UNORM: + bpp = 8; + break; + default: + bpp = 32; + break; + } + } + return width * height * bpp / 8; +} + +static const char* dxgiFormatName(DXGIFormat fmt) +{ + switch (fmt) { + case DXGIFormat::BC1_UNORM: + return "BC1_UNORM (DXT1)"; + case DXGIFormat::BC1_UNORM_SRGB: + return "BC1_UNORM_SRGB"; + case DXGIFormat::BC2_UNORM: + return "BC2_UNORM (DXT3)"; + case DXGIFormat::BC2_UNORM_SRGB: + return "BC2_UNORM_SRGB"; + case DXGIFormat::BC3_UNORM: + return "BC3_UNORM (DXT5)"; + case DXGIFormat::BC3_UNORM_SRGB: + return "BC3_UNORM_SRGB"; + case DXGIFormat::BC4_UNORM: + return "BC4_UNORM"; + case DXGIFormat::BC4_SNORM: + return "BC4_SNORM"; + case DXGIFormat::BC5_UNORM: + return "BC5_UNORM"; + case DXGIFormat::BC5_SNORM: + return "BC5_SNORM"; + case DXGIFormat::BC6H_UF16: + return "BC6H_UF16"; + case DXGIFormat::BC6H_SF16: + return "BC6H_SF16"; + case DXGIFormat::BC7_UNORM: + return "BC7_UNORM"; + case DXGIFormat::BC7_UNORM_SRGB: + return "BC7_UNORM_SRGB"; + case DXGIFormat::R8G8B8A8_UNORM: + return "R8G8B8A8_UNORM"; + case DXGIFormat::R8G8B8A8_UNORM_SRGB: + return "R8G8B8A8_UNORM_SRGB"; + case DXGIFormat::B8G8R8A8_UNORM: + return "B8G8R8A8_UNORM"; + case DXGIFormat::R16G16B16A16_FLOAT: + return "R16G16B16A16_FLOAT"; + case DXGIFormat::R32G32B32A32_FLOAT: + return "R32G32B32A32_FLOAT"; + default: + return "Unknown"; + } +} + +QString formatDescription(const DDSPixelFormat& pf, const DDSHeaderDXT10* dxt10) +{ + if (dxt10) { + return QString("DXGI: %1").arg(dxgiFormatName(dxt10->dxgiFormat)); + } + + if (pf.dwFlags & DDPF_FOURCC) { + char cc[5] = {0}; + std::memcpy(cc, &pf.dwFourCC, 4); + DXGIFormat dxgi = fourCCToDXGI(pf.dwFourCC); + if (dxgi != DXGIFormat::UNKNOWN) { + return QString("FourCC: %1 (%2)").arg(cc).arg(dxgiFormatName(dxgi)); + } + return QString("FourCC: %1").arg(cc); + } + + return QString("%1-bit R:0x%2 G:0x%3 B:0x%4 A:0x%5") + .arg(pf.dwRGBBitCount) + .arg(pf.dwRBitMask, 0, 16) + .arg(pf.dwGBitMask, 0, 16) + .arg(pf.dwBBitMask, 0, 16) + .arg(pf.dwABitMask, 0, 16); +} |
