Start to impliment backend for depth/3D textures

This commit is contained in:
KillzXGaming 2020-01-14 19:19:02 -05:00
parent 9735fb0ce6
commit f7d674fe18
37 changed files with 225 additions and 138 deletions

View file

@ -563,7 +563,7 @@ namespace Bfres.Structs
}
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
format = (int)texture.Format;
int swizzle = (int)texture.Swizzle;

View file

@ -66,7 +66,7 @@ namespace FirstPlugin
return TextureImage.PaletteData;
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return TextureImage.ImageData;
}

View file

@ -174,7 +174,7 @@ namespace FirstPlugin
IGZStructure.TextureInfo.ImageData = GenerateMipsAndCompress(bitmap, MipCount, Format);
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
if (PlatformSwizzle == PlatformSwizzle.Platform_Switch)
return TegraX1Swizzle.GetImageData(this, IGZStructure.TextureInfo.ImageData, ArrayLevel, MipLevel, 1);

View file

@ -926,7 +926,7 @@ namespace FirstPlugin
throw new NotImplementedException("Cannot set image data! Operation not implemented!");
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
uint GX2Format = (uint)GX2.GX2SurfaceFormat.T_BC5_UNORM;

View file

@ -679,7 +679,7 @@ namespace FirstPlugin
}
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return data;
}

View file

@ -635,7 +635,7 @@ namespace FirstPlugin
}
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
int swizzle = (int)Swizzle;
int pitch = (int)0;

View file

@ -678,7 +678,7 @@ namespace FirstPlugin
}
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
uint bpp = GetBytesPerPixel(Format);

View file

@ -113,4 +113,45 @@ namespace Grezzo.CmbEnums
ONE_MINUS_SRC_B = 0x8585,
};
public enum FresnelSelector
{
No = 25280,
Pri = 25281,
Sec = 25282,
PriSec = 25283
};
public enum LayerConfig
{
LayerConfig0 = 25264,
LayerConfig1 = 25265,
LayerConfig2 = 25266,
LayerConfig3 = 25267,
LayerConfig4 = 25268,
LayerConfig5 = 25269,
LayerConfig6 = 25270,
LayerConfig7 = 25271,
};
public enum LUTInput : ushort
{
CosNormalHalf = 25248,
CosViewHalf = 25249,
CosNormalView = 25250,
CosLightNormal = 25251,
CosLightSpot = 25252,
CosPhi = 25253
}
public enum StencilOp
{
Keep = 7680,
Zero = 0,
Replace = 7681,
Increment = 7682,
Decrement = 7683,
Invert = 5386,
IncrementWrap = 34055,
DecrementWrap = 34055
}
}

View file

@ -265,7 +265,7 @@ namespace FirstPlugin
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return ImageData;
}

View file

@ -201,7 +201,7 @@ namespace FirstPlugin
{
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
if (ContainerParent.Platform == GT1Platform.WiiU)
{

View file

@ -179,11 +179,8 @@ namespace LayoutBXLYT
bntx = BinaryContainers.Values.FirstOrDefault();
}
int startIndex = bntx.Textures.Count - 1;
var importedTextures = bntx.ImportTexture();
Console.WriteLine("startIndex " + startIndex);
//Load all the additional textues
for (int i = 0; i < importedTextures.Count; i++)
textures.Add(importedTextures[i]);

View file

@ -107,7 +107,7 @@ namespace FirstPlugin.LuigisMansion.DarkMoon
throw new NotImplementedException();
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return ImageData;
}

View file

@ -229,7 +229,7 @@ namespace FirstPlugin.LuigisMansion3
UpdateProperties();
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
uint blkHeight = STGenericTexture.GetBlockHeight(Format);
uint blkDepth = STGenericTexture.GetBlockDepth(Format);
@ -245,7 +245,7 @@ namespace FirstPlugin.LuigisMansion3
Console.WriteLine("blockHeight " + blockHeight);
Console.WriteLine("BlockHeightLog2 " + BlockHeightLog2);
return TegraX1Swizzle.GetImageData(this, ImageData, ArrayLevel, MipLevel, BlockHeightLog2, 1);
return TegraX1Swizzle.GetImageData(this, ImageData, ArrayLevel, MipLevel, DepthLevel, BlockHeightLog2, 1);
}
public override TEX_FORMAT[] SupportedFormats

View file

