diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj
index 50d7786d..04e88c80 100644
--- a/FModel/FModel.csproj
+++ b/FModel/FModel.csproj
@@ -127,6 +127,8 @@
+
+
diff --git a/FModel/PakReader/Textures/BC/Detex.cs b/FModel/PakReader/Textures/BC/Detex.cs
new file mode 100644
index 00000000..bcd032aa
--- /dev/null
+++ b/FModel/PakReader/Textures/BC/Detex.cs
@@ -0,0 +1,106 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+
+namespace PakReader.Textures.BC
+{
+ public static class Detex
+ {
+ private const string DETEX_DLL_NAME = "Detex.dll";
+
+ static Detex()
+ {
+ PrepareDllFile();
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ private unsafe struct detexTexture
+ {
+ public uint format;
+ public byte* data;
+ public int width;
+ public int height;
+ public int width_in_blocks;
+ public int height_in_blocks;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static byte[] DecodeDetexLinear(byte[] inp, int width, int height, bool isFloat, DetexTextureFormat inputFormat,
+ DetexPixelFormat outputPixelFormat, int blockSizeX = 4, int blockSizeY = 4)
+ {
+ var dst = new byte[width * height * (isFloat ? 16 : 4)];
+ DecodeDetexLinear(inp, dst, width, height, inputFormat, outputPixelFormat, blockSizeX, blockSizeY);
+ return dst;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool DecodeDetexLinear(byte[] inp, byte[] dst, int width, int height, DetexTextureFormat inputFormat, DetexPixelFormat outputPixelFormat, int blockSizeX = 4, int blockSizeY = 4)
+ {
+ unsafe
+ {
+ detexTexture tex;
+ tex.format = (uint) inputFormat;
+ tex.data = (byte*) Unsafe.AsPointer(ref inp[0]);
+ tex.width = width;
+ tex.height = height;
+ tex.width_in_blocks = width / 4;
+ tex.height_in_blocks = height / 4;
+ return detexDecompressTextureLinear(&tex, (byte*) Unsafe.AsPointer(ref dst[0]),
+ (uint) outputPixelFormat);
+ }
+ }
+
+ public static byte[] DecodeBC6H(byte[] inp, int width, int height)
+ {
+ const int PIXEL_SIZE = 16;
+ var dst = new byte[width * height * PIXEL_SIZE];
+
+ DecodeDetexLinear(inp, dst, width, height, DetexTextureFormat.DETEX_TEXTURE_FORMAT_BPTC_FLOAT,
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBX8);
+
+ return dst;
+ }
+
+ [DllImport(DETEX_DLL_NAME)]
+ private static extern unsafe bool detexDecompressTextureLinear(detexTexture* texture, byte* pixelBuffer,
+ uint pixelFormat);
+
+ private static void PrepareDllFile()
+ {
+ using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FModel.Resources.Detex.dll");
+ if (stream == null)
+ throw new MissingManifestResourceException("Couldn't find Detex.dll in Embedded Resources");
+ var ba = new byte[(int) stream.Length];
+ stream.Read(ba, 0, (int) stream.Length);
+
+ bool fileOk;
+ var dllFile = DETEX_DLL_NAME;
+
+ using (var sha1 = new SHA1CryptoServiceProvider())
+ {
+ var fileHash = BitConverter.ToString(sha1.ComputeHash(ba)).Replace("-", string.Empty);
+
+ if (File.Exists(dllFile))
+ {
+ var bb = File.ReadAllBytes(dllFile);
+ var fileHash2 = BitConverter.ToString(sha1.ComputeHash(bb)).Replace("-", string.Empty);
+
+ fileOk = fileHash == fileHash2;
+ }
+ else
+ {
+ fileOk = false;
+ }
+ }
+
+ if (!fileOk)
+ {
+ File.WriteAllBytes(dllFile, ba);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/FModel/PakReader/Textures/BC/DetexCompressedTextureFormatIndex.cs b/FModel/PakReader/Textures/BC/DetexCompressedTextureFormatIndex.cs
new file mode 100644
index 00000000..88d1b30c
--- /dev/null
+++ b/FModel/PakReader/Textures/BC/DetexCompressedTextureFormatIndex.cs
@@ -0,0 +1,39 @@
+namespace PakReader.Textures.BC
+{
+ internal enum DetexCompressedTextureFormatIndex : uint
+ {
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_UNCOMPRESSED = 0,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC1 = 1,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_DXT1 = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC1,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_S3TC = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC1,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC1A,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_DXT1A = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC1A,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC2,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_DXT3 = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC2,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC3,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_DXT5 = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC3,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_RGTC1,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC4_UNORM = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_RGTC1,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_SIGNED_RGTC1,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC4_SNORM = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_SIGNED_RGTC1,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_RGTC2,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC5_UNORM = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_RGTC2,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_SIGNED_RGTC2,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC5_SNORM = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_SIGNED_RGTC2,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BPTC_FLOAT,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC6H_UF16 = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BPTC_FLOAT,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BPTC_SIGNED_FLOAT,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC6H_SF16 = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BPTC_SIGNED_FLOAT,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BPTC,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC7 = DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BPTC,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_ETC1,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_ETC2,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_ETC2_PUNCHTHROUGH,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_ETC2_EAC,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_EAC_R11,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_EAC_SIGNED_R11,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_EAC_RG11,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_EAC_SIGNED_RG11,
+ DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_ASTC_4X4,
+ }
+}
\ No newline at end of file
diff --git a/FModel/PakReader/Textures/BC/DetexPixelFormat.cs b/FModel/PakReader/Textures/BC/DetexPixelFormat.cs
new file mode 100644
index 00000000..9dcc2f0b
--- /dev/null
+++ b/FModel/PakReader/Textures/BC/DetexPixelFormat.cs
@@ -0,0 +1,361 @@
+namespace PakReader.Textures.BC
+{
+ public enum DetexPixelFormat : uint
+ {
+ /* The format has 16-bit components. */
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT = 0x1,
+
+ /* The format has 32-bit components. */
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT = 0x2,
+
+ /* The format has an alpha component. */
+ DETEX_PIXEL_FORMAT_ALPHA_COMPONENT_BIT = 0x4,
+
+ /* The sequential component order is RGB. */
+ DETEX_PIXEL_FORMAT_RGB_COMPONENT_ORDER_BIT = 0x0,
+
+ /* The sequential component order is BGR. */
+ DETEX_PIXEL_FORMAT_BGR_COMPONENT_ORDER_BIT = 0x8,
+
+ /* The format has one component. */
+ DETEX_PIXEL_FORMAT_ONE_COMPONENT_BITS = 0x0,
+
+ /* The format has two components. */
+ DETEX_PIXEL_FORMAT_TWO_COMPONENTS_BITS = 0x10,
+
+ /* The format has three components. */
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS = 0x20,
+
+ /* The format has four components. */
+ DETEX_PIXEL_FORMAT_FOUR_COMPONENTS_BITS = 0x30,
+
+ /* The format is stored as 8-bit pixels. */
+ DETEX_PIXEL_FORMAT_8BIT_PIXEL_BITS = 0x000,
+
+ /* The format is stored as 16-bit pixels. */
+ DETEX_PIXEL_FORMAT_16BIT_PIXEL_BITS = 0x100,
+
+ /* The format is stored as 24-bit pixels. */
+ DETEX_PIXEL_FORMAT_24BIT_PIXEL_BITS = 0x200,
+
+ /* The format is stored as 32-bit pixels. */
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS = 0x300,
+
+ /* The format is stored as 48-bit pixels. */
+ DETEX_PIXEL_FORMAT_48BIT_PIXEL_BITS = 0x500,
+
+ /* The format is stored as 64-bit pixels. */
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS = 0x700,
+
+ /* The format is stored as 96-bit pixels. */
+ DETEX_PIXEL_FORMAT_96BIT_PIXEL_BITS = 0xB00,
+
+ /* The format is stored as 128-bit pixels. */
+ DETEX_PIXEL_FORMAT_128BIT_PIXEL_BITS = 0xF00,
+
+ /* The format has signed integer components. */
+ DETEX_PIXEL_FORMAT_SIGNED_BIT = 0x1000,
+
+ /* The format has (half-)float components. */
+ DETEX_PIXEL_FORMAT_FLOAT_BIT = 0x2000,
+
+ /* The fomat is HDR (high dynamic range). */
+ DETEX_PIXEL_FORMAT_HDR_BIT = 0x4000,
+
+ DETEX_PIXEL_FORMAT_RGBA8 = (
+ DETEX_PIXEL_FORMAT_ALPHA_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_FOUR_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_BGRA8 = (
+ DETEX_PIXEL_FORMAT_ALPHA_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_BGR_COMPONENT_ORDER_BIT |
+ DETEX_PIXEL_FORMAT_FOUR_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_RGBX8 = (
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_BGRX8 = (
+ DETEX_PIXEL_FORMAT_BGR_COMPONENT_ORDER_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_RGB8 = (
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_24BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_BGR8 = (
+ DETEX_PIXEL_FORMAT_BGR_COMPONENT_ORDER_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_24BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_R8 = (
+ DETEX_PIXEL_FORMAT_ONE_COMPONENT_BITS |
+ DETEX_PIXEL_FORMAT_8BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_SIGNED_R8 = (
+ DETEX_PIXEL_FORMAT_ONE_COMPONENT_BITS |
+ DETEX_PIXEL_FORMAT_8BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_SIGNED_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_RG8 = (
+ DETEX_PIXEL_FORMAT_TWO_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_16BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_SIGNED_RG8 = (
+ DETEX_PIXEL_FORMAT_TWO_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_16BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_SIGNED_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_R16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ONE_COMPONENT_BITS |
+ DETEX_PIXEL_FORMAT_16BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_SIGNED_R16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ONE_COMPONENT_BITS |
+ DETEX_PIXEL_FORMAT_16BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_SIGNED_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_RG16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_TWO_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_SIGNED_RG16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_TWO_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_SIGNED_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_RGB16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_48BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_RGBX16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_RGBA16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ALPHA_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_FOUR_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_R16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ONE_COMPONENT_BITS |
+ DETEX_PIXEL_FORMAT_16BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_R16_HDR = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ONE_COMPONENT_BITS |
+ DETEX_PIXEL_FORMAT_16BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RG16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_TWO_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RG16_HDR = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_TWO_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGBX16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGBX16_HDR = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGBA16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ALPHA_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_FOUR_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGBA16_HDR = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ALPHA_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_FOUR_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGB16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_48BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGB16_HDR = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_48BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_BGRX16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_BGR_COMPONENT_ORDER_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_BGRX16_HDR = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_BGR_COMPONENT_ORDER_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_SIGNED_FLOAT_RGBX16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_SIGNED_BIT |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_SIGNED_FLOAT_BGRX16 = (
+ DETEX_PIXEL_FORMAT_16BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_BGR_COMPONENT_ORDER_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_SIGNED_BIT |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_R32 = (
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ONE_COMPONENT_BITS |
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_R32_HDR = (
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ONE_COMPONENT_BITS |
+ DETEX_PIXEL_FORMAT_32BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RG32 = (
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_TWO_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RG32_HDR = (
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_TWO_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_64BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGB32 = (
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_96BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGB32_HDR = (
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_96BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGBX32 = (
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_128BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGBX32_HDR = (
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_THREE_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_128BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGBA32 = (
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ALPHA_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_FOUR_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_128BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_FLOAT_RGBA32_HDR = (
+ DETEX_PIXEL_FORMAT_32BIT_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ALPHA_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_FOUR_COMPONENTS_BITS |
+ DETEX_PIXEL_FORMAT_128BIT_PIXEL_BITS |
+ DETEX_PIXEL_FORMAT_FLOAT_BIT |
+ DETEX_PIXEL_FORMAT_HDR_BIT
+ ),
+
+ DETEX_PIXEL_FORMAT_A8 = (
+ DETEX_PIXEL_FORMAT_ALPHA_COMPONENT_BIT |
+ DETEX_PIXEL_FORMAT_ONE_COMPONENT_BITS |
+ DETEX_PIXEL_FORMAT_8BIT_PIXEL_BITS
+ ),
+ }
+}
\ No newline at end of file
diff --git a/FModel/PakReader/Textures/BC/DetexTextureFormat.cs b/FModel/PakReader/Textures/BC/DetexTextureFormat.cs
new file mode 100644
index 00000000..23247a13
--- /dev/null
+++ b/FModel/PakReader/Textures/BC/DetexTextureFormat.cs
@@ -0,0 +1,119 @@
+namespace PakReader.Textures.BC
+{
+ public enum DetexTextureFormat : uint
+ {
+ DETEX_TEXTURE_FORMAT_PIXEL_FORMAT_MASK = 0x0000FFFF,
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT = 0x00800000,
+
+ DETEX_TEXTURE_FORMAT_BC1 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC1 << 24) |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBX8
+ ),
+
+ DETEX_TEXTURE_FORMAT_BC1A = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC1A << 24) |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8
+ ),
+
+ DETEX_TEXTURE_FORMAT_BC2 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC2 << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8
+ ),
+
+ DETEX_TEXTURE_FORMAT_BC3 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BC3 << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8
+ ),
+
+ DETEX_TEXTURE_FORMAT_RGTC1 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_RGTC1 << 24) |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_R8
+ ),
+
+ DETEX_TEXTURE_FORMAT_SIGNED_RGTC1 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_SIGNED_RGTC1 << 24) |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_SIGNED_R16
+ ),
+
+ DETEX_TEXTURE_FORMAT_RGTC2 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_RGTC2 << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RG8
+ ),
+
+ DETEX_TEXTURE_FORMAT_SIGNED_RGTC2 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_SIGNED_RGTC2 << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_SIGNED_RG16
+ ),
+
+ DETEX_TEXTURE_FORMAT_BPTC_FLOAT = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BPTC_FLOAT << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_FLOAT_RGBX16
+ ),
+
+ DETEX_TEXTURE_FORMAT_BPTC_SIGNED_FLOAT = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BPTC_SIGNED_FLOAT << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_SIGNED_FLOAT_RGBX16
+ ),
+
+ DETEX_TEXTURE_FORMAT_BPTC = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_BPTC << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8
+ ),
+
+ DETEX_TEXTURE_FORMAT_ETC1 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_ETC1 << 24) |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBX8
+ ),
+
+ DETEX_TEXTURE_FORMAT_ETC2 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_ETC2 << 24) |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBX8
+ ),
+
+ DETEX_TEXTURE_FORMAT_ETC2_PUNCHTHROUGH = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_ETC2_PUNCHTHROUGH << 24) |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8
+ ),
+
+ DETEX_TEXTURE_FORMAT_ETC2_EAC = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_ETC2_EAC << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8
+ ),
+
+ DETEX_TEXTURE_FORMAT_EAC_R11 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_EAC_R11 << 24) |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_R16
+ ),
+
+ DETEX_TEXTURE_FORMAT_EAC_SIGNED_R11 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_EAC_SIGNED_R11 << 24) |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_SIGNED_R16
+ ),
+
+ DETEX_TEXTURE_FORMAT_EAC_RG11 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_EAC_RG11 << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RG16
+ ),
+
+ DETEX_TEXTURE_FORMAT_EAC_SIGNED_RG11 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_EAC_SIGNED_RG11 << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_SIGNED_RG16
+ ),
+
+ DETEX_TEXTURE_FORMAT_ASTC_4X4 = (
+ (DetexCompressedTextureFormatIndex.DETEX_COMPRESSED_TEXTURE_FORMAT_INDEX_ASTC_4X4 << 24) |
+ DETEX_TEXTURE_FORMAT_128BIT_BLOCK_BIT |
+ DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8
+ ),
+ }
+}
\ No newline at end of file
diff --git a/FModel/PakReader/Textures/TextureDecoder.cs b/FModel/PakReader/Textures/TextureDecoder.cs
index d929915c..6c0a557d 100644
--- a/FModel/PakReader/Textures/TextureDecoder.cs
+++ b/FModel/PakReader/Textures/TextureDecoder.cs
@@ -50,6 +50,37 @@ namespace PakReader.Textures
data = sequence;
colorType = SKColorType.RgbaF16;
break;
+ case EPixelFormat.PF_BC7:
+ data = Detex.DecodeDetexLinear(sequence, width, height, isFloat: false,
+ inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_BPTC,
+ outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
+ colorType = SKColorType.Rgba8888;
+ break;
+ case EPixelFormat.PF_BC6H:
+ data = Detex.DecodeDetexLinear(sequence, width, height, isFloat: true,
+ inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_BPTC_FLOAT,
+ outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBX8); // Not sure whether that works, would actually be DETEX_PIXEL_FORMAT_FLOAT_RGBX32
+ data = Detex.DecodeBC6H(sequence, width, height);
+ colorType = SKColorType.Rgb888x;
+ break;
+ case EPixelFormat.PF_ETC1:
+ data = Detex.DecodeDetexLinear(sequence, width, height, isFloat: false,
+ inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC1,
+ outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
+ colorType = SKColorType.Rgba8888;
+ break;
+ case EPixelFormat.PF_ETC2_RGB:
+ data = Detex.DecodeDetexLinear(sequence, width, height, isFloat: false,
+ inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC2,
+ outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
+ colorType = SKColorType.Rgba8888;
+ break;
+ case EPixelFormat.PF_ETC2_RGBA:
+ data = Detex.DecodeDetexLinear(sequence, width, height, isFloat: false,
+ inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC2_EAC,
+ outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
+ colorType = SKColorType.Rgba8888;
+ break;
default:
throw new NotImplementedException($"Cannot decode {format} format");
}
diff --git a/FModel/Resources/Detex.dll b/FModel/Resources/Detex.dll
new file mode 100644
index 00000000..a05872ba
Binary files /dev/null and b/FModel/Resources/Detex.dll differ