diff --git a/AssetStudio/AssetStudio-x86.csproj b/AssetStudio/AssetStudio-x86.csproj
index 96bafb2..a0a0ffc 100644
--- a/AssetStudio/AssetStudio-x86.csproj
+++ b/AssetStudio/AssetStudio-x86.csproj
@@ -176,7 +176,6 @@
-
@@ -212,6 +211,7 @@
+
AssetStudioForm.cs
diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj
index cdc3c6e..d747ccc 100644
--- a/AssetStudio/AssetStudio.csproj
+++ b/AssetStudio/AssetStudio.csproj
@@ -169,7 +169,6 @@
-
@@ -206,6 +205,7 @@
+
Form
diff --git a/AssetStudio/AssetStudioForm.cs b/AssetStudio/AssetStudioForm.cs
index e5f2e93..cce258e 100644
--- a/AssetStudio/AssetStudioForm.cs
+++ b/AssetStudio/AssetStudioForm.cs
@@ -715,7 +715,7 @@ namespace AssetStudio
case ClassIDReference.Texture2D:
{
imageTexture?.Dispose();
- var m_Texture2D = new Texture2D(asset, true);
+ var m_Texture2D = new Texture2DConverter(new Texture2D(asset, true));
imageTexture = m_Texture2D.ConvertToBitmap(true);
if (imageTexture != null)
{
diff --git a/AssetStudio/Classes/Texture2D.Converter.cs b/AssetStudio/Classes/Texture2D.Converter.cs
deleted file mode 100644
index 260eda2..0000000
--- a/AssetStudio/Classes/Texture2D.Converter.cs
+++ /dev/null
@@ -1,540 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace AssetStudio
-{
- partial class Texture2D
- {
- [DllImport("PVRTexLibWrapper.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern bool DecompressPVR(byte[] buffer, IntPtr bmp, int len);
-
- [DllImport("TextureConverterWrapper.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern bool Ponvert(byte[] buffer, IntPtr bmp, int nWidth, int nHeight, int len, int type, int bmpsize, bool fixAlpha);
-
- [DllImport("crunch.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern bool DecompressCRN(byte[] pSrc_file_data, int src_file_size, out IntPtr uncompressedData, out int uncompressedSize);
-
- [DllImport("crunchunity.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern bool DecompressUnityCRN(byte[] pSrc_file_data, int src_file_size, out IntPtr uncompressedData, out int uncompressedSize);
-
- [DllImport("texgenpack.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern void texgenpackdecode(int texturetype, byte[] texturedata, int width, int height, IntPtr bmp, bool fixAlpha);
-
-
- public byte[] ConvertToContainer()
- {
- if (image_data == null || image_data.Length == 0)
- return null;
- switch (m_TextureFormat)
- {
- case TextureFormat.Alpha8:
- case TextureFormat.ARGB4444:
- case TextureFormat.RGB24:
- case TextureFormat.RGBA32:
- case TextureFormat.ARGB32:
- case TextureFormat.RGB565:
- case TextureFormat.R16:
- case TextureFormat.DXT1:
- case TextureFormat.DXT5:
- case TextureFormat.RGBA4444:
- case TextureFormat.BGRA32:
- case TextureFormat.RG16:
- case TextureFormat.R8:
- return ConvertToDDS();
- case TextureFormat.YUY2:
- case TextureFormat.PVRTC_RGB2:
- case TextureFormat.PVRTC_RGBA2:
- case TextureFormat.PVRTC_RGB4:
- case TextureFormat.PVRTC_RGBA4:
- case TextureFormat.ETC_RGB4:
- case TextureFormat.ETC2_RGB:
- case TextureFormat.ETC2_RGBA1:
- case TextureFormat.ETC2_RGBA8:
- case TextureFormat.ASTC_RGB_4x4:
- case TextureFormat.ASTC_RGB_5x5:
- case TextureFormat.ASTC_RGB_6x6:
- case TextureFormat.ASTC_RGB_8x8:
- case TextureFormat.ASTC_RGB_10x10:
- case TextureFormat.ASTC_RGB_12x12:
- case TextureFormat.ASTC_RGBA_4x4:
- case TextureFormat.ASTC_RGBA_5x5:
- case TextureFormat.ASTC_RGBA_6x6:
- case TextureFormat.ASTC_RGBA_8x8:
- case TextureFormat.ASTC_RGBA_10x10:
- case TextureFormat.ASTC_RGBA_12x12:
- case TextureFormat.ETC_RGB4_3DS:
- case TextureFormat.ETC_RGBA8_3DS:
- return ConvertToPVR();
- case TextureFormat.RHalf:
- case TextureFormat.RGHalf:
- case TextureFormat.RGBAHalf:
- case TextureFormat.RFloat:
- case TextureFormat.RGFloat:
- case TextureFormat.RGBAFloat:
- case TextureFormat.BC4:
- case TextureFormat.BC5:
- case TextureFormat.BC6H:
- case TextureFormat.BC7:
- case TextureFormat.ATC_RGB4:
- case TextureFormat.ATC_RGBA8:
- case TextureFormat.EAC_R:
- case TextureFormat.EAC_R_SIGNED:
- case TextureFormat.EAC_RG:
- case TextureFormat.EAC_RG_SIGNED:
- return ConvertToKTX();
- default:
- return image_data;
- }
- }
-
- private byte[] ConvertToDDS()
- {
- var imageBuffer = new byte[128 + image_data_size];
- dwMagic.CopyTo(imageBuffer, 0);
- BitConverter.GetBytes(dwFlags).CopyTo(imageBuffer, 8);
- BitConverter.GetBytes(m_Height).CopyTo(imageBuffer, 12);
- BitConverter.GetBytes(m_Width).CopyTo(imageBuffer, 16);
- BitConverter.GetBytes(dwPitchOrLinearSize).CopyTo(imageBuffer, 20);
- BitConverter.GetBytes(dwMipMapCount).CopyTo(imageBuffer, 28);
- BitConverter.GetBytes(dwSize).CopyTo(imageBuffer, 76);
- BitConverter.GetBytes(dwFlags2).CopyTo(imageBuffer, 80);
- BitConverter.GetBytes(dwFourCC).CopyTo(imageBuffer, 84);
- BitConverter.GetBytes(dwRGBBitCount).CopyTo(imageBuffer, 88);
- BitConverter.GetBytes(dwRBitMask).CopyTo(imageBuffer, 92);
- BitConverter.GetBytes(dwGBitMask).CopyTo(imageBuffer, 96);
- BitConverter.GetBytes(dwBBitMask).CopyTo(imageBuffer, 100);
- BitConverter.GetBytes(dwABitMask).CopyTo(imageBuffer, 104);
- BitConverter.GetBytes(dwCaps).CopyTo(imageBuffer, 108);
- BitConverter.GetBytes(dwCaps2).CopyTo(imageBuffer, 112);
- image_data.CopyTo(imageBuffer, 128);
- return imageBuffer;
- }
-
- private byte[] ConvertToPVR()
- {
- var mstream = new MemoryStream();
- using (var writer = new BinaryWriter(mstream))
- {
- writer.Write(pvrVersion);
- writer.Write(pvrFlags);
- writer.Write(pvrPixelFormat);
- writer.Write(pvrColourSpace);
- writer.Write(pvrChannelType);
- writer.Write(m_Height);
- writer.Write(m_Width);
- writer.Write(pvrDepth);
- writer.Write(pvrNumSurfaces);
- writer.Write(pvrNumFaces);
- writer.Write(dwMipMapCount);
- writer.Write(pvrMetaDataSize);
- writer.Write(image_data);
- return mstream.ToArray();
- }
- }
-
- private byte[] ConvertToKTX()
- {
- var mstream = new MemoryStream();
- using (var writer = new BinaryWriter(mstream))
- {
- writer.Write(KTXHeader.IDENTIFIER);
- writer.Write(KTXHeader.ENDIANESS_LE);
- writer.Write(glType);
- writer.Write(glTypeSize);
- writer.Write(glFormat);
- writer.Write(glInternalFormat);
- writer.Write(glBaseInternalFormat);
- writer.Write(m_Width);
- writer.Write(m_Height);
- writer.Write(pixelDepth);
- writer.Write(numberOfArrayElements);
- writer.Write(numberOfFaces);
- writer.Write(numberOfMipmapLevels);
- writer.Write(bytesOfKeyValueData);
- writer.Write(image_data_size);
- writer.Write(image_data);
- return mstream.ToArray();
- }
- }
-
- public Bitmap ConvertToBitmap(bool flip)
- {
- if (image_data == null || image_data.Length == 0)
- return null;
- Bitmap bitmap;
- switch (m_TextureFormat)
- {
- case TextureFormat.Alpha8:
- case TextureFormat.ARGB4444:
- case TextureFormat.RGB24:
- case TextureFormat.RGBA32:
- case TextureFormat.ARGB32:
- case TextureFormat.R16:
- case TextureFormat.RGBA4444:
- case TextureFormat.BGRA32:
- case TextureFormat.RG16:
- case TextureFormat.R8:
- bitmap = BGRA32ToBitmap();
- break;
- case TextureFormat.RGB565:
- bitmap = RGB565ToBitmap();
- break;
- case TextureFormat.YUY2:
- case TextureFormat.PVRTC_RGB2:
- case TextureFormat.PVRTC_RGBA2:
- case TextureFormat.PVRTC_RGB4:
- case TextureFormat.PVRTC_RGBA4:
- case TextureFormat.ETC_RGB4:
- case TextureFormat.ETC2_RGB:
- case TextureFormat.ETC2_RGBA1:
- case TextureFormat.ETC2_RGBA8:
- case TextureFormat.ASTC_RGB_4x4:
- case TextureFormat.ASTC_RGB_5x5:
- case TextureFormat.ASTC_RGB_6x6:
- case TextureFormat.ASTC_RGB_8x8:
- case TextureFormat.ASTC_RGB_10x10:
- case TextureFormat.ASTC_RGB_12x12:
- case TextureFormat.ASTC_RGBA_4x4:
- case TextureFormat.ASTC_RGBA_5x5:
- case TextureFormat.ASTC_RGBA_6x6:
- case TextureFormat.ASTC_RGBA_8x8:
- case TextureFormat.ASTC_RGBA_10x10:
- case TextureFormat.ASTC_RGBA_12x12:
- case TextureFormat.ETC_RGB4_3DS:
- case TextureFormat.ETC_RGBA8_3DS:
- bitmap = PVRToBitmap(ConvertToPVR());
- break;
- case TextureFormat.DXT1:
- case TextureFormat.DXT5:
- case TextureFormat.RHalf:
- case TextureFormat.RGHalf:
- case TextureFormat.RGBAHalf:
- case TextureFormat.RFloat:
- case TextureFormat.RGFloat:
- case TextureFormat.RGBAFloat:
- case TextureFormat.RGB9e5Float:
- case TextureFormat.ATC_RGB4:
- case TextureFormat.ATC_RGBA8:
- case TextureFormat.EAC_R:
- case TextureFormat.EAC_R_SIGNED:
- case TextureFormat.EAC_RG:
- case TextureFormat.EAC_RG_SIGNED:
- bitmap = TextureConverter();
- break;
- case TextureFormat.BC4:
- case TextureFormat.BC5:
- case TextureFormat.BC6H:
- case TextureFormat.BC7:
- bitmap = Texgenpack();
- break;
- case TextureFormat.DXT1Crunched:
- case TextureFormat.DXT5Crunched:
- DecompressCRN();
- bitmap = TextureConverter();
- break;
- case TextureFormat.ETC_RGB4Crunched:
- case TextureFormat.ETC2_RGBA8Crunched:
- DecompressCRN();
- bitmap = PVRToBitmap(ConvertToPVR());
- break;
- default:
- return null;
- }
- if (bitmap != null && flip)
- bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
- return bitmap;
- }
-
- private Bitmap BGRA32ToBitmap()
- {
- var hObject = GCHandle.Alloc(image_data, GCHandleType.Pinned);
- var pObject = hObject.AddrOfPinnedObject();
- var bitmap = new Bitmap(m_Width, m_Height, m_Width * 4, PixelFormat.Format32bppArgb, pObject);
- hObject.Free();
- return bitmap;
- }
-
- private Bitmap RGB565ToBitmap()
- {
- //stride = m_Width * 2 + m_Width * 2 % 4
- //所以m_Width * 2不为4的倍数时,需要在每行补上相应的像素
- byte[] buff;
- var padding = m_Width * 2 % 4;
- var stride = m_Width * 2 + padding;
- if (padding != 0)
- {
- buff = new byte[stride * m_Height];
- for (int i = 0; i < m_Height; i++)
- {
- Array.Copy(image_data, i * m_Width * 2, buff, i * stride, m_Width * 2);
- }
- }
- else
- {
- buff = image_data;
- }
- var hObject = GCHandle.Alloc(buff, GCHandleType.Pinned);
- var pObject = hObject.AddrOfPinnedObject();
- var bitmap = new Bitmap(m_Width, m_Height, stride, PixelFormat.Format16bppRgb565, pObject);
- hObject.Free();
- return bitmap;
- }
-
- private Bitmap PVRToBitmap(byte[] pvrdata)
- {
- var bitmap = new Bitmap(m_Width, m_Height);
- var rect = new Rectangle(0, 0, m_Width, m_Height);
- var bmd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
- var len = Math.Abs(bmd.Stride) * bmd.Height;
- if (!DecompressPVR(pvrdata, bmd.Scan0, len))
- {
- bitmap.UnlockBits(bmd);
- bitmap.Dispose();
- return null;
- }
- bitmap.UnlockBits(bmd);
- return bitmap;
- }
-
- private Bitmap TextureConverter()
- {
- var bitmap = new Bitmap(m_Width, m_Height);
- var rect = new Rectangle(0, 0, m_Width, m_Height);
- var bmd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
- var len = Math.Abs(bmd.Stride) * bmd.Height;
- var fixAlpha = glBaseInternalFormat == KTXHeader.GL_RED || glBaseInternalFormat == KTXHeader.GL_RG;
- if (!Ponvert(image_data, bmd.Scan0, m_Width, m_Height, image_data_size, (int)q_format, len, fixAlpha))
- {
- bitmap.UnlockBits(bmd);
- bitmap.Dispose();
- return null;
- }
- bitmap.UnlockBits(bmd);
- return bitmap;
- }
-
- private void DecompressCRN()
- {
- IntPtr uncompressedData;
- int uncompressedSize;
- bool result;
- if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
- {
- result = DecompressUnityCRN(image_data, image_data_size, out uncompressedData, out uncompressedSize);
- }
- else
- {
- result = DecompressCRN(image_data, image_data_size, out uncompressedData, out uncompressedSize);
- }
-
- if (result)
- {
- var uncompressedBytes = new byte[uncompressedSize];
- Marshal.Copy(uncompressedData, uncompressedBytes, 0, uncompressedSize);
- Marshal.FreeHGlobal(uncompressedData);
- image_data = uncompressedBytes;
- image_data_size = uncompressedSize;
- }
- }
-
- private Bitmap Texgenpack()
- {
- var bitmap = new Bitmap(m_Width, m_Height);
- var rect = new Rectangle(0, 0, m_Width, m_Height);
- var bmd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
- var fixAlpha = glBaseInternalFormat == KTXHeader.GL_RED || glBaseInternalFormat == KTXHeader.GL_RG;
- texgenpackdecode((int)texturetype, image_data, m_Width, m_Height, bmd.Scan0, fixAlpha);
- bitmap.UnlockBits(bmd);
- return bitmap;
- }
- }
-
- public static class KTXHeader
- {
- public static byte[] IDENTIFIER = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
- public static byte[] ENDIANESS_LE = { 1, 2, 3, 4 };
- public static byte[] ENDIANESS_BE = { 4, 3, 2, 1 };
-
- // constants for glInternalFormat
- public static int GL_ETC1_RGB8_OES = 0x8D64;
-
- public static int GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
- public static int GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01;
- public static int GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
- public static int GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03;
-
- public static int GL_ATC_RGB_AMD = 0x8C92;
- public static int GL_ATC_RGBA_EXPLICIT_ALPHA_AMD = 0x8C93;
- public static int GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD = 0x87EE;
-
- public static int GL_COMPRESSED_RGB8_ETC2 = 0x9274;
- public static int GL_COMPRESSED_SRGB8_ETC2 = 0x9275;
- public static int GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276;
- public static int GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277;
- public static int GL_COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
- public static int GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
- public static int GL_COMPRESSED_R11_EAC = 0x9270;
- public static int GL_COMPRESSED_SIGNED_R11_EAC = 0x9271;
- public static int GL_COMPRESSED_RG11_EAC = 0x9272;
- public static int GL_COMPRESSED_SIGNED_RG11_EAC = 0x9273;
-
- public static int GL_COMPRESSED_RED_RGTC1 = 0x8DBB;
- public static int GL_COMPRESSED_RG_RGTC2 = 0x8DBD;
- public static int GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 0x8E8F;
- public static int GL_COMPRESSED_RGBA_BPTC_UNORM = 0x8E8C;
-
- public static int GL_R16F = 0x822D;
- public static int GL_RG16F = 0x822F;
- public static int GL_RGBA16F = 0x881A;
- public static int GL_R32F = 0x822E;
- public static int GL_RG32F = 0x8230;
- public static int GL_RGBA32F = 0x8814;
-
- // constants for glBaseInternalFormat
- public static int GL_RED = 0x1903;
- public static int GL_GREEN = 0x1904;
- public static int GL_BLUE = 0x1905;
- public static int GL_ALPHA = 0x1906;
- public static int GL_RGB = 0x1907;
- public static int GL_RGBA = 0x1908;
- public static int GL_RG = 0x8227;
- }
-
- //from TextureConverter.h
- public enum QFORMAT
- {
- // General formats
- Q_FORMAT_RGBA_8UI = 1,
- Q_FORMAT_RGBA_8I,
- Q_FORMAT_RGB5_A1UI,
- Q_FORMAT_RGBA_4444,
- Q_FORMAT_RGBA_16UI,
- Q_FORMAT_RGBA_16I,
- Q_FORMAT_RGBA_32UI,
- Q_FORMAT_RGBA_32I,
-
- Q_FORMAT_PALETTE_8_RGBA_8888,
- Q_FORMAT_PALETTE_8_RGBA_5551,
- Q_FORMAT_PALETTE_8_RGBA_4444,
- Q_FORMAT_PALETTE_4_RGBA_8888,
- Q_FORMAT_PALETTE_4_RGBA_5551,
- Q_FORMAT_PALETTE_4_RGBA_4444,
- Q_FORMAT_PALETTE_1_RGBA_8888,
- Q_FORMAT_PALETTE_8_RGB_888,
- Q_FORMAT_PALETTE_8_RGB_565,
- Q_FORMAT_PALETTE_4_RGB_888,
- Q_FORMAT_PALETTE_4_RGB_565,
-
- Q_FORMAT_R2_GBA10UI,
- Q_FORMAT_RGB10_A2UI,
- Q_FORMAT_RGB10_A2I,
- Q_FORMAT_RGBA_F,
- Q_FORMAT_RGBA_HF,
-
- Q_FORMAT_RGB9_E5, // Last five bits are exponent bits (Read following section in GLES3 spec: "3.8.17 Shared Exponent Texture Color Conversion")
- Q_FORMAT_RGB_8UI,
- Q_FORMAT_RGB_8I,
- Q_FORMAT_RGB_565,
- Q_FORMAT_RGB_16UI,
- Q_FORMAT_RGB_16I,
- Q_FORMAT_RGB_32UI,
- Q_FORMAT_RGB_32I,
-
- Q_FORMAT_RGB_F,
- Q_FORMAT_RGB_HF,
- Q_FORMAT_RGB_11_11_10_F,
-
- Q_FORMAT_RG_F,
- Q_FORMAT_RG_HF,
- Q_FORMAT_RG_32UI,
- Q_FORMAT_RG_32I,
- Q_FORMAT_RG_16I,
- Q_FORMAT_RG_16UI,
- Q_FORMAT_RG_8I,
- Q_FORMAT_RG_8UI,
- Q_FORMAT_RG_S88,
-
- Q_FORMAT_R_32UI,
- Q_FORMAT_R_32I,
- Q_FORMAT_R_F,
- Q_FORMAT_R_16F,
- Q_FORMAT_R_16I,
- Q_FORMAT_R_16UI,
- Q_FORMAT_R_8I,
- Q_FORMAT_R_8UI,
-
- Q_FORMAT_LUMINANCE_ALPHA_88,
- Q_FORMAT_LUMINANCE_8,
- Q_FORMAT_ALPHA_8,
-
- Q_FORMAT_LUMINANCE_ALPHA_F,
- Q_FORMAT_LUMINANCE_F,
- Q_FORMAT_ALPHA_F,
- Q_FORMAT_LUMINANCE_ALPHA_HF,
- Q_FORMAT_LUMINANCE_HF,
- Q_FORMAT_ALPHA_HF,
- Q_FORMAT_DEPTH_16,
- Q_FORMAT_DEPTH_24,
- Q_FORMAT_DEPTH_24_STENCIL_8,
- Q_FORMAT_DEPTH_32,
-
- Q_FORMAT_BGR_565,
- Q_FORMAT_BGRA_8888,
- Q_FORMAT_BGRA_5551,
- Q_FORMAT_BGRX_8888,
- Q_FORMAT_BGRA_4444,
- // Compressed formats
- Q_FORMAT_ATITC_RGBA,
- Q_FORMAT_ATC_RGBA_EXPLICIT_ALPHA = Q_FORMAT_ATITC_RGBA,
- Q_FORMAT_ATITC_RGB,
- Q_FORMAT_ATC_RGB = Q_FORMAT_ATITC_RGB,
- Q_FORMAT_ATC_RGBA_INTERPOLATED_ALPHA,
- Q_FORMAT_ETC1_RGB8,
- Q_FORMAT_3DC_X,
- Q_FORMAT_3DC_XY,
-
- Q_FORMAT_ETC2_RGB8,
- Q_FORMAT_ETC2_RGBA8,
- Q_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1,
- Q_FORMAT_ETC2_SRGB8,
- Q_FORMAT_ETC2_SRGB8_ALPHA8,
- Q_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1,
- Q_FORMAT_EAC_R_SIGNED,
- Q_FORMAT_EAC_R_UNSIGNED,
- Q_FORMAT_EAC_RG_SIGNED,
- Q_FORMAT_EAC_RG_UNSIGNED,
-
- Q_FORMAT_S3TC_DXT1_RGB,
- Q_FORMAT_S3TC_DXT1_RGBA,
- Q_FORMAT_S3TC_DXT3_RGBA,
- Q_FORMAT_S3TC_DXT5_RGBA,
-
- // YUV formats
- Q_FORMAT_AYUV_32,
- Q_FORMAT_I444_24,
- Q_FORMAT_YUYV_16,
- Q_FORMAT_UYVY_16,
- Q_FORMAT_I420_12,
- Q_FORMAT_YV12_12,
- Q_FORMAT_NV21_12,
- Q_FORMAT_NV12_12,
-
- // ASTC Format
- Q_FORMAT_ASTC_8,
- Q_FORMAT_ASTC_16,
- };
-
- public enum texgenpack_texturetype
- {
- RGTC1,
- RGTC2,
- BPTC_FLOAT,
- BPTC
- }
-}
diff --git a/AssetStudio/Classes/Texture2D.cs b/AssetStudio/Classes/Texture2D.cs
index d54191e..b165f18 100644
--- a/AssetStudio/Classes/Texture2D.cs
+++ b/AssetStudio/Classes/Texture2D.cs
@@ -8,14 +8,17 @@ using System.Windows.Forms;
namespace AssetStudio
{
- partial class Texture2D
+ class Texture2D
{
+ public AssetPreloadData preloadData;
+
public string m_Name;
public int m_Width;
public int m_Height;
public int m_CompleteImageSize;
public TextureFormat m_TextureFormat;
public bool m_MipMap;
+ public int m_MipCount;
public bool m_IsReadable;
public bool m_ReadAllowed;
public int m_ImageCount;
@@ -35,64 +38,12 @@ namespace AssetStudio
public uint size;
public string path;
- //DDS Start
- private byte[] dwMagic = { 0x44, 0x44, 0x53, 0x20, 0x7c };
- private int dwFlags = 0x1 + 0x2 + 0x4 + 0x1000;
- //public int dwHeight; m_Height
- //public int dwWidth; m_Width
- private int dwPitchOrLinearSize;
- private int dwMipMapCount = 0x1;
- private int dwSize = 0x20;
- private int dwFlags2;
- private int dwFourCC;
- private int dwRGBBitCount;
- private int dwRBitMask;
- private int dwGBitMask;
- private int dwBBitMask;
- private int dwABitMask;
- private int dwCaps = 0x1000;
- private int dwCaps2 = 0x0;
- //DDS End
- //PVR Start
- private int pvrVersion = 0x03525650;
- private int pvrFlags = 0x0;
- private long pvrPixelFormat;
- private int pvrColourSpace = 0x0;
- private int pvrChannelType = 0x0;
- //public int pvrHeight; m_Height
- //public int pvrWidth; m_Width
- private int pvrDepth = 0x1;
- private int pvrNumSurfaces = 0x1; //For texture arrays
- private int pvrNumFaces = 0x1; //For cube maps
- //public int pvrMIPMapCount; dwMipMapCount
- private int pvrMetaDataSize = 0x0;
- //PVR End
- //KTX Start
- private int glType = 0;
- private int glTypeSize = 1;
- private int glFormat = 0;
- private int glInternalFormat;
- private int glBaseInternalFormat;
- //public int pixelWidth; m_Width
- //public int pixelHeight; m_Height
- private int pixelDepth = 0;
- private int numberOfArrayElements = 0;
- private int numberOfFaces = 1;
- private int numberOfMipmapLevels = 1;
- private int bytesOfKeyValueData = 0;
- //KTX End
- //TextureConverter
- private QFORMAT q_format;
- //texgenpack
- private texgenpack_texturetype texturetype;
-
- private int[] version;
-
public Texture2D(AssetPreloadData preloadData, bool readSwitch)
{
+ this.preloadData = preloadData;
var sourceFile = preloadData.sourceFile;
var reader = preloadData.InitReader();
- version = sourceFile.version;
+ var version = sourceFile.version;
if (sourceFile.platform == -2)
{
@@ -114,12 +65,12 @@ namespace AssetStudio
m_TextureFormat = (TextureFormat)reader.ReadInt32();
if (version[0] < 5 || (version[0] == 5 && version[1] < 2))
- { m_MipMap = reader.ReadBoolean(); }
+ {
+ m_MipMap = reader.ReadBoolean();
+ }
else
{
- dwFlags += 0x20000;
- dwMipMapCount = reader.ReadInt32();//is this with or without main image?
- dwCaps += 0x400008;
+ m_MipCount = reader.ReadInt32();
}
m_IsReadable = reader.ReadBoolean(); //2.6.0 and up
@@ -132,27 +83,27 @@ namespace AssetStudio
m_FilterMode = reader.ReadInt32();
m_Aniso = reader.ReadInt32();
m_MipBias = reader.ReadSingle();
- m_WrapMode = reader.ReadInt32();
if (version[0] >= 2017)//2017.x and up
{
+ int m_WrapU = reader.ReadInt32();
int m_WrapV = reader.ReadInt32();
int m_WrapW = reader.ReadInt32();
}
+ else
+ {
+ m_WrapMode = reader.ReadInt32();
+ }
if (version[0] >= 3)
{
m_LightmapFormat = reader.ReadInt32();
- if (version[0] >= 4 || version[1] >= 5) { m_ColorSpace = reader.ReadInt32(); } //3.5.0 and up
+ if (version[0] >= 4 || version[1] >= 5)//3.5.0 and up
+ {
+ m_ColorSpace = reader.ReadInt32();
+ }
}
image_data_size = reader.ReadInt32();
- if (m_MipMap)
- {
- dwFlags += 0x20000;
- dwMipMapCount = Convert.ToInt32(Math.Log(Math.Max(m_Width, m_Height)) / Math.Log(2));
- dwCaps += 0x400008;
- }
-
if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up
{
offset = reader.ReadUInt32();
@@ -200,540 +151,16 @@ namespace AssetStudio
{
image_data = reader.ReadBytes(image_data_size);
}
-
- switch (m_TextureFormat)
- {
- //TODO 导出到DDS容器时应该用原像素还是转换以后的像素?
- case TextureFormat.Alpha8: //test pass
- {
- /*dwFlags2 = 0x2;
- dwRGBBitCount = 0x8;
- dwRBitMask = 0x0;
- dwGBitMask = 0x0;
- dwBBitMask = 0x0;
- dwABitMask = 0xFF; */
-
- //转BGRA32
- var BGRA32 = Enumerable.Repeat(0xFF, image_data_size * 4).ToArray();
- for (var i = 0; i < image_data_size; i++)
- {
- BGRA32[i * 4 + 3] = image_data[i];
- }
- SetBGRA32Info(BGRA32);
- break;
- }
- case TextureFormat.ARGB4444: //test pass
- {
- SwapBytesForXbox(sourceFile.platform);
-
- /*dwFlags2 = 0x41;
- dwRGBBitCount = 0x10;
- dwRBitMask = 0xF00;
- dwGBitMask = 0xF0;
- dwBBitMask = 0xF;
- dwABitMask = 0xF000;*/
-
- //转BGRA32
- var BGRA32 = new byte[image_data_size * 2];
- for (var i = 0; i < image_data_size / 2; i++)
- {
- var pixelNew = new byte[4];
- var pixelOldShort = BitConverter.ToUInt16(image_data, i * 2);
- pixelNew[0] = (byte)(pixelOldShort & 0x000f);
- pixelNew[1] = (byte)((pixelOldShort & 0x00f0) >> 4);
- pixelNew[2] = (byte)((pixelOldShort & 0x0f00) >> 8);
- pixelNew[3] = (byte)((pixelOldShort & 0xf000) >> 12);
- // convert range
- for (var j = 0; j < 4; j++)
- pixelNew[j] = (byte)((pixelNew[j] << 4) | pixelNew[j]);
- pixelNew.CopyTo(BGRA32, i * 4);
- }
- SetBGRA32Info(BGRA32);
- break;
- }
- case TextureFormat.RGB24: //test pass
- {
- /*dwFlags2 = 0x40;
- dwRGBBitCount = 0x18;
- dwRBitMask = 0xFF;
- dwGBitMask = 0xFF00;
- dwBBitMask = 0xFF0000;
- dwABitMask = 0x0;*/
-
- //转BGRA32
- var BGRA32 = new byte[image_data_size / 3 * 4];
- for (var i = 0; i < image_data_size / 3; i++)
- {
- BGRA32[i * 4] = image_data[i * 3 + 2];
- BGRA32[i * 4 + 1] = image_data[i * 3 + 1];
- BGRA32[i * 4 + 2] = image_data[i * 3 + 0];
- BGRA32[i * 4 + 3] = 255;
- }
- SetBGRA32Info(BGRA32);
- break;
- }
- case TextureFormat.RGBA32: //test pass
- {
- /*dwFlags2 = 0x41;
- dwRGBBitCount = 0x20;
- dwRBitMask = 0xFF;
- dwGBitMask = 0xFF00;
- dwBBitMask = 0xFF0000;
- dwABitMask = -16777216;*/
-
- //转BGRA32
- var BGRA32 = new byte[image_data_size];
- for (var i = 0; i < image_data_size; i += 4)
- {
- BGRA32[i] = image_data[i + 2];
- BGRA32[i + 1] = image_data[i + 1];
- BGRA32[i + 2] = image_data[i + 0];
- BGRA32[i + 3] = image_data[i + 3];
- }
- SetBGRA32Info(BGRA32);
- break;
- }
- case TextureFormat.ARGB32://test pass
- {
- /*dwFlags2 = 0x41;
- dwRGBBitCount = 0x20;
- dwRBitMask = 0xFF00;
- dwGBitMask = 0xFF0000;
- dwBBitMask = -16777216;
- dwABitMask = 0xFF;*/
-
- //转BGRA32
- var BGRA32 = new byte[image_data_size];
- for (var i = 0; i < image_data_size; i += 4)
- {
- BGRA32[i] = image_data[i + 3];
- BGRA32[i + 1] = image_data[i + 2];
- BGRA32[i + 2] = image_data[i + 1];
- BGRA32[i + 3] = image_data[i + 0];
- }
- SetBGRA32Info(BGRA32);
- break;
- }
- case TextureFormat.RGB565: //test pass
- {
- SwapBytesForXbox(sourceFile.platform);
-
- dwFlags2 = 0x40;
- dwRGBBitCount = 0x10;
- dwRBitMask = 0xF800;
- dwGBitMask = 0x7E0;
- dwBBitMask = 0x1F;
- dwABitMask = 0x0;
- break;
- }
- case TextureFormat.R16: //test pass
- {
- //转BGRA32
- var BGRA32 = new byte[image_data_size * 2];
- for (var i = 0; i < image_data_size; i += 2)
- {
- float f = Half.ToHalf(image_data, i);
- BGRA32[i * 2 + 2] = (byte)Math.Ceiling(f * 255);//R
- BGRA32[i * 2 + 3] = 255;//A
- }
- SetBGRA32Info(BGRA32);
- break;
- }
- case TextureFormat.DXT1: //test pass
- case TextureFormat.DXT1Crunched: //test pass
- {
- SwapBytesForXbox(sourceFile.platform);
-
- if (m_MipMap) { dwPitchOrLinearSize = m_Height * m_Width / 2; }
- dwFlags2 = 0x4;
- dwFourCC = 0x31545844;
- dwRGBBitCount = 0x0;
- dwRBitMask = 0x0;
- dwGBitMask = 0x0;
- dwBBitMask = 0x0;
- dwABitMask = 0x0;
-
- q_format = QFORMAT.Q_FORMAT_S3TC_DXT1_RGB;
- break;
- }
- case TextureFormat.DXT5: //test pass
- case TextureFormat.DXT5Crunched: //test pass
- {
- SwapBytesForXbox(sourceFile.platform);
-
- if (m_MipMap) { dwPitchOrLinearSize = m_Height * m_Width / 2; }
- dwFlags2 = 0x4;
- dwFourCC = 0x35545844;
- dwRGBBitCount = 0x0;
- dwRBitMask = 0x0;
- dwGBitMask = 0x0;
- dwBBitMask = 0x0;
- dwABitMask = 0x0;
-
- q_format = QFORMAT.Q_FORMAT_S3TC_DXT5_RGBA;
- break;
- }
- case TextureFormat.RGBA4444: //test pass
- {
- /*dwFlags2 = 0x41;
- dwRGBBitCount = 0x10;
- dwRBitMask = 0xF000;
- dwGBitMask = 0xF00;
- dwBBitMask = 0xF0;
- dwABitMask = 0xF;*/
-
- //转BGRA32
- var BGRA32 = new byte[image_data_size * 2];
- for (var i = 0; i < image_data_size / 2; i++)
- {
- var pixelNew = new byte[4];
- var pixelOldShort = BitConverter.ToUInt16(image_data, i * 2);
- pixelNew[0] = (byte)((pixelOldShort & 0x00f0) >> 4);
- pixelNew[1] = (byte)((pixelOldShort & 0x0f00) >> 8);
- pixelNew[2] = (byte)((pixelOldShort & 0xf000) >> 12);
- pixelNew[3] = (byte)(pixelOldShort & 0x000f);
- // convert range
- for (var j = 0; j < 4; j++)
- pixelNew[j] = (byte)((pixelNew[j] << 4) | pixelNew[j]);
- pixelNew.CopyTo(BGRA32, i * 4);
- }
- SetBGRA32Info(BGRA32);
- break;
- }
- case TextureFormat.BGRA32: //test pass
- {
- dwFlags2 = 0x41;
- dwRGBBitCount = 0x20;
- dwRBitMask = 0xFF0000;
- dwGBitMask = 0xFF00;
- dwBBitMask = 0xFF;
- dwABitMask = -16777216;
- break;
- }
- case TextureFormat.RHalf: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_R_16F;
- glInternalFormat = KTXHeader.GL_R16F;
- glBaseInternalFormat = KTXHeader.GL_RED;
- break;
- }
- case TextureFormat.RGHalf: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_RG_HF;
- glInternalFormat = KTXHeader.GL_RG16F;
- glBaseInternalFormat = KTXHeader.GL_RG;
- break;
- }
- case TextureFormat.RGBAHalf: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_RGBA_HF;
- glInternalFormat = KTXHeader.GL_RGBA16F;
- glBaseInternalFormat = KTXHeader.GL_RGBA;
- break;
- }
- case TextureFormat.RFloat: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_R_F;
- glInternalFormat = KTXHeader.GL_R32F;
- glBaseInternalFormat = KTXHeader.GL_RED;
- break;
- }
- case TextureFormat.RGFloat: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_RG_F;
- glInternalFormat = KTXHeader.GL_RG32F;
- glBaseInternalFormat = KTXHeader.GL_RG;
- break;
- }
- case TextureFormat.RGBAFloat: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_RGBA_F;
- glInternalFormat = KTXHeader.GL_RGBA32F;
- glBaseInternalFormat = KTXHeader.GL_RGBA;
- break;
- }
- case TextureFormat.YUY2: //test pass
- {
- pvrPixelFormat = 17;
- break;
- }
- case TextureFormat.RGB9e5Float:
- {
- q_format = QFORMAT.Q_FORMAT_RGB9_E5;
- break;
- }
- case TextureFormat.BC4: //test pass
- {
- texturetype = texgenpack_texturetype.RGTC1;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RED_RGTC1;
- glBaseInternalFormat = KTXHeader.GL_RED;
- break;
- }
- case TextureFormat.BC5: //test pass
- {
- texturetype = texgenpack_texturetype.RGTC2;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RG_RGTC2;
- glBaseInternalFormat = KTXHeader.GL_RG;
- break;
- }
- case TextureFormat.BC6H: //test pass
- {
- texturetype = texgenpack_texturetype.BPTC_FLOAT;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
- glBaseInternalFormat = KTXHeader.GL_RGB;
- break;
- }
- case TextureFormat.BC7: //test pass
- {
- texturetype = texgenpack_texturetype.BPTC;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RGBA_BPTC_UNORM;
- glBaseInternalFormat = KTXHeader.GL_RGBA;
- break;
- }
- case TextureFormat.PVRTC_RGB2: //test pass
- {
- pvrPixelFormat = 0;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
- glBaseInternalFormat = KTXHeader.GL_RGB;
- break;
- }
- case TextureFormat.PVRTC_RGBA2: //test pass
- {
- pvrPixelFormat = 1;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
- glBaseInternalFormat = KTXHeader.GL_RGBA;
- break;
- }
- case TextureFormat.PVRTC_RGB4: //test pass
- {
- pvrPixelFormat = 2;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
- glBaseInternalFormat = KTXHeader.GL_RGB;
- break;
- }
- case TextureFormat.PVRTC_RGBA4: //test pass
- {
- pvrPixelFormat = 3;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
- glBaseInternalFormat = KTXHeader.GL_RGBA;
- break;
- }
- case TextureFormat.ETC_RGB4Crunched:
- case TextureFormat.ETC_RGB4_3DS: //test pass
- case TextureFormat.ETC_RGB4: //test pass
- {
- pvrPixelFormat = 6;
- glInternalFormat = KTXHeader.GL_ETC1_RGB8_OES;
- glBaseInternalFormat = KTXHeader.GL_RGB;
- break;
- }
- case TextureFormat.ATC_RGB4: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_ATITC_RGB;
- glInternalFormat = KTXHeader.GL_ATC_RGB_AMD;
- glBaseInternalFormat = KTXHeader.GL_RGB;
- break;
- }
- case TextureFormat.ATC_RGBA8: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_ATC_RGBA_INTERPOLATED_ALPHA;
- glInternalFormat = KTXHeader.GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
- glBaseInternalFormat = KTXHeader.GL_RGBA;
- break;
- }
- case TextureFormat.EAC_R: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_EAC_R_UNSIGNED;
- glInternalFormat = KTXHeader.GL_COMPRESSED_R11_EAC;
- glBaseInternalFormat = KTXHeader.GL_RED;
- break;
- }
- case TextureFormat.EAC_R_SIGNED: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_EAC_R_SIGNED;
- glInternalFormat = KTXHeader.GL_COMPRESSED_SIGNED_R11_EAC;
- glBaseInternalFormat = KTXHeader.GL_RED;
- break;
- }
- case TextureFormat.EAC_RG: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_EAC_RG_UNSIGNED;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RG11_EAC;
- glBaseInternalFormat = KTXHeader.GL_RG;
- break;
- }
- case TextureFormat.EAC_RG_SIGNED: //test pass
- {
- q_format = QFORMAT.Q_FORMAT_EAC_RG_SIGNED;
- glInternalFormat = KTXHeader.GL_COMPRESSED_SIGNED_RG11_EAC;
- glBaseInternalFormat = KTXHeader.GL_RG;
- break;
- }
- case TextureFormat.ETC2_RGB: //test pass
- {
- pvrPixelFormat = 22;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RGB8_ETC2;
- glBaseInternalFormat = KTXHeader.GL_RGB;
- break;
- }
- case TextureFormat.ETC2_RGBA1: //test pass
- {
- pvrPixelFormat = 24;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
- glBaseInternalFormat = KTXHeader.GL_RGBA;
- break;
- }
- case TextureFormat.ETC2_RGBA8Crunched:
- case TextureFormat.ETC_RGBA8_3DS: //test pass
- case TextureFormat.ETC2_RGBA8: //test pass
- {
- pvrPixelFormat = 23;
- glInternalFormat = KTXHeader.GL_COMPRESSED_RGBA8_ETC2_EAC;
- glBaseInternalFormat = KTXHeader.GL_RGBA;
- break;
- }
- case TextureFormat.ASTC_RGB_4x4: //test pass
- case TextureFormat.ASTC_RGBA_4x4: //test pass
- {
- pvrPixelFormat = 27;
- break;
- }
- case TextureFormat.ASTC_RGB_5x5: //test pass
- case TextureFormat.ASTC_RGBA_5x5: //test pass
- {
- pvrPixelFormat = 29;
- break;
- }
- case TextureFormat.ASTC_RGB_6x6: //test pass
- case TextureFormat.ASTC_RGBA_6x6: //test pass
- {
- pvrPixelFormat = 31;
- break;
- }
- case TextureFormat.ASTC_RGB_8x8: //test pass
- case TextureFormat.ASTC_RGBA_8x8: //test pass
- {
- pvrPixelFormat = 34;
- break;
- }
- case TextureFormat.ASTC_RGB_10x10: //test pass
- case TextureFormat.ASTC_RGBA_10x10: //test pass
- {
- pvrPixelFormat = 38;
- break;
- }
- case TextureFormat.ASTC_RGB_12x12: //test pass
- case TextureFormat.ASTC_RGBA_12x12: //test pass
- {
- pvrPixelFormat = 40;
- break;
- }
- case TextureFormat.RG16: //test pass
- {
- //转BGRA32
- var BGRA32 = new byte[image_data_size * 2];
- for (var i = 0; i < image_data_size; i += 2)
- {
- BGRA32[i * 2 + 1] = image_data[i + 1];//G
- BGRA32[i * 2 + 2] = image_data[i];//R
- BGRA32[i * 2 + 3] = 255;//A
- }
- SetBGRA32Info(BGRA32);
- break;
- }
- case TextureFormat.R8: //test pass
- {
- //转BGRA32
- var BGRA32 = new byte[image_data_size * 4];
- for (var i = 0; i < image_data_size; i++)
- {
- BGRA32[i * 4 + 2] = image_data[i];//R
- BGRA32[i * 4 + 3] = 255;//A
- }
- SetBGRA32Info(BGRA32);
- break;
- }
- }
}
else
{
- preloadData.InfoText = $"Width: {m_Width}\nHeight: {m_Height}\nFormat: ";
-
- string type = m_TextureFormat.ToString();
- preloadData.InfoText += type;
-
- switch (m_TextureFormat)
- {
- case TextureFormat.Alpha8:
- case TextureFormat.ARGB4444:
- case TextureFormat.RGB24:
- case TextureFormat.RGBA32:
- case TextureFormat.ARGB32:
- case TextureFormat.RGB565:
- case TextureFormat.R16:
- case TextureFormat.DXT1:
- case TextureFormat.DXT5:
- case TextureFormat.RGBA4444:
- case TextureFormat.BGRA32:
- case TextureFormat.RG16:
- case TextureFormat.R8:
- preloadData.extension = ".dds"; break;
- case TextureFormat.DXT1Crunched:
- case TextureFormat.DXT5Crunched:
- case TextureFormat.ETC_RGB4Crunched:
- case TextureFormat.ETC2_RGBA8Crunched:
- preloadData.extension = ".crn"; break;
- case TextureFormat.YUY2:
- case TextureFormat.PVRTC_RGB2:
- case TextureFormat.PVRTC_RGBA2:
- case TextureFormat.PVRTC_RGB4:
- case TextureFormat.PVRTC_RGBA4:
- case TextureFormat.ETC_RGB4:
- case TextureFormat.ETC2_RGB:
- case TextureFormat.ETC2_RGBA1:
- case TextureFormat.ETC2_RGBA8:
- case TextureFormat.ASTC_RGB_4x4:
- case TextureFormat.ASTC_RGB_5x5:
- case TextureFormat.ASTC_RGB_6x6:
- case TextureFormat.ASTC_RGB_8x8:
- case TextureFormat.ASTC_RGB_10x10:
- case TextureFormat.ASTC_RGB_12x12:
- case TextureFormat.ASTC_RGBA_4x4:
- case TextureFormat.ASTC_RGBA_5x5:
- case TextureFormat.ASTC_RGBA_6x6:
- case TextureFormat.ASTC_RGBA_8x8:
- case TextureFormat.ASTC_RGBA_10x10:
- case TextureFormat.ASTC_RGBA_12x12:
- case TextureFormat.ETC_RGB4_3DS:
- case TextureFormat.ETC_RGBA8_3DS:
- preloadData.extension = ".pvr"; break;
- case TextureFormat.RHalf:
- case TextureFormat.RGHalf:
- case TextureFormat.RGBAHalf:
- case TextureFormat.RFloat:
- case TextureFormat.RGFloat:
- case TextureFormat.RGBAFloat:
- case TextureFormat.BC4:
- case TextureFormat.BC5:
- case TextureFormat.BC6H:
- case TextureFormat.BC7:
- case TextureFormat.ATC_RGB4:
- case TextureFormat.ATC_RGBA8:
- case TextureFormat.EAC_R:
- case TextureFormat.EAC_R_SIGNED:
- case TextureFormat.EAC_RG:
- case TextureFormat.EAC_RG_SIGNED:
- preloadData.extension = ".ktx"; break;
- default:
- preloadData.extension = ".tex"; break;
- }
+ preloadData.InfoText = $"Width: {m_Width}\nHeight: {m_Height}\nFormat: {m_TextureFormat}";
switch (m_FilterMode)
{
case 0: preloadData.InfoText += "\nFilter Mode: Point "; break;
case 1: preloadData.InfoText += "\nFilter Mode: Bilinear "; break;
case 2: preloadData.InfoText += "\nFilter Mode: Trilinear "; break;
-
}
preloadData.InfoText += $"\nAnisotropic level: {m_Aniso}\nMip map bias: {m_MipBias}";
@@ -749,31 +176,6 @@ namespace AssetStudio
preloadData.fullSize = preloadData.Size + (int)size;
}
}
-
- private void SwapBytesForXbox(int platform)
- {
- if (platform == 11) //swap bytes for Xbox confirmed, PS3 not encountered
- {
- for (var i = 0; i < image_data_size / 2; i++)
- {
- var b0 = image_data[i * 2];
- image_data[i * 2] = image_data[i * 2 + 1];
- image_data[i * 2 + 1] = b0;
- }
- }
- }
-
- private void SetBGRA32Info(byte[] BGRA32)
- {
- image_data = BGRA32;
- image_data_size = BGRA32.Length;
- dwFlags2 = 0x41;
- dwRGBBitCount = 0x20;
- dwRBitMask = 0xFF0000;
- dwGBitMask = 0xFF00;
- dwBBitMask = 0xFF;
- dwABitMask = -16777216;
- }
}
public enum TextureFormat
diff --git a/AssetStudio/StudioClasses/Exporter.cs b/AssetStudio/StudioClasses/Exporter.cs
index 9166589..dbbc777 100644
--- a/AssetStudio/StudioClasses/Exporter.cs
+++ b/AssetStudio/StudioClasses/Exporter.cs
@@ -13,7 +13,7 @@ namespace AssetStudio
{
public static bool ExportTexture2D(AssetPreloadData asset, string exportPathName, bool flip)
{
- var m_Texture2D = new Texture2D(asset, true);
+ var m_Texture2D = new Texture2DConverter(new Texture2D(asset, true));
if (m_Texture2D.image_data == null)
return false;
var convert = (bool)Properties.Settings.Default["convertTexture"];
@@ -41,15 +41,14 @@ namespace AssetStudio
bitmap.Dispose();
return true;
}
- if (!convert)
+ else
{
- var exportFullName = exportPathName + asset.Text + asset.extension;
+ var exportFullName = exportPathName + asset.Text + m_Texture2D.GetExtensionName();
if (ExportFileExists(exportFullName))
return false;
File.WriteAllBytes(exportFullName, m_Texture2D.ConvertToContainer());
return true;
}
- return false;
}
public static bool ExportAudioClip(AssetPreloadData asset, string exportPath)
diff --git a/AssetStudio/StudioClasses/ModelConverter.cs b/AssetStudio/StudioClasses/ModelConverter.cs
index 7a751b3..cb2ebae 100644
--- a/AssetStudio/StudioClasses/ModelConverter.cs
+++ b/AssetStudio/StudioClasses/ModelConverter.cs
@@ -568,7 +568,7 @@ namespace AssetStudio
using (var memStream = new MemoryStream())
{
- var bitmap = tex2D.ConvertToBitmap(true);
+ var bitmap = new Texture2DConverter(tex2D).ConvertToBitmap(true);
if (bitmap != null)
{
bitmap.Save(memStream, ImageFormat.Png);
diff --git a/AssetStudio/StudioClasses/SpriteHelper.cs b/AssetStudio/StudioClasses/SpriteHelper.cs
index 726e982..4d2c646 100644
--- a/AssetStudio/StudioClasses/SpriteHelper.cs
+++ b/AssetStudio/StudioClasses/SpriteHelper.cs
@@ -40,7 +40,7 @@ namespace AssetStudio
private static Bitmap CutImage(AssetPreloadData asset, AssetPreloadData texture2DAsset, RectangleF textureRect)
{
- var texture2D = new Texture2D(texture2DAsset, true);
+ var texture2D = new Texture2DConverter(new Texture2D(texture2DAsset, true));
using (var originalImage = texture2D.ConvertToBitmap(false))
{
if (originalImage != null)
@@ -61,7 +61,7 @@ namespace AssetStudio
private static Bitmap CutImage(AssetPreloadData asset, AssetPreloadData texture2DAsset, RectangleF textureRect, Sprite sprite)
{
- var texture2D = new Texture2D(texture2DAsset, true);
+ var texture2D = new Texture2DConverter(new Texture2D(texture2DAsset, true));
using (var originalImage = texture2D.ConvertToBitmap(false))
{
if (originalImage != null)
diff --git a/AssetStudio/StudioClasses/Texture2DConverter.cs b/AssetStudio/StudioClasses/Texture2DConverter.cs
new file mode 100644
index 0000000..d367cd6
--- /dev/null
+++ b/AssetStudio/StudioClasses/Texture2DConverter.cs
@@ -0,0 +1,1175 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace AssetStudio
+{
+ class Texture2DConverter
+ {
+ //Texture2D
+ private int m_Width;
+ private int m_Height;
+ private TextureFormat m_TextureFormat;
+ private int image_data_size;
+ public byte[] image_data;
+ private int[] version;
+
+ //DDS Start
+ private byte[] dwMagic = { 0x44, 0x44, 0x53, 0x20, 0x7c };
+ private int dwFlags = 0x1 + 0x2 + 0x4 + 0x1000;
+ //public int dwHeight; m_Height
+ //public int dwWidth; m_Width
+ private int dwPitchOrLinearSize;
+ private int dwMipMapCount = 0x1;
+ private int dwSize = 0x20;
+ private int dwFlags2;
+ private int dwFourCC;
+ private int dwRGBBitCount;
+ private int dwRBitMask;
+ private int dwGBitMask;
+ private int dwBBitMask;
+ private int dwABitMask;
+ private int dwCaps = 0x1000;
+ private int dwCaps2 = 0x0;
+ //DDS End
+ //PVR Start
+ private int pvrVersion = 0x03525650;
+ private int pvrFlags = 0x0;
+ private long pvrPixelFormat;
+ private int pvrColourSpace = 0x0;
+ private int pvrChannelType = 0x0;
+ //public int pvrHeight; m_Height
+ //public int pvrWidth; m_Width
+ private int pvrDepth = 0x1;
+ private int pvrNumSurfaces = 0x1; //For texture arrays
+ private int pvrNumFaces = 0x1; //For cube maps
+ //public int pvrMIPMapCount; dwMipMapCount
+ private int pvrMetaDataSize = 0x0;
+ //PVR End
+ //KTX Start
+ private int glType = 0;
+ private int glTypeSize = 1;
+ private int glFormat = 0;
+ private int glInternalFormat;
+ private int glBaseInternalFormat;
+ //public int pixelWidth; m_Width
+ //public int pixelHeight; m_Height
+ private int pixelDepth = 0;
+ private int numberOfArrayElements = 0;
+ private int numberOfFaces = 1;
+ private int numberOfMipmapLevels = 1;
+ private int bytesOfKeyValueData = 0;
+ //KTX End
+ //TextureConverter
+ private QFORMAT q_format;
+ //texgenpack
+ private texgenpack_texturetype texturetype;
+
+ [DllImport("PVRTexLibWrapper.dll", CallingConvention = CallingConvention.Cdecl)]
+ private static extern bool DecompressPVR(byte[] buffer, IntPtr bmp, int len);
+
+ [DllImport("TextureConverterWrapper.dll", CallingConvention = CallingConvention.Cdecl)]
+ private static extern bool Ponvert(byte[] buffer, IntPtr bmp, int nWidth, int nHeight, int len, int type, int bmpsize, bool fixAlpha);
+
+ [DllImport("crunch.dll", CallingConvention = CallingConvention.Cdecl)]
+ private static extern bool DecompressCRN(byte[] pSrc_file_data, int src_file_size, out IntPtr uncompressedData, out int uncompressedSize);
+
+ [DllImport("crunchunity.dll", CallingConvention = CallingConvention.Cdecl)]
+ private static extern bool DecompressUnityCRN(byte[] pSrc_file_data, int src_file_size, out IntPtr uncompressedData, out int uncompressedSize);
+
+ [DllImport("texgenpack.dll", CallingConvention = CallingConvention.Cdecl)]
+ private static extern void texgenpackdecode(int texturetype, byte[] texturedata, int width, int height, IntPtr bmp, bool fixAlpha);
+
+
+ public Texture2DConverter(Texture2D m_Texture2D)
+ {
+ image_data_size = m_Texture2D.image_data_size;
+ image_data = m_Texture2D.image_data;
+ m_Width = m_Texture2D.m_Width;
+ m_Height = m_Texture2D.m_Height;
+ m_TextureFormat = m_Texture2D.m_TextureFormat;
+ var mMipMap = m_Texture2D.m_MipMap;
+ version = m_Texture2D.preloadData.sourceFile.version;
+ var platform = m_Texture2D.preloadData.sourceFile.platform;
+
+ if (version[0] < 5 || (version[0] == 5 && version[1] < 2))//5.2 down
+ {
+ if (mMipMap)
+ {
+ dwFlags += 0x20000;
+ dwMipMapCount = Convert.ToInt32(Math.Log(Math.Max(m_Width, m_Height)) / Math.Log(2));
+ dwCaps += 0x400008;
+ }
+ }
+ else
+ {
+ dwFlags += 0x20000;
+ dwMipMapCount = m_Texture2D.m_MipCount;
+ dwCaps += 0x400008;
+ }
+
+
+ switch (m_TextureFormat)
+ {
+ //TODO 导出到DDS容器时应该用原像素还是转换以后的像素?
+ case TextureFormat.Alpha8: //test pass
+ {
+ /*dwFlags2 = 0x2;
+ dwRGBBitCount = 0x8;
+ dwRBitMask = 0x0;
+ dwGBitMask = 0x0;
+ dwBBitMask = 0x0;
+ dwABitMask = 0xFF; */
+
+ //转BGRA32
+ var BGRA32 = Enumerable.Repeat(0xFF, image_data_size * 4).ToArray();
+ for (var i = 0; i < image_data_size; i++)
+ {
+ BGRA32[i * 4 + 3] = image_data[i];
+ }
+ SetBGRA32Info(BGRA32);
+ break;
+ }
+ case TextureFormat.ARGB4444: //test pass
+ {
+ SwapBytesForXbox(platform);
+
+ /*dwFlags2 = 0x41;
+ dwRGBBitCount = 0x10;
+ dwRBitMask = 0xF00;
+ dwGBitMask = 0xF0;
+ dwBBitMask = 0xF;
+ dwABitMask = 0xF000;*/
+
+ //转BGRA32
+ var BGRA32 = new byte[image_data_size * 2];
+ for (var i = 0; i < image_data_size / 2; i++)
+ {
+ var pixelNew = new byte[4];
+ var pixelOldShort = BitConverter.ToUInt16(image_data, i * 2);
+ pixelNew[0] = (byte)(pixelOldShort & 0x000f);
+ pixelNew[1] = (byte)((pixelOldShort & 0x00f0) >> 4);
+ pixelNew[2] = (byte)((pixelOldShort & 0x0f00) >> 8);
+ pixelNew[3] = (byte)((pixelOldShort & 0xf000) >> 12);
+ // convert range
+ for (var j = 0; j < 4; j++)
+ pixelNew[j] = (byte)((pixelNew[j] << 4) | pixelNew[j]);
+ pixelNew.CopyTo(BGRA32, i * 4);
+ }
+ SetBGRA32Info(BGRA32);
+ break;
+ }
+ case TextureFormat.RGB24: //test pass
+ {
+ /*dwFlags2 = 0x40;
+ dwRGBBitCount = 0x18;
+ dwRBitMask = 0xFF;
+ dwGBitMask = 0xFF00;
+ dwBBitMask = 0xFF0000;
+ dwABitMask = 0x0;*/
+
+ //转BGRA32
+ var BGRA32 = new byte[image_data_size / 3 * 4];
+ for (var i = 0; i < image_data_size / 3; i++)
+ {
+ BGRA32[i * 4] = image_data[i * 3 + 2];
+ BGRA32[i * 4 + 1] = image_data[i * 3 + 1];
+ BGRA32[i * 4 + 2] = image_data[i * 3 + 0];
+ BGRA32[i * 4 + 3] = 255;
+ }
+ SetBGRA32Info(BGRA32);
+ break;
+ }
+ case TextureFormat.RGBA32: //test pass
+ {
+ /*dwFlags2 = 0x41;
+ dwRGBBitCount = 0x20;
+ dwRBitMask = 0xFF;
+ dwGBitMask = 0xFF00;
+ dwBBitMask = 0xFF0000;
+ dwABitMask = -16777216;*/
+
+ //转BGRA32
+ var BGRA32 = new byte[image_data_size];
+ for (var i = 0; i < image_data_size; i += 4)
+ {
+ BGRA32[i] = image_data[i + 2];
+ BGRA32[i + 1] = image_data[i + 1];
+ BGRA32[i + 2] = image_data[i + 0];
+ BGRA32[i + 3] = image_data[i + 3];
+ }
+ SetBGRA32Info(BGRA32);
+ break;
+ }
+ case TextureFormat.ARGB32://test pass
+ {
+ /*dwFlags2 = 0x41;
+ dwRGBBitCount = 0x20;
+ dwRBitMask = 0xFF00;
+ dwGBitMask = 0xFF0000;
+ dwBBitMask = -16777216;
+ dwABitMask = 0xFF;*/
+
+ //转BGRA32
+ var BGRA32 = new byte[image_data_size];
+ for (var i = 0; i < image_data_size; i += 4)
+ {
+ BGRA32[i] = image_data[i + 3];
+ BGRA32[i + 1] = image_data[i + 2];
+ BGRA32[i + 2] = image_data[i + 1];
+ BGRA32[i + 3] = image_data[i + 0];
+ }
+ SetBGRA32Info(BGRA32);
+ break;
+ }
+ case TextureFormat.RGB565: //test pass
+ {
+ SwapBytesForXbox(platform);
+
+ dwFlags2 = 0x40;
+ dwRGBBitCount = 0x10;
+ dwRBitMask = 0xF800;
+ dwGBitMask = 0x7E0;
+ dwBBitMask = 0x1F;
+ dwABitMask = 0x0;
+ break;
+ }
+ case TextureFormat.R16: //test pass
+ {
+ //转BGRA32
+ var BGRA32 = new byte[image_data_size * 2];
+ for (var i = 0; i < image_data_size; i += 2)
+ {
+ float f = Half.ToHalf(image_data, i);
+ BGRA32[i * 2 + 2] = (byte)Math.Ceiling(f * 255);//R
+ BGRA32[i * 2 + 3] = 255;//A
+ }
+ SetBGRA32Info(BGRA32);
+ break;
+ }
+ case TextureFormat.DXT1: //test pass
+ case TextureFormat.DXT1Crunched: //test pass
+ {
+ SwapBytesForXbox(platform);
+
+ if (mMipMap)
+ {
+ dwPitchOrLinearSize = m_Height * m_Width / 2;
+ }
+ dwFlags2 = 0x4;
+ dwFourCC = 0x31545844;
+ dwRGBBitCount = 0x0;
+ dwRBitMask = 0x0;
+ dwGBitMask = 0x0;
+ dwBBitMask = 0x0;
+ dwABitMask = 0x0;
+
+ q_format = QFORMAT.Q_FORMAT_S3TC_DXT1_RGB;
+ break;
+ }
+ case TextureFormat.DXT5: //test pass
+ case TextureFormat.DXT5Crunched: //test pass
+ {
+ SwapBytesForXbox(platform);
+
+ if (mMipMap)
+ {
+ dwPitchOrLinearSize = m_Height * m_Width / 2;
+ }
+ dwFlags2 = 0x4;
+ dwFourCC = 0x35545844;
+ dwRGBBitCount = 0x0;
+ dwRBitMask = 0x0;
+ dwGBitMask = 0x0;
+ dwBBitMask = 0x0;
+ dwABitMask = 0x0;
+
+ q_format = QFORMAT.Q_FORMAT_S3TC_DXT5_RGBA;
+ break;
+ }
+ case TextureFormat.RGBA4444: //test pass
+ {
+ /*dwFlags2 = 0x41;
+ dwRGBBitCount = 0x10;
+ dwRBitMask = 0xF000;
+ dwGBitMask = 0xF00;
+ dwBBitMask = 0xF0;
+ dwABitMask = 0xF;*/
+
+ //转BGRA32
+ var BGRA32 = new byte[image_data_size * 2];
+ for (var i = 0; i < image_data_size / 2; i++)
+ {
+ var pixelNew = new byte[4];
+ var pixelOldShort = BitConverter.ToUInt16(image_data, i * 2);
+ pixelNew[0] = (byte)((pixelOldShort & 0x00f0) >> 4);
+ pixelNew[1] = (byte)((pixelOldShort & 0x0f00) >> 8);
+ pixelNew[2] = (byte)((pixelOldShort & 0xf000) >> 12);
+ pixelNew[3] = (byte)(pixelOldShort & 0x000f);
+ // convert range
+ for (var j = 0; j < 4; j++)
+ pixelNew[j] = (byte)((pixelNew[j] << 4) | pixelNew[j]);
+ pixelNew.CopyTo(BGRA32, i * 4);
+ }
+ SetBGRA32Info(BGRA32);
+ break;
+ }
+ case TextureFormat.BGRA32: //test pass
+ {
+ dwFlags2 = 0x41;
+ dwRGBBitCount = 0x20;
+ dwRBitMask = 0xFF0000;
+ dwGBitMask = 0xFF00;
+ dwBBitMask = 0xFF;
+ dwABitMask = -16777216;
+ break;
+ }
+ case TextureFormat.RHalf: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_R_16F;
+ glInternalFormat = KTXHeader.GL_R16F;
+ glBaseInternalFormat = KTXHeader.GL_RED;
+ break;
+ }
+ case TextureFormat.RGHalf: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_RG_HF;
+ glInternalFormat = KTXHeader.GL_RG16F;
+ glBaseInternalFormat = KTXHeader.GL_RG;
+ break;
+ }
+ case TextureFormat.RGBAHalf: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_RGBA_HF;
+ glInternalFormat = KTXHeader.GL_RGBA16F;
+ glBaseInternalFormat = KTXHeader.GL_RGBA;
+ break;
+ }
+ case TextureFormat.RFloat: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_R_F;
+ glInternalFormat = KTXHeader.GL_R32F;
+ glBaseInternalFormat = KTXHeader.GL_RED;
+ break;
+ }
+ case TextureFormat.RGFloat: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_RG_F;
+ glInternalFormat = KTXHeader.GL_RG32F;
+ glBaseInternalFormat = KTXHeader.GL_RG;
+ break;
+ }
+ case TextureFormat.RGBAFloat: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_RGBA_F;
+ glInternalFormat = KTXHeader.GL_RGBA32F;
+ glBaseInternalFormat = KTXHeader.GL_RGBA;
+ break;
+ }
+ case TextureFormat.YUY2: //test pass
+ {
+ pvrPixelFormat = 17;
+ break;
+ }
+ case TextureFormat.RGB9e5Float: //TODO Test failure
+ {
+ q_format = QFORMAT.Q_FORMAT_RGB9_E5;
+ break;
+ }
+ case TextureFormat.BC4: //test pass
+ {
+ texturetype = texgenpack_texturetype.RGTC1;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RED_RGTC1;
+ glBaseInternalFormat = KTXHeader.GL_RED;
+ break;
+ }
+ case TextureFormat.BC5: //test pass
+ {
+ texturetype = texgenpack_texturetype.RGTC2;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RG_RGTC2;
+ glBaseInternalFormat = KTXHeader.GL_RG;
+ break;
+ }
+ case TextureFormat.BC6H: //test pass
+ {
+ texturetype = texgenpack_texturetype.BPTC_FLOAT;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
+ glBaseInternalFormat = KTXHeader.GL_RGB;
+ break;
+ }
+ case TextureFormat.BC7: //test pass
+ {
+ texturetype = texgenpack_texturetype.BPTC;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RGBA_BPTC_UNORM;
+ glBaseInternalFormat = KTXHeader.GL_RGBA;
+ break;
+ }
+ case TextureFormat.PVRTC_RGB2: //test pass
+ {
+ pvrPixelFormat = 0;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
+ glBaseInternalFormat = KTXHeader.GL_RGB;
+ break;
+ }
+ case TextureFormat.PVRTC_RGBA2: //test pass
+ {
+ pvrPixelFormat = 1;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
+ glBaseInternalFormat = KTXHeader.GL_RGBA;
+ break;
+ }
+ case TextureFormat.PVRTC_RGB4: //test pass
+ {
+ pvrPixelFormat = 2;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
+ glBaseInternalFormat = KTXHeader.GL_RGB;
+ break;
+ }
+ case TextureFormat.PVRTC_RGBA4: //test pass
+ {
+ pvrPixelFormat = 3;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
+ glBaseInternalFormat = KTXHeader.GL_RGBA;
+ break;
+ }
+ case TextureFormat.ETC_RGB4Crunched: //test pass
+ case TextureFormat.ETC_RGB4_3DS: //test pass
+ case TextureFormat.ETC_RGB4: //test pass
+ {
+ pvrPixelFormat = 6;
+ glInternalFormat = KTXHeader.GL_ETC1_RGB8_OES;
+ glBaseInternalFormat = KTXHeader.GL_RGB;
+ break;
+ }
+ case TextureFormat.ATC_RGB4: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_ATITC_RGB;
+ glInternalFormat = KTXHeader.GL_ATC_RGB_AMD;
+ glBaseInternalFormat = KTXHeader.GL_RGB;
+ break;
+ }
+ case TextureFormat.ATC_RGBA8: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_ATC_RGBA_INTERPOLATED_ALPHA;
+ glInternalFormat = KTXHeader.GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
+ glBaseInternalFormat = KTXHeader.GL_RGBA;
+ break;
+ }
+ case TextureFormat.EAC_R: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_EAC_R_UNSIGNED;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_R11_EAC;
+ glBaseInternalFormat = KTXHeader.GL_RED;
+ break;
+ }
+ case TextureFormat.EAC_R_SIGNED: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_EAC_R_SIGNED;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_SIGNED_R11_EAC;
+ glBaseInternalFormat = KTXHeader.GL_RED;
+ break;
+ }
+ case TextureFormat.EAC_RG: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_EAC_RG_UNSIGNED;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RG11_EAC;
+ glBaseInternalFormat = KTXHeader.GL_RG;
+ break;
+ }
+ case TextureFormat.EAC_RG_SIGNED: //test pass
+ {
+ q_format = QFORMAT.Q_FORMAT_EAC_RG_SIGNED;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_SIGNED_RG11_EAC;
+ glBaseInternalFormat = KTXHeader.GL_RG;
+ break;
+ }
+ case TextureFormat.ETC2_RGB: //test pass
+ {
+ pvrPixelFormat = 22;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RGB8_ETC2;
+ glBaseInternalFormat = KTXHeader.GL_RGB;
+ break;
+ }
+ case TextureFormat.ETC2_RGBA1: //test pass
+ {
+ pvrPixelFormat = 24;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+ glBaseInternalFormat = KTXHeader.GL_RGBA;
+ break;
+ }
+ case TextureFormat.ETC2_RGBA8Crunched: //test pass
+ case TextureFormat.ETC_RGBA8_3DS: //test pass
+ case TextureFormat.ETC2_RGBA8: //test pass
+ {
+ pvrPixelFormat = 23;
+ glInternalFormat = KTXHeader.GL_COMPRESSED_RGBA8_ETC2_EAC;
+ glBaseInternalFormat = KTXHeader.GL_RGBA;
+ break;
+ }
+ case TextureFormat.ASTC_RGB_4x4: //test pass
+ case TextureFormat.ASTC_RGBA_4x4: //test pass
+ {
+ pvrPixelFormat = 27;
+ break;
+ }
+ case TextureFormat.ASTC_RGB_5x5: //test pass
+ case TextureFormat.ASTC_RGBA_5x5: //test pass
+ {
+ pvrPixelFormat = 29;
+ break;
+ }
+ case TextureFormat.ASTC_RGB_6x6: //test pass
+ case TextureFormat.ASTC_RGBA_6x6: //test pass
+ {
+ pvrPixelFormat = 31;
+ break;
+ }
+ case TextureFormat.ASTC_RGB_8x8: //test pass
+ case TextureFormat.ASTC_RGBA_8x8: //test pass
+ {
+ pvrPixelFormat = 34;
+ break;
+ }
+ case TextureFormat.ASTC_RGB_10x10: //test pass
+ case TextureFormat.ASTC_RGBA_10x10: //test pass
+ {
+ pvrPixelFormat = 38;
+ break;
+ }
+ case TextureFormat.ASTC_RGB_12x12: //test pass
+ case TextureFormat.ASTC_RGBA_12x12: //test pass
+ {
+ pvrPixelFormat = 40;
+ break;
+ }
+ case TextureFormat.RG16: //test pass
+ {
+ //转BGRA32
+ var BGRA32 = new byte[image_data_size * 2];
+ for (var i = 0; i < image_data_size; i += 2)
+ {
+ BGRA32[i * 2 + 1] = image_data[i + 1];//G
+ BGRA32[i * 2 + 2] = image_data[i];//R
+ BGRA32[i * 2 + 3] = 255;//A
+ }
+ SetBGRA32Info(BGRA32);
+ break;
+ }
+ case TextureFormat.R8: //test pass
+ {
+ //转BGRA32
+ var BGRA32 = new byte[image_data_size * 4];
+ for (var i = 0; i < image_data_size; i++)
+ {
+ BGRA32[i * 4 + 2] = image_data[i];//R
+ BGRA32[i * 4 + 3] = 255;//A
+ }
+ SetBGRA32Info(BGRA32);
+ break;
+ }
+ }
+ }
+
+ private void SetBGRA32Info(byte[] BGRA32)
+ {
+ image_data = BGRA32;
+ image_data_size = BGRA32.Length;
+ dwFlags2 = 0x41;
+ dwRGBBitCount = 0x20;
+ dwRBitMask = 0xFF0000;
+ dwGBitMask = 0xFF00;
+ dwBBitMask = 0xFF;
+ dwABitMask = -16777216;
+ }
+
+ private void SwapBytesForXbox(int platform)
+ {
+ if (platform == 11) //swap bytes for Xbox confirmed, PS3 not encountered
+ {
+ for (var i = 0; i < image_data_size / 2; i++)
+ {
+ var b0 = image_data[i * 2];
+ image_data[i * 2] = image_data[i * 2 + 1];
+ image_data[i * 2 + 1] = b0;
+ }
+ }
+ }
+
+ public string GetExtensionName()
+ {
+ switch (m_TextureFormat)
+ {
+ case TextureFormat.Alpha8:
+ case TextureFormat.ARGB4444:
+ case TextureFormat.RGB24:
+ case TextureFormat.RGBA32:
+ case TextureFormat.ARGB32:
+ case TextureFormat.RGB565:
+ case TextureFormat.R16:
+ case TextureFormat.DXT1:
+ case TextureFormat.DXT5:
+ case TextureFormat.RGBA4444:
+ case TextureFormat.BGRA32:
+ case TextureFormat.RG16:
+ case TextureFormat.R8:
+ return ".dds";
+ case TextureFormat.DXT1Crunched:
+ case TextureFormat.DXT5Crunched:
+ case TextureFormat.ETC_RGB4Crunched:
+ case TextureFormat.ETC2_RGBA8Crunched:
+ return ".crn";
+ case TextureFormat.YUY2:
+ case TextureFormat.PVRTC_RGB2:
+ case TextureFormat.PVRTC_RGBA2:
+ case TextureFormat.PVRTC_RGB4:
+ case TextureFormat.PVRTC_RGBA4:
+ case TextureFormat.ETC_RGB4:
+ case TextureFormat.ETC2_RGB:
+ case TextureFormat.ETC2_RGBA1:
+ case TextureFormat.ETC2_RGBA8:
+ case TextureFormat.ASTC_RGB_4x4:
+ case TextureFormat.ASTC_RGB_5x5:
+ case TextureFormat.ASTC_RGB_6x6:
+ case TextureFormat.ASTC_RGB_8x8:
+ case TextureFormat.ASTC_RGB_10x10:
+ case TextureFormat.ASTC_RGB_12x12:
+ case TextureFormat.ASTC_RGBA_4x4:
+ case TextureFormat.ASTC_RGBA_5x5:
+ case TextureFormat.ASTC_RGBA_6x6:
+ case TextureFormat.ASTC_RGBA_8x8:
+ case TextureFormat.ASTC_RGBA_10x10:
+ case TextureFormat.ASTC_RGBA_12x12:
+ case TextureFormat.ETC_RGB4_3DS:
+ case TextureFormat.ETC_RGBA8_3DS:
+ return ".pvr";
+ case TextureFormat.RHalf:
+ case TextureFormat.RGHalf:
+ case TextureFormat.RGBAHalf:
+ case TextureFormat.RFloat:
+ case TextureFormat.RGFloat:
+ case TextureFormat.RGBAFloat:
+ case TextureFormat.BC4:
+ case TextureFormat.BC5:
+ case TextureFormat.BC6H:
+ case TextureFormat.BC7:
+ case TextureFormat.ATC_RGB4:
+ case TextureFormat.ATC_RGBA8:
+ case TextureFormat.EAC_R:
+ case TextureFormat.EAC_R_SIGNED:
+ case TextureFormat.EAC_RG:
+ case TextureFormat.EAC_RG_SIGNED:
+ return ".ktx";
+ default:
+ return ".tex";
+ }
+ }
+
+
+ public byte[] ConvertToContainer()
+ {
+ if (image_data == null || image_data.Length == 0)
+ return null;
+ switch (m_TextureFormat)
+ {
+ case TextureFormat.Alpha8:
+ case TextureFormat.ARGB4444:
+ case TextureFormat.RGB24:
+ case TextureFormat.RGBA32:
+ case TextureFormat.ARGB32:
+ case TextureFormat.RGB565:
+ case TextureFormat.R16:
+ case TextureFormat.DXT1:
+ case TextureFormat.DXT5:
+ case TextureFormat.RGBA4444:
+ case TextureFormat.BGRA32:
+ case TextureFormat.RG16:
+ case TextureFormat.R8:
+ return ConvertToDDS();
+ case TextureFormat.YUY2:
+ case TextureFormat.PVRTC_RGB2:
+ case TextureFormat.PVRTC_RGBA2:
+ case TextureFormat.PVRTC_RGB4:
+ case TextureFormat.PVRTC_RGBA4:
+ case TextureFormat.ETC_RGB4:
+ case TextureFormat.ETC2_RGB:
+ case TextureFormat.ETC2_RGBA1:
+ case TextureFormat.ETC2_RGBA8:
+ case TextureFormat.ASTC_RGB_4x4:
+ case TextureFormat.ASTC_RGB_5x5:
+ case TextureFormat.ASTC_RGB_6x6:
+ case TextureFormat.ASTC_RGB_8x8:
+ case TextureFormat.ASTC_RGB_10x10:
+ case TextureFormat.ASTC_RGB_12x12:
+ case TextureFormat.ASTC_RGBA_4x4:
+ case TextureFormat.ASTC_RGBA_5x5:
+ case TextureFormat.ASTC_RGBA_6x6:
+ case TextureFormat.ASTC_RGBA_8x8:
+ case TextureFormat.ASTC_RGBA_10x10:
+ case TextureFormat.ASTC_RGBA_12x12:
+ case TextureFormat.ETC_RGB4_3DS:
+ case TextureFormat.ETC_RGBA8_3DS:
+ return ConvertToPVR();
+ case TextureFormat.RHalf:
+ case TextureFormat.RGHalf:
+ case TextureFormat.RGBAHalf:
+ case TextureFormat.RFloat:
+ case TextureFormat.RGFloat:
+ case TextureFormat.RGBAFloat:
+ case TextureFormat.BC4:
+ case TextureFormat.BC5:
+ case TextureFormat.BC6H:
+ case TextureFormat.BC7:
+ case TextureFormat.ATC_RGB4:
+ case TextureFormat.ATC_RGBA8:
+ case TextureFormat.EAC_R:
+ case TextureFormat.EAC_R_SIGNED:
+ case TextureFormat.EAC_RG:
+ case TextureFormat.EAC_RG_SIGNED:
+ return ConvertToKTX();
+ default:
+ return image_data;
+ }
+ }
+
+ private byte[] ConvertToDDS()
+ {
+ var imageBuffer = new byte[128 + image_data_size];
+ dwMagic.CopyTo(imageBuffer, 0);
+ BitConverter.GetBytes(dwFlags).CopyTo(imageBuffer, 8);
+ BitConverter.GetBytes(m_Height).CopyTo(imageBuffer, 12);
+ BitConverter.GetBytes(m_Width).CopyTo(imageBuffer, 16);
+ BitConverter.GetBytes(dwPitchOrLinearSize).CopyTo(imageBuffer, 20);
+ BitConverter.GetBytes(dwMipMapCount).CopyTo(imageBuffer, 28);
+ BitConverter.GetBytes(dwSize).CopyTo(imageBuffer, 76);
+ BitConverter.GetBytes(dwFlags2).CopyTo(imageBuffer, 80);
+ BitConverter.GetBytes(dwFourCC).CopyTo(imageBuffer, 84);
+ BitConverter.GetBytes(dwRGBBitCount).CopyTo(imageBuffer, 88);
+ BitConverter.GetBytes(dwRBitMask).CopyTo(imageBuffer, 92);
+ BitConverter.GetBytes(dwGBitMask).CopyTo(imageBuffer, 96);
+ BitConverter.GetBytes(dwBBitMask).CopyTo(imageBuffer, 100);
+ BitConverter.GetBytes(dwABitMask).CopyTo(imageBuffer, 104);
+ BitConverter.GetBytes(dwCaps).CopyTo(imageBuffer, 108);
+ BitConverter.GetBytes(dwCaps2).CopyTo(imageBuffer, 112);
+ image_data.CopyTo(imageBuffer, 128);
+ return imageBuffer;
+ }
+
+ private byte[] ConvertToPVR()
+ {
+ var mstream = new MemoryStream();
+ using (var writer = new BinaryWriter(mstream))
+ {
+ writer.Write(pvrVersion);
+ writer.Write(pvrFlags);
+ writer.Write(pvrPixelFormat);
+ writer.Write(pvrColourSpace);
+ writer.Write(pvrChannelType);
+ writer.Write(m_Height);
+ writer.Write(m_Width);
+ writer.Write(pvrDepth);
+ writer.Write(pvrNumSurfaces);
+ writer.Write(pvrNumFaces);
+ writer.Write(dwMipMapCount);
+ writer.Write(pvrMetaDataSize);
+ writer.Write(image_data);
+ return mstream.ToArray();
+ }
+ }
+
+ private byte[] ConvertToKTX()
+ {
+ var mstream = new MemoryStream();
+ using (var writer = new BinaryWriter(mstream))
+ {
+ writer.Write(KTXHeader.IDENTIFIER);
+ writer.Write(KTXHeader.ENDIANESS_LE);
+ writer.Write(glType);
+ writer.Write(glTypeSize);
+ writer.Write(glFormat);
+ writer.Write(glInternalFormat);
+ writer.Write(glBaseInternalFormat);
+ writer.Write(m_Width);
+ writer.Write(m_Height);
+ writer.Write(pixelDepth);
+ writer.Write(numberOfArrayElements);
+ writer.Write(numberOfFaces);
+ writer.Write(numberOfMipmapLevels);
+ writer.Write(bytesOfKeyValueData);
+ writer.Write(image_data_size);
+ writer.Write(image_data);
+ return mstream.ToArray();
+ }
+ }
+
+ public Bitmap ConvertToBitmap(bool flip)
+ {
+ if (image_data == null || image_data.Length == 0)
+ return null;
+ Bitmap bitmap;
+ switch (m_TextureFormat)
+ {
+ case TextureFormat.Alpha8:
+ case TextureFormat.ARGB4444:
+ case TextureFormat.RGB24:
+ case TextureFormat.RGBA32:
+ case TextureFormat.ARGB32:
+ case TextureFormat.R16:
+ case TextureFormat.RGBA4444:
+ case TextureFormat.BGRA32:
+ case TextureFormat.RG16:
+ case TextureFormat.R8:
+ bitmap = BGRA32ToBitmap();
+ break;
+ case TextureFormat.RGB565:
+ bitmap = RGB565ToBitmap();
+ break;
+ case TextureFormat.YUY2:
+ case TextureFormat.PVRTC_RGB2:
+ case TextureFormat.PVRTC_RGBA2:
+ case TextureFormat.PVRTC_RGB4:
+ case TextureFormat.PVRTC_RGBA4:
+ case TextureFormat.ETC_RGB4:
+ case TextureFormat.ETC2_RGB:
+ case TextureFormat.ETC2_RGBA1:
+ case TextureFormat.ETC2_RGBA8:
+ case TextureFormat.ASTC_RGB_4x4:
+ case TextureFormat.ASTC_RGB_5x5:
+ case TextureFormat.ASTC_RGB_6x6:
+ case TextureFormat.ASTC_RGB_8x8:
+ case TextureFormat.ASTC_RGB_10x10:
+ case TextureFormat.ASTC_RGB_12x12:
+ case TextureFormat.ASTC_RGBA_4x4:
+ case TextureFormat.ASTC_RGBA_5x5:
+ case TextureFormat.ASTC_RGBA_6x6:
+ case TextureFormat.ASTC_RGBA_8x8:
+ case TextureFormat.ASTC_RGBA_10x10:
+ case TextureFormat.ASTC_RGBA_12x12:
+ case TextureFormat.ETC_RGB4_3DS:
+ case TextureFormat.ETC_RGBA8_3DS:
+ bitmap = PVRToBitmap(ConvertToPVR());
+ break;
+ case TextureFormat.DXT1:
+ case TextureFormat.DXT5:
+ case TextureFormat.RHalf:
+ case TextureFormat.RGHalf:
+ case TextureFormat.RGBAHalf:
+ case TextureFormat.RFloat:
+ case TextureFormat.RGFloat:
+ case TextureFormat.RGBAFloat:
+ case TextureFormat.RGB9e5Float:
+ case TextureFormat.ATC_RGB4:
+ case TextureFormat.ATC_RGBA8:
+ case TextureFormat.EAC_R:
+ case TextureFormat.EAC_R_SIGNED:
+ case TextureFormat.EAC_RG:
+ case TextureFormat.EAC_RG_SIGNED:
+ bitmap = TextureConverter();
+ break;
+ case TextureFormat.BC4:
+ case TextureFormat.BC5:
+ case TextureFormat.BC6H:
+ case TextureFormat.BC7:
+ bitmap = Texgenpack();
+ break;
+ case TextureFormat.DXT1Crunched:
+ case TextureFormat.DXT5Crunched:
+ DecompressCRN();
+ bitmap = TextureConverter();
+ break;
+ case TextureFormat.ETC_RGB4Crunched:
+ case TextureFormat.ETC2_RGBA8Crunched:
+ DecompressCRN();
+ bitmap = PVRToBitmap(ConvertToPVR());
+ break;
+ default:
+ return null;
+ }
+ if (bitmap != null && flip)
+ bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
+ return bitmap;
+ }
+
+ private Bitmap BGRA32ToBitmap()
+ {
+ var hObject = GCHandle.Alloc(image_data, GCHandleType.Pinned);
+ var pObject = hObject.AddrOfPinnedObject();
+ var bitmap = new Bitmap(m_Width, m_Height, m_Width * 4, PixelFormat.Format32bppArgb, pObject);
+ hObject.Free();
+ return bitmap;
+ }
+
+ private Bitmap RGB565ToBitmap()
+ {
+ //stride = m_Width * 2 + m_Width * 2 % 4
+ //所以m_Width * 2不为4的倍数时,需要在每行补上相应的像素
+ byte[] buff;
+ var padding = m_Width * 2 % 4;
+ var stride = m_Width * 2 + padding;
+ if (padding != 0)
+ {
+ buff = new byte[stride * m_Height];
+ for (int i = 0; i < m_Height; i++)
+ {
+ Array.Copy(image_data, i * m_Width * 2, buff, i * stride, m_Width * 2);
+ }
+ }
+ else
+ {
+ buff = image_data;
+ }
+ var hObject = GCHandle.Alloc(buff, GCHandleType.Pinned);
+ var pObject = hObject.AddrOfPinnedObject();
+ var bitmap = new Bitmap(m_Width, m_Height, stride, PixelFormat.Format16bppRgb565, pObject);
+ hObject.Free();
+ return bitmap;
+ }
+
+ private Bitmap PVRToBitmap(byte[] pvrdata)
+ {
+ var bitmap = new Bitmap(m_Width, m_Height);
+ var rect = new Rectangle(0, 0, m_Width, m_Height);
+ var bmd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
+ var len = Math.Abs(bmd.Stride) * bmd.Height;
+ if (!DecompressPVR(pvrdata, bmd.Scan0, len))
+ {
+ bitmap.UnlockBits(bmd);
+ bitmap.Dispose();
+ return null;
+ }
+ bitmap.UnlockBits(bmd);
+ return bitmap;
+ }
+
+ private Bitmap TextureConverter()
+ {
+ var bitmap = new Bitmap(m_Width, m_Height);
+ var rect = new Rectangle(0, 0, m_Width, m_Height);
+ var bmd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
+ var len = Math.Abs(bmd.Stride) * bmd.Height;
+ var fixAlpha = glBaseInternalFormat == KTXHeader.GL_RED || glBaseInternalFormat == KTXHeader.GL_RG;
+ if (!Ponvert(image_data, bmd.Scan0, m_Width, m_Height, image_data_size, (int)q_format, len, fixAlpha))
+ {
+ bitmap.UnlockBits(bmd);
+ bitmap.Dispose();
+ return null;
+ }
+ bitmap.UnlockBits(bmd);
+ return bitmap;
+ }
+
+ private void DecompressCRN()
+ {
+ IntPtr uncompressedData;
+ int uncompressedSize;
+ bool result;
+ if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
+ {
+ result = DecompressUnityCRN(image_data, image_data_size, out uncompressedData, out uncompressedSize);
+ }
+ else
+ {
+ result = DecompressCRN(image_data, image_data_size, out uncompressedData, out uncompressedSize);
+ }
+
+ if (result)
+ {
+ var uncompressedBytes = new byte[uncompressedSize];
+ Marshal.Copy(uncompressedData, uncompressedBytes, 0, uncompressedSize);
+ Marshal.FreeHGlobal(uncompressedData);
+ image_data = uncompressedBytes;
+ image_data_size = uncompressedSize;
+ }
+ }
+
+ private Bitmap Texgenpack()
+ {
+ var bitmap = new Bitmap(m_Width, m_Height);
+ var rect = new Rectangle(0, 0, m_Width, m_Height);
+ var bmd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
+ var fixAlpha = glBaseInternalFormat == KTXHeader.GL_RED || glBaseInternalFormat == KTXHeader.GL_RG;
+ texgenpackdecode((int)texturetype, image_data, m_Width, m_Height, bmd.Scan0, fixAlpha);
+ bitmap.UnlockBits(bmd);
+ return bitmap;
+ }
+ }
+
+ public static class KTXHeader
+ {
+ public static byte[] IDENTIFIER = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
+ public static byte[] ENDIANESS_LE = { 1, 2, 3, 4 };
+
+ // constants for glInternalFormat
+ public static int GL_ETC1_RGB8_OES = 0x8D64;
+
+ public static int GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
+ public static int GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01;
+ public static int GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
+ public static int GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03;
+
+ public static int GL_ATC_RGB_AMD = 0x8C92;
+ public static int GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD = 0x87EE;
+
+ public static int GL_COMPRESSED_RGB8_ETC2 = 0x9274;
+ public static int GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276;
+ public static int GL_COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
+ public static int GL_COMPRESSED_R11_EAC = 0x9270;
+ public static int GL_COMPRESSED_SIGNED_R11_EAC = 0x9271;
+ public static int GL_COMPRESSED_RG11_EAC = 0x9272;
+ public static int GL_COMPRESSED_SIGNED_RG11_EAC = 0x9273;
+
+ public static int GL_COMPRESSED_RED_RGTC1 = 0x8DBB;
+ public static int GL_COMPRESSED_RG_RGTC2 = 0x8DBD;
+ public static int GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 0x8E8F;
+ public static int GL_COMPRESSED_RGBA_BPTC_UNORM = 0x8E8C;
+
+ public static int GL_R16F = 0x822D;
+ public static int GL_RG16F = 0x822F;
+ public static int GL_RGBA16F = 0x881A;
+ public static int GL_R32F = 0x822E;
+ public static int GL_RG32F = 0x8230;
+ public static int GL_RGBA32F = 0x8814;
+
+ // constants for glBaseInternalFormat
+ public static int GL_RED = 0x1903;
+ public static int GL_RGB = 0x1907;
+ public static int GL_RGBA = 0x1908;
+ public static int GL_RG = 0x8227;
+ }
+
+ //from TextureConverter.h
+ public enum QFORMAT
+ {
+ // General formats
+ Q_FORMAT_RGBA_8UI = 1,
+ Q_FORMAT_RGBA_8I,
+ Q_FORMAT_RGB5_A1UI,
+ Q_FORMAT_RGBA_4444,
+ Q_FORMAT_RGBA_16UI,
+ Q_FORMAT_RGBA_16I,
+ Q_FORMAT_RGBA_32UI,
+ Q_FORMAT_RGBA_32I,
+
+ Q_FORMAT_PALETTE_8_RGBA_8888,
+ Q_FORMAT_PALETTE_8_RGBA_5551,
+ Q_FORMAT_PALETTE_8_RGBA_4444,
+ Q_FORMAT_PALETTE_4_RGBA_8888,
+ Q_FORMAT_PALETTE_4_RGBA_5551,
+ Q_FORMAT_PALETTE_4_RGBA_4444,
+ Q_FORMAT_PALETTE_1_RGBA_8888,
+ Q_FORMAT_PALETTE_8_RGB_888,
+ Q_FORMAT_PALETTE_8_RGB_565,
+ Q_FORMAT_PALETTE_4_RGB_888,
+ Q_FORMAT_PALETTE_4_RGB_565,
+
+ Q_FORMAT_R2_GBA10UI,
+ Q_FORMAT_RGB10_A2UI,
+ Q_FORMAT_RGB10_A2I,
+ Q_FORMAT_RGBA_F,
+ Q_FORMAT_RGBA_HF,
+
+ Q_FORMAT_RGB9_E5, // Last five bits are exponent bits (Read following section in GLES3 spec: "3.8.17 Shared Exponent Texture Color Conversion")
+ Q_FORMAT_RGB_8UI,
+ Q_FORMAT_RGB_8I,
+ Q_FORMAT_RGB_565,
+ Q_FORMAT_RGB_16UI,
+ Q_FORMAT_RGB_16I,
+ Q_FORMAT_RGB_32UI,
+ Q_FORMAT_RGB_32I,
+
+ Q_FORMAT_RGB_F,
+ Q_FORMAT_RGB_HF,
+ Q_FORMAT_RGB_11_11_10_F,
+
+ Q_FORMAT_RG_F,
+ Q_FORMAT_RG_HF,
+ Q_FORMAT_RG_32UI,
+ Q_FORMAT_RG_32I,
+ Q_FORMAT_RG_16I,
+ Q_FORMAT_RG_16UI,
+ Q_FORMAT_RG_8I,
+ Q_FORMAT_RG_8UI,
+ Q_FORMAT_RG_S88,
+
+ Q_FORMAT_R_32UI,
+ Q_FORMAT_R_32I,
+ Q_FORMAT_R_F,
+ Q_FORMAT_R_16F,
+ Q_FORMAT_R_16I,
+ Q_FORMAT_R_16UI,
+ Q_FORMAT_R_8I,
+ Q_FORMAT_R_8UI,
+
+ Q_FORMAT_LUMINANCE_ALPHA_88,
+ Q_FORMAT_LUMINANCE_8,
+ Q_FORMAT_ALPHA_8,
+
+ Q_FORMAT_LUMINANCE_ALPHA_F,
+ Q_FORMAT_LUMINANCE_F,
+ Q_FORMAT_ALPHA_F,
+ Q_FORMAT_LUMINANCE_ALPHA_HF,
+ Q_FORMAT_LUMINANCE_HF,
+ Q_FORMAT_ALPHA_HF,
+ Q_FORMAT_DEPTH_16,
+ Q_FORMAT_DEPTH_24,
+ Q_FORMAT_DEPTH_24_STENCIL_8,
+ Q_FORMAT_DEPTH_32,
+
+ Q_FORMAT_BGR_565,
+ Q_FORMAT_BGRA_8888,
+ Q_FORMAT_BGRA_5551,
+ Q_FORMAT_BGRX_8888,
+ Q_FORMAT_BGRA_4444,
+ // Compressed formats
+ Q_FORMAT_ATITC_RGBA,
+ Q_FORMAT_ATC_RGBA_EXPLICIT_ALPHA = Q_FORMAT_ATITC_RGBA,
+ Q_FORMAT_ATITC_RGB,
+ Q_FORMAT_ATC_RGB = Q_FORMAT_ATITC_RGB,
+ Q_FORMAT_ATC_RGBA_INTERPOLATED_ALPHA,
+ Q_FORMAT_ETC1_RGB8,
+ Q_FORMAT_3DC_X,
+ Q_FORMAT_3DC_XY,
+
+ Q_FORMAT_ETC2_RGB8,
+ Q_FORMAT_ETC2_RGBA8,
+ Q_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1,
+ Q_FORMAT_ETC2_SRGB8,
+ Q_FORMAT_ETC2_SRGB8_ALPHA8,
+ Q_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1,
+ Q_FORMAT_EAC_R_SIGNED,
+ Q_FORMAT_EAC_R_UNSIGNED,
+ Q_FORMAT_EAC_RG_SIGNED,
+ Q_FORMAT_EAC_RG_UNSIGNED,
+
+ Q_FORMAT_S3TC_DXT1_RGB,
+ Q_FORMAT_S3TC_DXT1_RGBA,
+ Q_FORMAT_S3TC_DXT3_RGBA,
+ Q_FORMAT_S3TC_DXT5_RGBA,
+
+ // YUV formats
+ Q_FORMAT_AYUV_32,
+ Q_FORMAT_I444_24,
+ Q_FORMAT_YUYV_16,
+ Q_FORMAT_UYVY_16,
+ Q_FORMAT_I420_12,
+ Q_FORMAT_YV12_12,
+ Q_FORMAT_NV21_12,
+ Q_FORMAT_NV12_12,
+
+ // ASTC Format
+ Q_FORMAT_ASTC_8,
+ Q_FORMAT_ASTC_16,
+ };
+
+ public enum texgenpack_texturetype
+ {
+ RGTC1,
+ RGTC2,
+ BPTC_FLOAT,
+ BPTC
+ }
+}
diff --git a/AssetStudioFBX/AssetStudioFBX.h b/AssetStudioFBX/AssetStudioFBX.h
index 2227836..53b3219 100644
--- a/AssetStudioFBX/AssetStudioFBX.h
+++ b/AssetStudioFBX/AssetStudioFBX.h
@@ -41,11 +41,7 @@ namespace AssetStudio {
private:
HashSet^ frameNames;
- HashSet^ meshNames;
- bool EulerFilter;
- float filterPrecision;
bool exportSkins;
- bool embedMedia;
float boneSize;
IImported^ imported;
@@ -72,39 +68,11 @@ namespace AssetStudio {
void ExportMesh(FbxNode* pFrameNode, ImportedMesh^ meshList, bool normals);
FbxFileTexture* ExportTexture(ImportedTexture^ matTex, FbxMesh* pMesh);
void ExportAnimations(bool EulerFilter, float filterValue, bool flatInbetween);
- void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision,
- FbxPropertyT& scale, FbxPropertyT& rotate, FbxPropertyT& translate, List^ pNotFound);
- void ExportSampledAnimation(ImportedSampledAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, bool flatInbetween,
- FbxPropertyT& scale, FbxPropertyT& rotate, FbxPropertyT& translate, List^ pNotFound);
+ void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, List^ pNotFound);
+ void ExportSampledAnimation(ImportedSampledAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, bool flatInbetween, List^ pNotFound);
void ExportMorphs(IImported^ imported, bool morphMask, bool flatInbetween);
};
- private:
- ref class InterpolationHelper
- {
- private:
- FbxScene * pScene;
- FbxAnimLayer* pAnimLayer;
- FbxAnimEvaluator* pAnimEvaluator;
-
- FbxAnimCurveDef::EInterpolationType interpolationMethod;
- FbxAnimCurveFilterUnroll* lFilter;
- float filterPrecision;
-
- FbxPropertyT* scale, *translate;
- FbxPropertyT* rotate;
- FbxAnimCurve* pScaleCurveX, *pScaleCurveY, *pScaleCurveZ,
- *pRotateCurveX, *pRotateCurveY, *pRotateCurveZ, *pRotateCurveW,
- *pTranslateCurveX, *pTranslateCurveY, *pTranslateCurveZ;
-
- array^ allCurves;
-
- public:
- static const char* pScaleName = "Scale";
- static const char* pRotateName = "Rotate";
- static const char* pTranslateName = "Translate";
- };
-
static char* StringToCharArray(String^ s);
static void Init(FbxManager** pSdkManager, FbxScene** pScene);
};
diff --git a/AssetStudioFBX/AssetStudioFBXExporter.cpp b/AssetStudioFBX/AssetStudioFBXExporter.cpp
index 83d4e93..81c8081 100644
--- a/AssetStudioFBX/AssetStudioFBXExporter.cpp
+++ b/AssetStudioFBX/AssetStudioFBXExporter.cpp
@@ -21,14 +21,6 @@ namespace AssetStudio
}
if (pTextures != NULL)
{
- if (embedMedia)
- {
- for (int i = 0; i < pTextures->GetCount(); i++)
- {
- FbxFileTexture* tex = pTextures->GetAt(i);
- File::Delete(gcnew String(tex->GetFileName()));
- }
- }
delete pTextures;
}
if (pExporter != NULL)
diff --git a/AssetStudioFBX/ImportedFBXExporter.cpp b/AssetStudioFBX/ImportedFBXExporter.cpp
index 3373cff..a4a465e 100644
--- a/AssetStudioFBX/ImportedFBXExporter.cpp
+++ b/AssetStudioFBX/ImportedFBXExporter.cpp
@@ -675,10 +675,6 @@ namespace AssetStudio
List^ pNotFound = gcnew List();
- FbxPropertyT scale = FbxProperty::Create(pScene, FbxDouble3DT, InterpolationHelper::pScaleName);
- FbxPropertyT rotate = FbxProperty::Create(pScene, FbxDouble4DT, InterpolationHelper::pRotateName);
- FbxPropertyT translate = FbxProperty::Create(pScene, FbxDouble3DT, InterpolationHelper::pTranslateName);
-
FbxAnimCurveFilterUnroll* lFilter = EulerFilter ? new FbxAnimCurveFilterUnroll() : NULL;
for (int i = 0; i < importedAnimationList->Count; i++)
@@ -702,12 +698,12 @@ namespace AssetStudio
if (keyframed)
{
ImportedKeyframedAnimation^ parser = (ImportedKeyframedAnimation^)importedAnimation;
- ExportKeyframedAnimation(parser, kTakeName, lFilter, filterPrecision, scale, rotate, translate, pNotFound);
+ ExportKeyframedAnimation(parser, kTakeName, lFilter, filterPrecision, pNotFound);
}
else
{
ImportedSampledAnimation^ parser = (ImportedSampledAnimation^)importedAnimation;
- ExportSampledAnimation(parser, kTakeName, lFilter, filterPrecision, flatInbetween, scale, rotate, translate, pNotFound);
+ ExportSampledAnimation(parser, kTakeName, lFilter, filterPrecision, flatInbetween, pNotFound);
}
}
@@ -722,8 +718,7 @@ namespace AssetStudio
}*/
}
- void Fbx::Exporter::ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision,
- FbxPropertyT& scale, FbxPropertyT& rotate, FbxPropertyT& translate, List^ pNotFound)
+ void Fbx::Exporter::ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, List^ pNotFound)
{
List^ pAnimationList = parser->TrackList;
@@ -834,8 +829,7 @@ namespace AssetStudio
}
}
- void Fbx::Exporter::ExportSampledAnimation(ImportedSampledAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, bool flatInbetween,
- FbxPropertyT& scale, FbxPropertyT& rotate, FbxPropertyT& translate, List^ pNotFound)
+ void Fbx::Exporter::ExportSampledAnimation(ImportedSampledAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, bool flatInbetween, List^ pNotFound)
{
List^ pAnimationList = parser->TrackList;