mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-25 05:40:21 -04:00
Add support for swizzled Switch textures
Co-Authored-By: nesrak1 <12544505+nesrak1@users.noreply.github.com>
This commit is contained in:
parent
4cd246592b
commit
ae4548f1c3
@ -14,12 +14,13 @@ namespace AssetStudio
|
|||||||
public int m_MipCount;
|
public int m_MipCount;
|
||||||
public GLTextureSettings m_TextureSettings;
|
public GLTextureSettings m_TextureSettings;
|
||||||
public int m_ImageCount;
|
public int m_ImageCount;
|
||||||
|
public byte[] m_PlatformBlob;
|
||||||
public ResourceReader image_data;
|
public ResourceReader image_data;
|
||||||
public StreamingInfo m_StreamData;
|
public StreamingInfo m_StreamData;
|
||||||
|
|
||||||
public Texture2D() { }
|
public Texture2D() { }
|
||||||
|
|
||||||
public Texture2D(Texture2DArray m_Texture2DArray, int layer)
|
public Texture2D(Texture2DArray m_Texture2DArray, int layer) // Texture2DArrayImage
|
||||||
{
|
{
|
||||||
reader = m_Texture2DArray.reader;
|
reader = m_Texture2DArray.reader;
|
||||||
assetsFile = m_Texture2DArray.assetsFile;
|
assetsFile = m_Texture2DArray.assetsFile;
|
||||||
@ -63,6 +64,7 @@ namespace AssetStudio
|
|||||||
m_ImageCount = parsedTex2d.m_ImageCount;
|
m_ImageCount = parsedTex2d.m_ImageCount;
|
||||||
m_TextureSettings = parsedTex2d.m_TextureSettings;
|
m_TextureSettings = parsedTex2d.m_TextureSettings;
|
||||||
m_StreamData = parsedTex2d.m_StreamData;
|
m_StreamData = parsedTex2d.m_StreamData;
|
||||||
|
m_PlatformBlob = parsedTex2d.m_PlatformBlob ?? Array.Empty<byte>();
|
||||||
|
|
||||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
||||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
||||||
@ -141,9 +143,13 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
|
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
|
||||||
{
|
{
|
||||||
var m_PlatformBlob = reader.ReadUInt8Array();
|
m_PlatformBlob = reader.ReadUInt8Array();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_PlatformBlob = Array.Empty<byte>();
|
||||||
|
}
|
||||||
var image_data_size = reader.ReadInt32();
|
var image_data_size = reader.ReadInt32();
|
||||||
if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up
|
if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up
|
||||||
{
|
{
|
||||||
|
@ -932,6 +932,8 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var switchSwizzled = m_Texture2D.m_PlatformBlob.Length != 0;
|
||||||
|
assetItem.InfoText += assetItem.Asset.platform == BuildTarget.Switch ? $"\nUses texture swizzling: {switchSwizzled}" : "";
|
||||||
PreviewTexture(bitmap);
|
PreviewTexture(bitmap);
|
||||||
|
|
||||||
StatusStripUpdate("'Ctrl'+'R'/'G'/'B'/'A' for Channel Toggle");
|
StatusStripUpdate("'Ctrl'+'R'/'G'/'B'/'A' for Channel Toggle");
|
||||||
|
@ -9,20 +9,74 @@ namespace AssetStudio
|
|||||||
private ResourceReader reader;
|
private ResourceReader reader;
|
||||||
private int m_Width;
|
private int m_Width;
|
||||||
private int m_Height;
|
private int m_Height;
|
||||||
|
private int m_WidthCrop;
|
||||||
|
private int m_HeightCrop;
|
||||||
private TextureFormat m_TextureFormat;
|
private TextureFormat m_TextureFormat;
|
||||||
|
private byte[] m_PlatformBlob;
|
||||||
private int[] version;
|
private int[] version;
|
||||||
private BuildTarget platform;
|
private BuildTarget platform;
|
||||||
public int outPutSize;
|
private int outPutDataSize;
|
||||||
|
|
||||||
|
private bool switchSwizzled;
|
||||||
|
private int gobsPerBlock;
|
||||||
|
private SixLabors.ImageSharp.Size blockSize;
|
||||||
|
|
||||||
|
public int OutputDataSize => outPutDataSize;
|
||||||
|
public bool UsesSwitchSwizzle => switchSwizzled;
|
||||||
|
|
||||||
public Texture2DConverter(Texture2D m_Texture2D)
|
public Texture2DConverter(Texture2D m_Texture2D)
|
||||||
{
|
{
|
||||||
reader = m_Texture2D.image_data;
|
reader = m_Texture2D.image_data;
|
||||||
m_Width = m_Texture2D.m_Width;
|
m_WidthCrop = m_Texture2D.m_Width;
|
||||||
m_Height = m_Texture2D.m_Height;
|
m_HeightCrop = m_Texture2D.m_Height;
|
||||||
m_TextureFormat = m_Texture2D.m_TextureFormat;
|
m_TextureFormat = m_Texture2D.m_TextureFormat;
|
||||||
|
m_PlatformBlob = m_Texture2D.m_PlatformBlob;
|
||||||
version = m_Texture2D.version;
|
version = m_Texture2D.version;
|
||||||
platform = m_Texture2D.platform;
|
platform = m_Texture2D.platform;
|
||||||
outPutSize = m_Width * m_Height * 4;
|
// not guaranteed, you can have a swizzled texture without m_PlatformBlob
|
||||||
|
// but officially, I don't think this can happen. maybe check which engine
|
||||||
|
// version this started happening in...
|
||||||
|
switchSwizzled = platform == BuildTarget.Switch && m_PlatformBlob.Length != 0;
|
||||||
|
if (switchSwizzled)
|
||||||
|
{
|
||||||
|
SetupSwitchSwizzle();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Width = m_WidthCrop;
|
||||||
|
m_Height = m_HeightCrop;
|
||||||
|
}
|
||||||
|
outPutDataSize = m_Width * m_Height * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupSwitchSwizzle()
|
||||||
|
{
|
||||||
|
//apparently there is another value to worry about, but seeing as it's
|
||||||
|
//always 0 and I have nothing else to test against, this will probably
|
||||||
|
//work fine for now
|
||||||
|
gobsPerBlock = 1 << BitConverter.ToInt32(m_PlatformBlob, 8);
|
||||||
|
|
||||||
|
//in older versions of unity, rgb24 has a platformBlob which shouldn't
|
||||||
|
//be possible. it turns out in this case, the image is just rgba32.
|
||||||
|
//probably shouldn't be modifying the texture2d here, but eh, who cares
|
||||||
|
if (m_TextureFormat == TextureFormat.RGB24)
|
||||||
|
{
|
||||||
|
m_TextureFormat = TextureFormat.RGBA32;
|
||||||
|
}
|
||||||
|
else if (m_TextureFormat == TextureFormat.BGR24)
|
||||||
|
{
|
||||||
|
m_TextureFormat = TextureFormat.BGRA32;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockSize = Texture2DSwitchDeswizzler.GetTextureFormatBlockSize(m_TextureFormat);
|
||||||
|
var realSize = Texture2DSwitchDeswizzler.GetPaddedTextureSize(m_WidthCrop, m_HeightCrop, blockSize.Width, blockSize.Height, gobsPerBlock);
|
||||||
|
m_Width = realSize.Width;
|
||||||
|
m_Height = realSize.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SixLabors.ImageSharp.Size GetUncroppedSize()
|
||||||
|
{
|
||||||
|
return new SixLabors.ImageSharp.Size(m_Width, m_Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DecodeTexture2D(byte[] bytes)
|
public bool DecodeTexture2D(byte[] bytes)
|
||||||
@ -36,6 +90,11 @@ namespace AssetStudio
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
reader.GetData(buff);
|
reader.GetData(buff);
|
||||||
|
if (switchSwizzled)
|
||||||
|
{
|
||||||
|
buff = Texture2DSwitchDeswizzler.Unswizzle(buff, GetUncroppedSize(), blockSize, gobsPerBlock);
|
||||||
|
}
|
||||||
|
|
||||||
switch (m_TextureFormat)
|
switch (m_TextureFormat)
|
||||||
{
|
{
|
||||||
case TextureFormat.Alpha8: //test pass
|
case TextureFormat.Alpha8: //test pass
|
||||||
@ -275,7 +334,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeRGBA32(byte[] image_data, byte[] buff)
|
private bool DecodeRGBA32(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = image_data[i + 2];
|
buff[i] = image_data[i + 2];
|
||||||
buff[i + 1] = image_data[i + 1];
|
buff[i + 1] = image_data[i + 1];
|
||||||
@ -287,7 +346,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeARGB32(byte[] image_data, byte[] buff)
|
private bool DecodeARGB32(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = image_data[i + 3];
|
buff[i] = image_data[i + 3];
|
||||||
buff[i + 1] = image_data[i + 2];
|
buff[i + 1] = image_data[i + 2];
|
||||||
@ -354,7 +413,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeBGRA32(byte[] image_data, byte[] buff)
|
private bool DecodeBGRA32(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = image_data[i];
|
buff[i] = image_data[i];
|
||||||
buff[i + 1] = image_data[i + 1];
|
buff[i + 1] = image_data[i + 1];
|
||||||
@ -366,7 +425,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeRHalf(byte[] image_data, byte[] buff)
|
private bool DecodeRHalf(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = 0;
|
buff[i] = 0;
|
||||||
buff[i + 1] = 0;
|
buff[i + 1] = 0;
|
||||||
@ -378,7 +437,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeRGHalf(byte[] image_data, byte[] buff)
|
private bool DecodeRGHalf(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = 0;
|
buff[i] = 0;
|
||||||
buff[i + 1] = (byte)Math.Round(Half.ToHalf(image_data, i + 2) * 255f);
|
buff[i + 1] = (byte)Math.Round(Half.ToHalf(image_data, i + 2) * 255f);
|
||||||
@ -390,7 +449,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeRGBAHalf(byte[] image_data, byte[] buff)
|
private bool DecodeRGBAHalf(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = (byte)Math.Round(Half.ToHalf(image_data, i * 2 + 4) * 255f);
|
buff[i] = (byte)Math.Round(Half.ToHalf(image_data, i * 2 + 4) * 255f);
|
||||||
buff[i + 1] = (byte)Math.Round(Half.ToHalf(image_data, i * 2 + 2) * 255f);
|
buff[i + 1] = (byte)Math.Round(Half.ToHalf(image_data, i * 2 + 2) * 255f);
|
||||||
@ -402,7 +461,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeRFloat(byte[] image_data, byte[] buff)
|
private bool DecodeRFloat(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = 0;
|
buff[i] = 0;
|
||||||
buff[i + 1] = 0;
|
buff[i + 1] = 0;
|
||||||
@ -414,7 +473,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeRGFloat(byte[] image_data, byte[] buff)
|
private bool DecodeRGFloat(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = 0;
|
buff[i] = 0;
|
||||||
buff[i + 1] = (byte)Math.Round(BitConverter.ToSingle(image_data, i * 2 + 4) * 255f);
|
buff[i + 1] = (byte)Math.Round(BitConverter.ToSingle(image_data, i * 2 + 4) * 255f);
|
||||||
@ -426,7 +485,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeRGBAFloat(byte[] image_data, byte[] buff)
|
private bool DecodeRGBAFloat(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = (byte)Math.Round(BitConverter.ToSingle(image_data, i * 4 + 8) * 255f);
|
buff[i] = (byte)Math.Round(BitConverter.ToSingle(image_data, i * 4 + 8) * 255f);
|
||||||
buff[i + 1] = (byte)Math.Round(BitConverter.ToSingle(image_data, i * 4 + 4) * 255f);
|
buff[i + 1] = (byte)Math.Round(BitConverter.ToSingle(image_data, i * 4 + 4) * 255f);
|
||||||
@ -474,7 +533,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeRGB9e5Float(byte[] image_data, byte[] buff)
|
private bool DecodeRGB9e5Float(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
var n = BitConverter.ToInt32(image_data, i);
|
var n = BitConverter.ToInt32(image_data, i);
|
||||||
var scale = n >> 27 & 0x1f;
|
var scale = n >> 27 & 0x1f;
|
||||||
@ -652,7 +711,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeRG32(byte[] image_data, byte[] buff)
|
private bool DecodeRG32(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = 0; //b
|
buff[i] = 0; //b
|
||||||
buff[i + 1] = DownScaleFrom16BitTo8Bit(BitConverter.ToUInt16(image_data, i + 2)); //g
|
buff[i + 1] = DownScaleFrom16BitTo8Bit(BitConverter.ToUInt16(image_data, i + 2)); //g
|
||||||
@ -677,7 +736,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private bool DecodeRGBA64(byte[] image_data, byte[] buff)
|
private bool DecodeRGBA64(byte[] image_data, byte[] buff)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < outPutSize; i += 4)
|
for (var i = 0; i < outPutDataSize; i += 4)
|
||||||
{
|
{
|
||||||
buff[i] = DownScaleFrom16BitTo8Bit(BitConverter.ToUInt16(image_data, i * 2 + 4)); //b
|
buff[i] = DownScaleFrom16BitTo8Bit(BitConverter.ToUInt16(image_data, i * 2 + 4)); //b
|
||||||
buff[i + 1] = DownScaleFrom16BitTo8Bit(BitConverter.ToUInt16(image_data, i * 2 + 2)); //g
|
buff[i + 1] = DownScaleFrom16BitTo8Bit(BitConverter.ToUInt16(image_data, i * 2 + 2)); //g
|
||||||
|
@ -10,20 +10,30 @@ namespace AssetStudio
|
|||||||
public static Image<Bgra32> ConvertToImage(this Texture2D m_Texture2D, bool flip)
|
public static Image<Bgra32> ConvertToImage(this Texture2D m_Texture2D, bool flip)
|
||||||
{
|
{
|
||||||
var converter = new Texture2DConverter(m_Texture2D);
|
var converter = new Texture2DConverter(m_Texture2D);
|
||||||
var buff = BigArrayPool<byte>.Shared.Rent(converter.outPutSize);
|
var uncroppedSize = converter.GetUncroppedSize();
|
||||||
|
var buff = BigArrayPool<byte>.Shared.Rent(converter.OutputDataSize);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (converter.DecodeTexture2D(buff))
|
if (!converter.DecodeTexture2D(buff))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Image<Bgra32> image;
|
||||||
|
if (converter.UsesSwitchSwizzle)
|
||||||
{
|
{
|
||||||
var image = Image.LoadPixelData<Bgra32>(buff, m_Texture2D.m_Width, m_Texture2D.m_Height);
|
image = Image.LoadPixelData<Bgra32>(buff, uncroppedSize.Width, uncroppedSize.Height);
|
||||||
|
image.Mutate(x => x.Crop(m_Texture2D.m_Width, m_Texture2D.m_Height));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
image = Image.LoadPixelData<Bgra32>(buff, m_Texture2D.m_Width, m_Texture2D.m_Height);
|
||||||
|
}
|
||||||
|
|
||||||
if (flip)
|
if (flip)
|
||||||
{
|
{
|
||||||
image.Mutate(x => x.Flip(FlipMode.Vertical));
|
image.Mutate(x => x.Flip(FlipMode.Vertical));
|
||||||
}
|
}
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
BigArrayPool<byte>.Shared.Return(buff, clearArray: true);
|
BigArrayPool<byte>.Shared.Return(buff, clearArray: true);
|
||||||
|
129
AssetStudioUtility/Texture2DSwitchDeswizzler.cs
Normal file
129
AssetStudioUtility/Texture2DSwitchDeswizzler.cs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// https://github.com/nesrak1/AssetStudio/tree/switch-tex-deswizzle
|
||||||
|
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public class Texture2DSwitchDeswizzler
|
||||||
|
{
|
||||||
|
// referring to block here as a compressed texture block, not a gob one
|
||||||
|
const int GOB_X_TEXEL_COUNT = 4;
|
||||||
|
const int GOB_Y_TEXEL_COUNT = 8;
|
||||||
|
const int TEXEL_BYTE_SIZE = 16;
|
||||||
|
const int BLOCKS_IN_GOB = GOB_X_TEXEL_COUNT * GOB_Y_TEXEL_COUNT;
|
||||||
|
static readonly int[] GOB_X_POSES = {
|
||||||
|
0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3
|
||||||
|
};
|
||||||
|
static readonly int[] GOB_Y_POSES = {
|
||||||
|
0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, 0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
sector:
|
||||||
|
A
|
||||||
|
B
|
||||||
|
|
||||||
|
gob (made of sectors):
|
||||||
|
ABIJ
|
||||||
|
CDKL
|
||||||
|
EFMN
|
||||||
|
GHOP
|
||||||
|
|
||||||
|
gob blocks (example with height 2):
|
||||||
|
ACEGIK... from left to right of image
|
||||||
|
BDFHJL...
|
||||||
|
--------- start new row of blocks
|
||||||
|
MOQSUW...
|
||||||
|
NPRTVX...
|
||||||
|
*/
|
||||||
|
|
||||||
|
private static int CeilDivide(int a, int b)
|
||||||
|
{
|
||||||
|
return (a + b - 1) / b;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static byte[] Unswizzle(byte[] data, Size imageSize, Size blockSize, int gobsPerBlock)
|
||||||
|
{
|
||||||
|
byte[] newData = new byte[data.Length];
|
||||||
|
|
||||||
|
int width = imageSize.Width;
|
||||||
|
int height = imageSize.Height;
|
||||||
|
|
||||||
|
int blockCountX = CeilDivide(width, blockSize.Width);
|
||||||
|
int blockCountY = CeilDivide(height, blockSize.Height);
|
||||||
|
|
||||||
|
int gobCountX = blockCountX / GOB_X_TEXEL_COUNT;
|
||||||
|
int gobCountY = blockCountY / GOB_Y_TEXEL_COUNT;
|
||||||
|
|
||||||
|
int srcPos = 0;
|
||||||
|
for (int i = 0; i < gobCountY / gobsPerBlock; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < gobCountX; j++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < gobsPerBlock; k++)
|
||||||
|
{
|
||||||
|
for (int l = 0; l < BLOCKS_IN_GOB; l++)
|
||||||
|
{
|
||||||
|
int gobX = GOB_X_POSES[l];
|
||||||
|
int gobY = GOB_Y_POSES[l];
|
||||||
|
int gobDstX = j * GOB_X_TEXEL_COUNT + gobX;
|
||||||
|
int gobDstY = (i * gobsPerBlock + k) * GOB_Y_TEXEL_COUNT + gobY;
|
||||||
|
int gobDstLinPos = gobDstY * blockCountX * TEXEL_BYTE_SIZE + gobDstX * TEXEL_BYTE_SIZE;
|
||||||
|
|
||||||
|
Array.Copy(data, srcPos, newData, gobDstLinPos, TEXEL_BYTE_SIZE);
|
||||||
|
|
||||||
|
srcPos += TEXEL_BYTE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newData;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this should be the amount of pixels that can fit 16 bytes
|
||||||
|
internal static Size GetTextureFormatBlockSize(TextureFormat m_TextureFormat)
|
||||||
|
{
|
||||||
|
switch (m_TextureFormat)
|
||||||
|
{
|
||||||
|
case TextureFormat.Alpha8: return new Size(16, 1); // 1 byte per pixel
|
||||||
|
case TextureFormat.ARGB4444: return new Size(8, 1); // 2 bytes per pixel
|
||||||
|
case TextureFormat.RGBA32: return new Size(4, 1); // 4 bytes per pixel
|
||||||
|
case TextureFormat.ARGB32: return new Size(4, 1); // 4 bytes per pixel
|
||||||
|
case TextureFormat.ARGBFloat: return new Size(1, 1); // 16 bytes per pixel (?)
|
||||||
|
case TextureFormat.RGB565: return new Size(8, 1); // 2 bytes per pixel
|
||||||
|
case TextureFormat.R16: return new Size(8, 1); // 2 bytes per pixel
|
||||||
|
case TextureFormat.DXT1: return new Size(8, 4); // 8 bytes per 4x4=16 pixels
|
||||||
|
case TextureFormat.DXT5: return new Size(4, 4); // 16 bytes per 4x4=16 pixels
|
||||||
|
case TextureFormat.RGBA4444: return new Size(8, 1); // 2 bytes per pixel
|
||||||
|
case TextureFormat.BGRA32: return new Size(4, 1); // 4 bytes per pixel
|
||||||
|
case TextureFormat.BC6H: return new Size(4, 4); // 16 bytes per 4x4=16 pixels
|
||||||
|
case TextureFormat.BC7: return new Size(4, 4); // 16 bytes per 4x4=16 pixels
|
||||||
|
case TextureFormat.BC4: return new Size(8, 4); // 8 bytes per 4x4=16 pixels
|
||||||
|
case TextureFormat.BC5: return new Size(4, 4); // 16 bytes per 4x4=16 pixels
|
||||||
|
case TextureFormat.ASTC_RGB_4x4: return new Size(4, 4); // 16 bytes per 4x4=16 pixels
|
||||||
|
case TextureFormat.ASTC_RGB_5x5: return new Size(5, 5); // 16 bytes per 5x5=25 pixels
|
||||||
|
case TextureFormat.ASTC_RGB_6x6: return new Size(6, 6); // 16 bytes per 6x6=36 pixels
|
||||||
|
case TextureFormat.ASTC_RGB_8x8: return new Size(8, 8); // 16 bytes per 8x8=64 pixels
|
||||||
|
case TextureFormat.ASTC_RGB_10x10: return new Size(10, 10); // 16 bytes per 10x10=100 pixels
|
||||||
|
case TextureFormat.ASTC_RGB_12x12: return new Size(12, 12); // 16 bytes per 12x12=144 pixels
|
||||||
|
case TextureFormat.ASTC_RGBA_4x4: return new Size(4, 4); // 16 bytes per 4x4=16 pixels
|
||||||
|
case TextureFormat.ASTC_RGBA_5x5: return new Size(5, 5); // 16 bytes per 5x5=25 pixels
|
||||||
|
case TextureFormat.ASTC_RGBA_6x6: return new Size(6, 6); // 16 bytes per 6x6=36 pixels
|
||||||
|
case TextureFormat.ASTC_RGBA_8x8: return new Size(8, 8); // 16 bytes per 8x8=64 pixels
|
||||||
|
case TextureFormat.ASTC_RGBA_10x10: return new Size(10, 10); // 16 bytes per 10x10=100 pixels
|
||||||
|
case TextureFormat.ASTC_RGBA_12x12: return new Size(12, 12); // 16 bytes per 12x12=144 pixels
|
||||||
|
case TextureFormat.RG16: return new Size(8, 1); // 2 bytes per pixel
|
||||||
|
case TextureFormat.R8: return new Size(16, 1); // 1 byte per pixel
|
||||||
|
default: throw new NotImplementedException();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Size GetPaddedTextureSize(int width, int height, int blockWidth, int blockHeight, int gobsPerBlock)
|
||||||
|
{
|
||||||
|
width = CeilDivide(width, blockWidth * GOB_X_TEXEL_COUNT) * blockWidth * GOB_X_TEXEL_COUNT;
|
||||||
|
height = CeilDivide(height, blockHeight * GOB_Y_TEXEL_COUNT * gobsPerBlock) * blockHeight * GOB_Y_TEXEL_COUNT * gobsPerBlock;
|
||||||
|
return new Size(width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user