@ -192,7 +192,7 @@ namespace FirstPlugin.NLG
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return Decode_Gamecube.GetMipLevel(ImageData, Width, Height, MipCount, (uint)MipLevel, Format);
}

View file

@ -33,7 +33,7 @@ namespace FirstPlugin.PunchOutWii
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return Decode_Gamecube.GetMipLevel(ImageData, Width, Height, MipCount, (uint)MipLevel, Format);
}

View file

@ -155,7 +155,7 @@ namespace FirstPlugin
//Gets the raw image data in bytes
//Gets decoded automatically
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return Decode_Gamecube.GetMipLevel(ImageData, Width, Height, MipCount, (uint)MipLevel, Format);
}

View file

@ -420,7 +420,7 @@ namespace FirstPlugin
}
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return ImageData;
}

View file

@ -586,7 +586,7 @@ namespace FirstPlugin
}
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
if (image.Is3DS)
{

View file

@ -1236,7 +1236,8 @@ namespace FirstPlugin
Text = tex.Name;
Width = tex.Width;
Height = tex.Height;
ArrayCount = (uint)tex.TextureData.Count;
ArrayCount = tex.Depth;
// ArrayCount = (uint)tex.TextureData.Count;
MipCount = (uint)tex.TextureData[0].Count;
Format = ConvertFormat(tex.Format);
@ -1672,7 +1673,7 @@ namespace FirstPlugin
}
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
int target = 1;
if (ParentBNTX != null && ParentBNTX is BNTX && ParentBNTX.BinaryTexFile != null)
@ -1696,34 +1697,43 @@ namespace FirstPlugin
int linesPerBlockHeight = (1 << (int)Texture.BlockHeightLog2) * 8;
uint bpp = GetBytesPerPixel(Format);
uint numDepth = 1;
if (Depth > 1)
numDepth = Depth;
for (int arrayLevel = 0; arrayLevel < Texture.TextureData.Count; arrayLevel++)
return TegraX1Swizzle.GetImageData(this, Texture.TextureData[0][0], ArrayLevel, MipLevel, DepthLevel, target, Texture.TileMode == TileMode.LinearAligned);
for (int depthLevel = 0; depthLevel < numDepth; depthLevel++)
{
int blockHeightShift = 0;
for (int mipLevel = 0; mipLevel < Texture.TextureData[arrayLevel].Count; mipLevel++)
for (int arrayLevel = 0; arrayLevel < Texture.TextureData.Count; arrayLevel++)
{
uint width = (uint)Math.Max(1, Texture.Width >> mipLevel);
uint height = (uint)Math.Max(1, Texture.Height >> mipLevel);
uint depth = (uint)Math.Max(1, Texture.Depth >> mipLevel);
int blockHeightShift = 0;
uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp;
for (int mipLevel = 0; mipLevel < Texture.TextureData[arrayLevel].Count; mipLevel++)
{
uint width = (uint)Math.Max(1, Texture.Width >> mipLevel);
uint height = (uint)Math.Max(1, Texture.Height >> mipLevel);
uint depth = (uint)Math.Max(1, Texture.Depth >> mipLevel);
if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight)
blockHeightShift += 1;
uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp;
Console.WriteLine($"{width} {height} {depth} {blkWidth} {blkHeight} {blkDepth} {target} {bpp} {Texture.TileMode} {(int)Math.Max(0, Texture.BlockHeightLog2 - blockHeightShift)} {Texture.TextureData[arrayLevel][mipLevel].Length}");
byte[] result = TegraX1Swizzle.deswizzle(width, height, depth, blkWidth, blkHeight, blkDepth, target, bpp, (uint)Texture.TileMode, (int)Math.Max(0, Texture.BlockHeightLog2 - blockHeightShift), Texture.TextureData[arrayLevel][mipLevel]);
//Create a copy and use that to remove uneeded data
byte[] result_ = new byte[size];
Array.Copy(result, 0, result_, 0, size);
if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight)
blockHeightShift += 1;
result = null;
Console.WriteLine($"{width} {height} {depth} {blkWidth} {blkHeight} {blkDepth} {target} {bpp} {Texture.TileMode} {(int)Math.Max(0, Texture.BlockHeightLog2 - blockHeightShift)} {Texture.TextureData[arrayLevel][mipLevel].Length}");
byte[] result = TegraX1Swizzle.deswizzle(width, height, depth, blkWidth, blkHeight, blkDepth, target, bpp, (uint)Texture.TileMode, (int)Math.Max(0, Texture.BlockHeightLog2 - blockHeightShift), Texture.TextureData[arrayLevel][mipLevel]);
//Create a copy and use that to remove uneeded data
byte[] result_ = new byte[size];
Array.Copy(result, 0, result_, 0, size);
if (ArrayLevel == arrayLevel && MipLevel == mipLevel)
return result_;
result = null;
if (ArrayLevel == arrayLevel && MipLevel == mipLevel && DepthLevel == depthLevel)
return result_;
}
}
}
return new byte[0];
}
catch (Exception e)

