Update DDS and nutexb with fixes

This commit is contained in:
KillzXGaming 2018-11-28 13:22:25 -05:00
parent f51dd17f94
commit 0c9bafe67f
5 changed files with 133 additions and 133 deletions

View file

@ -1252,71 +1252,14 @@ namespace FirstPlugin
dds.header.width = Texture.Width;
dds.header.height = Texture.Height;
dds.header.mipmapCount = (uint)mipmaps.Count;
dds.header.pitchOrLinearSize = (uint)mipmaps[0][0].Length;
bool IsDX10 = false;
if (IsCompressedFormat(Texture.Format))
dds.SetFlags(GetCompressedDXGI_FORMAT(Texture.Format));
else
dds.SetFlags(GetUncompressedDXGI_FORMAT(Texture.Format));
switch (Texture.Format)
{
case SurfaceFormat.BC1_UNORM:
case SurfaceFormat.BC1_SRGB:
dds.header.ddspf.fourCC = "DXT1";
break;
case SurfaceFormat.BC2_UNORM:
case SurfaceFormat.BC2_SRGB:
dds.header.ddspf.fourCC = "DXT3";
break;
case SurfaceFormat.BC3_UNORM:
case SurfaceFormat.BC3_SRGB:
dds.header.ddspf.fourCC = "DXT5";
break;
case SurfaceFormat.BC4_UNORM:
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM;
break;
case SurfaceFormat.BC4_SNORM:
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM;
break;
case SurfaceFormat.BC5_UNORM:
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM;
break;
case SurfaceFormat.BC5_SNORM:
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM;
break;
case SurfaceFormat.BC6_FLOAT:
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16;
break;
case SurfaceFormat.BC6_UFLOAT:
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16;
break;
case SurfaceFormat.BC7_UNORM:
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB;
break;
case SurfaceFormat.BC7_SRGB:
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM;
break;
default:
throw new Exception($"Format {Texture.Format} not supported!");
}
if (IsDX10)
dds.header.ddspf.fourCC = "DX10";
dds.Save(dds, FileName, IsDX10, mipmaps);
dds.Save(dds, FileName, mipmaps);
}
public void LoadTexture(Texture tex, int target = 1)
{
@ -1331,11 +1274,9 @@ namespace FirstPlugin
int linesPerBlockHeight = (1 << (int)tex.BlockHeightLog2) * 8;
uint bpp = Formats.bpps((uint)((int)tex.Format >> 8));
for (int arrayLevel = 0; arrayLevel < tex.ArrayLength; arrayLevel++)
{
int blockHeightShift = 0;
List<byte[]> mips = new List<byte[]>();
for (int mipLevel = 0; mipLevel < tex.TextureData[arrayLevel].Count; mipLevel++)
{

View file

@ -219,50 +219,14 @@ namespace FirstPlugin
dds.header.height = (uint)renderedTex.width;
dds.header.mipmapCount = (uint)renderedTex.mipmaps[0].Count;
bool IsDX10 = false;
dds.header.pitchOrLinearSize = (uint)renderedTex.mipmaps[0][0].Length;
switch (format)
{
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_UNORM):
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC1_SRGB):
dds.header.ddspf.fourCC = "DXT1";
break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_UNORM):
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC2_SRGB):
dds.header.ddspf.fourCC = "DXT3";
break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_UNORM):
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC3_SRGB):
dds.header.ddspf.fourCC = "DXT5";
break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_UNORM):
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM;
break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC4_SNORM):
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM;
break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_UNORM):
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM;
break;
case ((int)GTX.GX2SurfaceFormat.GX2_SURFACE_FORMAT_T_BC5_SNORM):
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM;
break;
default:
throw new Exception($"Format {(GTX.GX2SurfaceFormat)format} not supported!");
}
if (IsCompressedFormat((GX2SurfaceFormat)format))
dds.SetFlags(GetCompressedDXGI_FORMAT((GX2SurfaceFormat)format));
else
dds.SetFlags(GetUncompressedDXGI_FORMAT((GX2SurfaceFormat)format));
if (IsDX10)
dds.header.ddspf.fourCC = "DX10";
dds.Save(dds, FileName, IsDX10, renderedTex.mipmaps);
dds.Save(dds, FileName, renderedTex.mipmaps);
}

View file