View file

@ -182,7 +182,7 @@ namespace FirstPlugin
//Gets the raw image data in bytes
//Gets decoded automatically
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return Decode_Gamecube.GetMipLevel(ImageData, Width, Height, MipCount, (uint)MipLevel, Format);
}

View file

@ -126,7 +126,7 @@ namespace FirstPlugin
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return CtpkTexture.ImageData;
}

View file

@ -668,7 +668,7 @@ namespace FirstPlugin
LibraryGUI.UpdateViewport();
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
RedChannel = SetChannel(surface.compSel[0]);
GreenChannel = SetChannel(surface.compSel[1]);

View file

@ -385,7 +385,7 @@ namespace FirstPlugin
throw new NotImplementedException();
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
if (Gx2HeaderData != null)
{

View file

@ -427,6 +427,7 @@ namespace FirstPlugin
//Seek to next one
reader.Seek(mipPos + 0x40, System.IO.SeekOrigin.Begin);
}
reader.Seek(0, System.IO.SeekOrigin.Begin);
ImageData = reader.ReadBytes(imagesize);
}
@ -572,12 +573,12 @@ namespace FirstPlugin
ImageData = Utils.CombineByteArray(mipmaps.ToArray());
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
if (!IsSwizzled)
return DDS.GetArrayFaces(this, ImageData,1)[ArrayLevel].mipmaps[0];
return TegraX1Swizzle.GetImageData(this, ImageData, ArrayLevel, MipLevel, 1);
return TegraX1Swizzle.GetImageData(this, ImageData, ArrayLevel, MipLevel, DepthLevel, 1);
}
STToolStripItem useSizeRestrictions = new STToolStripItem("UseSizeRestrictions");

View file

@ -206,7 +206,7 @@ namespace FirstPlugin
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return ImageData;
}

View file

@ -203,7 +203,7 @@ namespace FirstPlugin
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return ImageData;
}

View file

@ -147,6 +147,8 @@ namespace FirstPlugin
texWrapper.ImageData = reader.getSection(image.ImageOffset,
(uint)Decode_Gamecube.GetDataSize(GXFormat, (int)image.Width, (int)image.Height));
Console.WriteLine($"PaletteHeaderOffset {PaletteHeaderOffset}");
//Palette is sometimes unused to check
if (PaletteHeaderOffset != 0)
{
@ -200,7 +202,7 @@ namespace FirstPlugin
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return Decode_Gamecube.GetMipLevel(ImageData, Width, Height, MipCount, (uint)MipLevel, Format);
}

View file

@ -181,7 +181,7 @@ namespace FirstPlugin
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
if (PlatformSwizzle == PlatformSwizzle.Platform_Switch)
return TegraX1Swizzle.GetImageData(this, ImageData, ArrayLevel, MipLevel, (int)Target);

View file

@ -308,7 +308,7 @@ namespace FirstPlugin
}
private bool hasShownDialog = false;
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
if (Texture.ImageData == null)
{
@ -324,7 +324,7 @@ namespace FirstPlugin
var BlockHeightLog2 = Texture.Info.textureLayout & 7;
return TegraX1Swizzle.GetImageData(this, Texture.ImageData, ArrayLevel, MipLevel, BlockHeightLog2, 1);
return TegraX1Swizzle.GetImageData(this, Texture.ImageData, ArrayLevel, MipLevel, DepthLevel, BlockHeightLog2, 1);
}

View file

@ -728,7 +728,7 @@ namespace FirstPlugin
ImageData = Utils.CombineByteArray(mipmaps.ToArray());
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return TegraX1Swizzle.GetImageData(this, ImageData, ArrayLevel, MipLevel, (int)Target);
}

View file