@ -32,6 +32,8 @@ namespace FirstPlugin
{
R8G8B8A8_UNORM = 0x00,
R8G8B8A8_SRGB = 0x05,
B8G8R8A8_UNORM = 0x50,
B8G8R8A8_SRGB = 0x55,
BC1_UNORM = 0x80,
BC1_SRGB = 0x85,
BC2_UNORM = 0x90,
@ -74,6 +76,8 @@ namespace FirstPlugin
{
switch (format)
{
case (byte)NUTEXImageFormat.B8G8R8A8_UNORM:
case (byte)NUTEXImageFormat.B8G8R8A8_SRGB:
case (byte)NUTEXImageFormat.R8G8B8A8_UNORM:
case (byte)NUTEXImageFormat.R8G8B8A8_SRGB:
return 4;
@ -134,14 +138,12 @@ namespace FirstPlugin
texture.Read(new FileReader(file));
Console.WriteLine(texture.Format.ToString("x") + " " + file + " " + texture.Text);
/*
try
{
Bitmap bitmap = texture.DisplayImage();
Bitmap bitmap = texture.DisplayTexture();
if (bitmap != null)
bitmap.Save(System.IO.Path.GetDirectoryName(ofd.FileName) + texture.Text + ".png");
bitmap.Save(System.IO.Path.GetFullPath(file) + texture.ArcOffset + texture.Text + ".png");
else
Console.WriteLine(" Not supported Format! " + texture.Format);
@ -150,16 +152,21 @@ namespace FirstPlugin
}
catch
{
Console.WriteLine();
Console.WriteLine("Somethign went wrong??");
}
texture.blocksCompressed.Clear();
texture.mipmaps.Clear();
texture = null;
GC.Collect();*/
GC.Collect();
}
}
}
}
public class NuTex : TreeNodeFile
{
public bool BadSwizzle;
public uint Width;
public uint Height;
public byte Format;
@ -168,6 +175,7 @@ namespace FirstPlugin
public List<List<byte[]>> mipmaps = new List<List<byte[]>>();
public List<List<byte[]>> blocksCompressed = new List<List<byte[]>>();
bool IsSwizzled = true;
public string ArcOffset; //Temp for exporting in batch
MenuItem export = new MenuItem("Export");
@ -227,17 +235,15 @@ namespace FirstPlugin
dds.header.width = Width;
dds.header.height = Height;
dds.header.mipmapCount = (uint)mipmaps.Count;
dds.header.pitchOrLinearSize = (uint)mipmaps[0][0].Length;
bool IsDX10 = false;
if (IsCompressedFormat((NUTEXImageFormat)Format))
dds.SetFlags(GetCompressedDXGI_FORMAT((NUTEXImageFormat)Format));
else
dds.SetFlags(GetUncompressedDXGI_FORMAT((NUTEXImageFormat)Format));
IsDX10 = true;
dds.DX10header = new DDS.DX10Header();
dds.DX10header.DXGI_Format = DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM;
if (IsDX10)
dds.header.ddspf.fourCC = "DX10";
dds.Save(dds, FileName, IsDX10, mipmaps);
dds.Save(dds, FileName, mipmaps);
}
public void Read(FileReader reader)
{
@ -285,8 +291,8 @@ namespace FirstPlugin
{
for (int mipLevel = 0; mipLevel < mipCount; mipLevel++)
{
mips.Add(reader.ReadBytes((int)mipSizes[mipLevel]));
break; //Don't load mip maps yet. They break for some reason????
mips.Add(reader.ReadBytes((int)Width * (int)Height * (int)bpps(Format)));
break;
}
blocksCompressed.Add(mips);
}
@ -300,20 +306,26 @@ namespace FirstPlugin
public Bitmap DisplayTexture(int DisplayMipIndex = 0, int ArrayIndex = 0)
{
if (BadSwizzle)
return BitmapExtension.GetBitmap(Properties.Resources.Black, 32, 32);
if (IsSwizzled)
LoadTexture();
else
mipmaps.Add(blocksCompressed[0]);
if (mipmaps.Count <= 0)
if (mipmaps[0].Count <= 0)
{
throw new Exception("No texture data found");
return BitmapExtension.GetBitmap(Properties.Resources.Black, 32, 32);
}
uint width = (uint)Math.Max(1, Width >> DisplayMipIndex);
uint height = (uint)Math.Max(1, Height >> DisplayMipIndex);
byte[] data = mipmaps[ArrayIndex][DisplayMipIndex];
return DecodeBlock(data, width, height, (NUTEXImageFormat)Format);
}
public static Bitmap DecodeBlock(byte[] data, uint Width, uint Height, NUTEXImageFormat Format)
@ -342,6 +354,8 @@ namespace FirstPlugin
{
case NUTEXImageFormat.R8G8B8A8_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM;
case NUTEXImageFormat.R8G8B8A8_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
case NUTEXImageFormat.B8G8R8A8_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
case NUTEXImageFormat.B8G8R8A8_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
default:
throw new Exception($"Cannot convert format {Format}");
}
@ -423,12 +437,22 @@ namespace FirstPlugin
Console.WriteLine($"{blk_dim.ToString("x")} {bpp} {width} {height} {linesPerBlockHeight} {blkWidth} {blkHeight} {size} { blocksCompressed[arrayLevel][mipLevel].Length}");
byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, target, bpp, tileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), blocksCompressed[arrayLevel][mipLevel]);
//Create a copy and use that to remove uneeded data
byte[] result_ = new byte[size];
Array.Copy(result, 0, result_, 0, size);
try
{
byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, target, bpp, tileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), blocksCompressed[arrayLevel][mipLevel]);
//Create a copy and use that to remove uneeded data
byte[] result_ = new byte[size];
Array.Copy(result, 0, result_, 0, size);
mips.Add(result_);
mips.Add(result_);
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show("Failed to swizzle texture!");
Console.WriteLine(e);
BadSwizzle = true;
break;
}
}
mipmaps.Add(mips);
}
@ -456,6 +480,7 @@ namespace FirstPlugin
IsActive = true;
EditorRoot = new NuTex();
((NuTex)EditorRoot).FileHandler = this;
((NuTex)EditorRoot).ArcOffset = System.IO.Path.GetFileNameWithoutExtension(FileName);
((NuTex)EditorRoot).Read(new FileReader(Data));
}
public void Unload()

View file

@ -76,7 +76,7 @@ namespace FirstPlugin
{
uint block_height = (uint)(1 << blockHeightLog2);
// Console.WriteLine($"Swizzle {width} {height} {blkWidth} {blkHeight} {roundPitch} {bpp} {tileMode} {blockHeightLog2} {data.Length} {toSwizzle}");
Console.WriteLine($"Swizzle {width} {height} {blkWidth} {blkHeight} {roundPitch} {bpp} {tileMode} {blockHeightLog2} {data.Length} {toSwizzle}");
width = DIV_ROUND_UP(width, blkWidth);
height = DIV_ROUND_UP(height, blkHeight);

View file

@ -95,7 +95,25 @@ namespace Switch_Toolbox.Library
return 0;
}
}
public void SetFourCC(DXGI_FORMAT Format)
{
switch (Format)
{
case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM:
case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB:
header.ddspf.fourCC = "DXT1";
break;
case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB:
header.ddspf.fourCC = "DXT3";
break;
case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM:
case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB:
header.ddspf.fourCC = "DXT5";
break;
}
}
public bool IsDX10;
public Header header;
public DX10Header DX10header;
public class Header
@ -318,6 +336,8 @@ namespace Switch_Toolbox.Library
int DX10HeaderSize = 0;
if (header.ddspf.fourCC == "DX10")
{
IsDX10 = true;
DX10HeaderSize = 20;
ReadDX10Header(reader);
}
@ -357,7 +377,57 @@ namespace Switch_Toolbox.Library
return array;
}
}
public void Save(DDS dds, string FileName, bool IsDX10 = false, List<List<byte[]>> data = null)
public void SetFlags(DXGI_FORMAT Format)
{
header.flags = (uint)(DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PIXELFORMAT | DDSD.MIPMAPCOUNT | DDSD.LINEARSIZE);
header.caps = (uint)DDSCAPS.TEXTURE;
if (header.mipmapCount > 1)
header.caps |= (uint)(DDSCAPS.COMPLEX | DDSCAPS.MIPMAP);
switch (Format)
{
case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
header.ddspf.flags = (uint)(DDPF.RGB | DDPF.ALPHAPIXELS);
header.ddspf.RGBBitCount = 0x8 * 4;
header.ddspf.RBitMask = 0x000000FF;
header.ddspf.GBitMask = 0x0000FF00;
header.ddspf.BBitMask = 0x00FF0000;
header.ddspf.ABitMask = 0xFF000000;
break;
case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB:
case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM:
header.ddspf.flags = (uint)DDPF.FOURCC;
header.ddspf.fourCC = "DXT1";
break;
case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB:
case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM:
header.ddspf.flags = (uint)DDPF.FOURCC;
header.ddspf.fourCC = "DXT3";
break;
case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB:
case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM:
header.ddspf.flags = (uint)DDPF.FOURCC;
header.ddspf.fourCC = "DXT5";
break;
case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM:
case DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM:
case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM:
case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM:
case DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16:
case DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16:
case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB:
header.ddspf.fourCC = "DX10";
if (DX10header == null)
DX10header = new DX10Header();
IsDX10 = true;
DX10header.DXGI_Format = Format;
break;
}
}
public void Save(DDS dds, string FileName, List<List<byte[]>> data = null)
{
FileWriter writer = new FileWriter(new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.Write));
writer.Write(Encoding.ASCII.GetBytes("DDS "));