@ -67,7 +67,7 @@ namespace FirstPlugin
for (int m = 0; m < Meshes.Count; m++)
{
if (((CMB.CMBMaterialWrapper)Meshes[m].GetMaterial()).Material.IsTransparent)
if (((CMB.CMBMaterialWrapper)Meshes[m].GetMaterial()).CMBMaterial.IsTransparent)
transparent.Add(Meshes[m]);
else
opaque.Add(Meshes[m]);
@ -88,7 +88,7 @@ namespace FirstPlugin
public override void SetRenderData(STGenericMaterial mat, ShaderProgram shader, STGenericObject m)
{
var cmbMaterial = ((CMB.CMBMaterialWrapper)mat).Material;
var cmbMaterial = ((CMB.CMBMaterialWrapper)mat).CMBMaterial;
var cmbMesh = ((CMB.CmbMeshWrapper)m);
bool HasNoNormals = cmbMesh.Shape.Normal.VertexData == null || cmbMesh.Shape.Normal.VertexData.Length == 0;

View file

@ -208,7 +208,7 @@ namespace Toolbox.Library
throw new NotImplementedException("Cannot set image data! Operation not implemented!");
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return DataBlock;
}

View file

@ -816,15 +816,15 @@ namespace Toolbox.Library
}
public bool SwitchSwizzle = false;
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
if (IsAtscFormat(Format))
SwitchSwizzle = true;
if (SwitchSwizzle)
return TegraX1Swizzle.GetImageData(this, bdata, ArrayLevel, MipLevel);
return TegraX1Swizzle.GetImageData(this, bdata, ArrayLevel, MipLevel, DepthLevel);
return GetArrayFaces(this, ArrayCount)[ArrayLevel].mipmaps[MipLevel];
return GetArrayFaces(this, ArrayCount, DepthLevel)[ArrayLevel].mipmaps[MipLevel];
}
public override void SetImageData(Bitmap bitmap, int ArrayLevel)
@ -985,8 +985,12 @@ namespace Toolbox.Library
uint formatSize = GetBytesPerPixel(tex.Format);
uint numDepth = 1;
if (tex.Depth > 1)
numDepth = tex.Depth;
uint Offset = 0;
for (byte d = 0; d < tex.Depth; ++d)
for (byte d = 0; d < numDepth; ++d)
{
for (byte i = 0; i < Length; ++i)
{
@ -1021,7 +1025,7 @@ namespace Toolbox.Library
}
}
public static List<Surface> GetArrayFaces(DDS dds, uint Length)
public static List<Surface> GetArrayFaces(DDS dds, uint Length, int DepthLevel = 0)
{
using (FileReader reader = new FileReader(dds.bdata))
{
@ -1034,32 +1038,37 @@ namespace Toolbox.Library
dds.header.mipmapCount = 1;
uint Offset = 0;
for (byte i = 0; i < Length; ++i)
for (byte d = 0; d < dds.Depth; ++d)
{
var Surface = new STGenericTexture.Surface();
uint MipWidth = dds.header.width, MipHeight = dds.header.height;
for (int j = 0; j < dds.header.mipmapCount; ++j)
for (byte i = 0; i < Length; ++i)
{
MipWidth = (uint)Math.Max(1, dds.header.width >> j);
MipHeight = (uint)Math.Max(1, dds.header.height >> j);
var Surface = new STGenericTexture.Surface();
uint size = (MipWidth * MipHeight); //Total pixels
if (isBlock)
uint MipWidth = dds.header.width, MipHeight = dds.header.height;
for (int j = 0; j < dds.header.mipmapCount; ++j)
{
size = ((MipWidth + 3) >> 2) * ((MipHeight + 3) >> 2) * formatSize;
if (size < formatSize)
size = formatSize;
}
else
{
size = (uint)(size * (GetBytesPerPixel(dds.Format))); //Bytes per pixel
MipWidth = (uint)Math.Max(1, dds.header.width >> j);
MipHeight = (uint)Math.Max(1, dds.header.height >> j);
uint size = (MipWidth * MipHeight); //Total pixels
if (isBlock)
{
size = ((MipWidth + 3) >> 2) * ((MipHeight + 3) >> 2) * formatSize;
if (size < formatSize)
size = formatSize;
}
else
{
size = (uint)(size * (GetBytesPerPixel(dds.Format))); //Bytes per pixel
}
Surface.mipmaps.Add(reader.getSection((int)Offset, (int)size));
Offset += size;
}
Surface.mipmaps.Add(reader.getSection((int)Offset, (int)size));
Offset += size;
if (d == DepthLevel)
Surfaces.Add(Surface);
}
Surfaces.Add(Surface);
}
return Surfaces;

View file

@ -104,7 +104,7 @@ namespace Toolbox.Library
throw new NotImplementedException("Cannot set image data! Operation not implemented!");
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
if (TargaImage == null || TargaImage.Image == null) return new byte[0];

View file

@ -66,7 +66,7 @@ namespace Toolbox.Library
ImageData = DDSCompressor.EncodePixelBlock(Data, bitmap.Width, bitmap.Width, DDS.DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
return ImageData;
}

View file

@ -191,7 +191,7 @@ namespace Toolbox.Library
public string DataSize { get { return STMath.GetFileSize(DataSizeInBytes, 5); } }
public abstract byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0);
public abstract byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0);
private byte[] paletteData = new byte[0];
@ -493,18 +493,40 @@ namespace Toolbox.Library
}
}
public Bitmap GetBitmap3D(int ArrayLevel = 0, int MipLevel = 0)
{
List<Bitmap> images = new List<Bitmap>();
for (int i = 0; i < Depth; i++)
images.Add(GetBitmap(ArrayLevel, MipLevel, i));
//Combine images in a horizontal pattern
uint width = Width * Depth;
var newBitmap = new Bitmap((int)width, (int)Height);
using (Graphics grfx = Graphics.FromImage(newBitmap))
{
int x = 0;
foreach (var image in images) {
grfx.DrawImage(image, x, 0);
x += image.Width;
}
return newBitmap;
}
}
/// <summary>
/// Gets a <see cref="Bitmap"/> given an array and mip index.
/// </summary>
/// <param name="ArrayIndex">The index of the surface/array. Cubemaps will have 6</param>
/// <param name="MipLevel">The index of the mip level.</param>
/// <returns></returns>
public Bitmap GetBitmap(int ArrayLevel = 0, int MipLevel = 0)
public Bitmap GetBitmap(int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0)
{
uint width = Math.Max(1, Width >> MipLevel);
uint height = Math.Max(1, Height >> MipLevel);
byte[] data = GetImageData(ArrayLevel, MipLevel);
byte[] data = GetImageData(ArrayLevel, MipLevel, DepthLevel);
byte[] paletteData = GetPaletteData();
if (Format == TEX_FORMAT.R8G8B8A8_UNORM) return BitmapExtension.GetBitmap(ConvertBgraToRgba(data), (int)width, (int)height);
try
{

View file

@ -68,16 +68,16 @@ namespace Toolbox.Library
return MipMapSizes;
}
public static byte[] GetImageData(STGenericTexture texture, byte[] ImageData, int ArrayLevel, int MipLevel, int target = 1, bool LinearTileMode = false)
public static byte[] GetImageData(STGenericTexture texture, byte[] ImageData, int ArrayLevel, int MipLevel, int DepthLevel, int target = 1, bool LinearTileMode = false)
{
uint blkHeight = STGenericTexture.GetBlockHeight(texture.Format);
uint blkDepth = STGenericTexture.GetBlockDepth(texture.Format);
uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.DIV_ROUND_UP(texture.Height, blkHeight));
uint BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1;
return GetImageData(texture, ImageData, ArrayLevel, MipLevel, BlockHeightLog2, target, LinearTileMode);
return GetImageData(texture, ImageData, ArrayLevel, MipLevel, DepthLevel, BlockHeightLog2, target, LinearTileMode);
}
public static byte[] GetImageData(STGenericTexture texture, byte[] ImageData, int ArrayLevel, int MipLevel, uint BlockHeightLog2, int target = 1, bool LinearTileMode = false)
public static byte[] GetImageData(STGenericTexture texture, byte[] ImageData, int ArrayLevel, int MipLevel, int DepthLevel, uint BlockHeightLog2, int target = 1, bool LinearTileMode = false)
{
uint bpp = STGenericTexture.GetBytesPerPixel(texture.Format);
uint blkWidth = STGenericTexture.GetBlockWidth(texture.Format);
@ -90,68 +90,73 @@ namespace Toolbox.Library
uint TileMode = 0;
if (LinearTileMode)
TileMode = 1;
uint numDepth = 1;
if (texture.Depth > 1)
numDepth = texture.Depth;
int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8;
uint ArrayOffset = 0;
for (int arrayLevel = 0; arrayLevel < texture.ArrayCount; arrayLevel++)
for (int depthLevel = 0; depthLevel < numDepth; depthLevel++)
{
uint SurfaceSize = 0;
int blockHeightShift = 0;
List<uint> MipOffsets = new List<uint>();
for (int mipLevel = 0; mipLevel < texture.MipCount; mipLevel++)
for (int arrayLevel = 0; arrayLevel < texture.ArrayCount; arrayLevel++)
{
uint width = (uint)Math.Max(1, texture.Width >> mipLevel);
uint height = (uint)Math.Max(1, texture.Height >> mipLevel);
uint depth = (uint)Math.Max(1, texture.Depth >> mipLevel);
uint SurfaceSize = 0;
int blockHeightShift = 0;
uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp;
List<uint> MipOffsets = new List<uint>();
Console.WriteLine($"size " + size);
if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight)
blockHeightShift += 1;
uint width__ = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth);
uint height__ = TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight);
//Calculate the mip size instead
byte[] AlignedData = new byte[(TegraX1Swizzle.round_up(SurfaceSize, DataAlignment) - SurfaceSize)];
SurfaceSize += (uint)AlignedData.Length;
MipOffsets.Add(SurfaceSize);
//Get the first mip offset and current one and the total image size
int msize = (int)((MipOffsets[0] + ImageData.Length - MipOffsets[mipLevel]) / texture.ArrayCount);
byte[] data_ = Utils.SubArray(ImageData, ArrayOffset + MipOffsets[mipLevel], (uint)msize);
try
for (int mipLevel = 0; mipLevel < texture.MipCount; mipLevel++)
{
Pitch = TegraX1Swizzle.round_up(width__ * bpp, 64);
SurfaceSize += Pitch * TegraX1Swizzle.round_up(height__, Math.Max(1, blockHeight >> blockHeightShift) * 8);
uint width = (uint)Math.Max(1, texture.Width >> mipLevel);
uint height = (uint)Math.Max(1, texture.Height >> mipLevel);
uint depth = (uint)Math.Max(1, texture.Depth >> mipLevel);
byte[] result = TegraX1Swizzle.deswizzle(width, height, depth, blkWidth, blkHeight, blkDepth, target, bpp, TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), data_);
//Create a copy and use that to remove uneeded data
byte[] result_ = new byte[size];
Array.Copy(result, 0, result_, 0, size);
result = null;
uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp;
if (ArrayLevel == arrayLevel && MipLevel == mipLevel)
return result_;
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show($"Failed to swizzle texture {texture.Text}!");
Console.WriteLine(e);
return new byte[0];
Console.WriteLine($"size " + size);
if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight)
blockHeightShift += 1;
uint width__ = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth);
uint height__ = TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight);
//Calculate the mip size instead
byte[] AlignedData = new byte[(TegraX1Swizzle.round_up(SurfaceSize, DataAlignment) - SurfaceSize)];
SurfaceSize += (uint)AlignedData.Length;
MipOffsets.Add(SurfaceSize);
//Get the first mip offset and current one and the total image size
int msize = (int)((MipOffsets[0] + ImageData.Length - MipOffsets[mipLevel]) / texture.ArrayCount);
byte[] data_ = Utils.SubArray(ImageData, ArrayOffset + MipOffsets[mipLevel], (uint)msize);
try
{
Pitch = TegraX1Swizzle.round_up(width__ * bpp, 64);
SurfaceSize += Pitch * TegraX1Swizzle.round_up(height__, Math.Max(1, blockHeight >> blockHeightShift) * 8);
byte[] result = TegraX1Swizzle.deswizzle(width, height, depth, blkWidth, blkHeight, blkDepth, target, bpp, TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), data_);
//Create a copy and use that to remove uneeded data
byte[] result_ = new byte[size];
Array.Copy(result, 0, result_, 0, size);
result = null;
if (ArrayLevel == arrayLevel && MipLevel == mipLevel && DepthLevel == depthLevel)
return result_;
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show($"Failed to swizzle texture {texture.Text}!");
Console.WriteLine(e);
return new byte[0];
}
}
ArrayOffset += (uint)(ImageData.Length / texture.ArrayCount);
}
ArrayOffset += (uint)(ImageData.Length / texture.ArrayCount);
}
return new byte[0];
}
@ -222,7 +227,7 @@ namespace Toolbox.Library
for (uint y = 0; y < height; y++)
{
for (uint x = 0; x < width; x++)
for (uint x = 0; x < width; x++)
{
uint pos;
uint pos_;