public Texture FromBitMap(List <byte[]> arrayFaces, TextureImporterSettings settings) { Texture tex = new Texture(); tex.Height = (uint)settings.TexHeight; tex.Width = (uint)settings.TexWidth; tex.Format = Format; tex.Name = settings.TexName; tex.Path = ""; tex.TextureData = new List <List <byte[]> >(); if (settings.MipCount == 0) { settings.MipCount = 1; } STChannelType[] channels = STGenericTexture.SetChannelsByFormat(TextureData.ConvertFormat(settings.Format)); tex.ChannelRed = ConvertChannel(channels[0]); tex.ChannelGreen = ConvertChannel(channels[1]); tex.ChannelBlue = ConvertChannel(channels[2]); tex.ChannelAlpha = ConvertChannel(channels[3]); tex.sparseBinding = settings.sparseBinding; tex.sparseResidency = settings.sparseResidency; tex.AccessFlags = settings.AccessFlags; tex.ArrayLength = settings.arrayLength; tex.MipCount = settings.MipCount; tex.Depth = settings.Depth; tex.Dim = settings.Dim; tex.Flags = settings.Flags; tex.TileMode = settings.TileMode; tex.textureLayout = settings.TextureLayout; tex.textureLayout2 = settings.TextureLayout2; tex.Swizzle = settings.Swizzle; tex.SurfaceDim = settings.SurfaceDim; tex.SampleCount = settings.SampleCount; tex.Regs = settings.Regs; tex.Pitch = settings.Pitch; tex.MipOffsets = new long[tex.MipCount]; for (int i = 0; i < arrayFaces.Count; i++) { List <byte[]> mipmaps = SwizzleSurfaceMipMaps(tex, arrayFaces[i], tex.MipCount); tex.TextureData.Add(mipmaps); //Combine mip map data byte[] combinedMips = Utils.CombineByteArray(mipmaps.ToArray()); tex.TextureData[i][0] = combinedMips; } return(tex); }
public void SetupSettings(TextureImporterSettings setting) { if (setting.Format == SurfaceFormat.Invalid || SelectedIndex == -1) { return; } WidthLabel.Text = $"Width: {setting.TexWidth}"; HeightLabel.Text = $"Height: {setting.TexHeight}"; if (Thread != null && Thread.IsAlive) { Thread.Abort(); } if (formatComboBox.SelectedItem is SurfaceDim) { setting.SurfaceDim = (SurfaceDim)formatComboBox.SelectedItem; } if (formatComboBox.SelectedItem is SurfaceFormat) { setting.Format = (SurfaceFormat)formatComboBox.SelectedItem; listViewCustom1.Items[SelectedIndex].SubItems[1].Text = setting.Format.ToString(); } if (setting.Format == SurfaceFormat.BC7_UNORM || setting.Format == SurfaceFormat.BC7_SRGB) { compressionModeCB.Visible = true; compModeLbl.Visible = true; } else { compressionModeCB.Visible = false; compModeLbl.Visible = false; } Bitmap bitmap = Toolbox.Library.Imaging.GetLoadingImage(); if (compressionModeCB.SelectedIndex == 0) { CompressionMode = STCompressionMode.Fast; } else { CompressionMode = STCompressionMode.Normal; } Thread = new Thread((ThreadStart)(() => { setting.IsFinishedCompressing = false; ToggleOkButton(false); pictureBox1.Image = bitmap; var mips = setting.GenerateMipList(CompressionMode); setting.DataBlockOutput.Clear(); setting.DataBlockOutput.Add(Utils.CombineByteArray(mips.ToArray())); ToggleOkButton(true); setting.IsFinishedCompressing = true; if (setting.DataBlockOutput.Count > 0) { if (setting.Format == SurfaceFormat.BC5_SNORM) { bitmap = DDSCompressor.DecompressBC5(mips[0], (int)setting.TexWidth, (int)setting.TexHeight, true); } else { bitmap = STGenericTexture.DecodeBlockGetBitmap(mips[0], setting.TexWidth, setting.TexHeight, TextureData.ConvertFormat(setting.Format), new byte[0]); } } if (pictureBox1.InvokeRequired) { pictureBox1.Invoke((MethodInvoker) delegate { pictureBox1.Image = bitmap; pictureBox1.Refresh(); int size = Utils.GetSizeInBytes(mips); dataSizeLbl.Text = $"Data Size: {STMath.GetFileSize(size, 5)}"; }); } mips.Clear(); })); Thread.Start(); }
public static List <byte[]> SwizzleSurfaceMipMaps(Texture tex, byte[] data, uint MipCount) { var TexFormat = TextureData.ConvertFormat(tex.Format); int blockHeightShift = 0; int target = 1; uint Pitch = 0; uint SurfaceSize = 0; uint blockHeight = 0; uint blkWidth = STGenericTexture.GetBlockWidth(TexFormat); uint blkHeight = STGenericTexture.GetBlockHeight(TexFormat); uint blkDepth = STGenericTexture.GetBlockDepth(TexFormat); uint bpp = STGenericTexture.GetBytesPerPixel(TexFormat); uint linesPerBlockHeight = 0; if (tex.TileMode == TileMode.LinearAligned) { blockHeight = 1; tex.BlockHeightLog2 = 0; tex.Alignment = 1; linesPerBlockHeight = 1; tex.ReadTextureLayout = 0; } else { blockHeight = TegraX1Swizzle.GetBlockHeight(DIV_ROUND_UP(tex.Height, blkHeight)); tex.BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; tex.Alignment = 512; tex.ReadTextureLayout = 1; linesPerBlockHeight = blockHeight * 8; } List <byte[]> mipmaps = new List <byte[]>(); for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) { var result = TextureHelper.GetCurrentMipSize(tex.Width, tex.Height, blkWidth, blkHeight, bpp, mipLevel); uint offset = result.Item1; uint size = result.Item2; byte[] data_ = Utils.SubArray(data, offset, size); uint width_ = Math.Max(1, tex.Width >> mipLevel); uint height_ = Math.Max(1, tex.Height >> mipLevel); uint depth_ = Math.Max(1, tex.Depth >> mipLevel); uint width__ = DIV_ROUND_UP(width_, blkWidth); uint height__ = DIV_ROUND_UP(height_, blkHeight); uint depth__ = DIV_ROUND_UP(depth_, blkDepth); byte[] AlignedData = new byte[(TegraX1Swizzle.round_up(SurfaceSize, (uint)tex.Alignment) - SurfaceSize)]; SurfaceSize += (uint)AlignedData.Length; // Console.WriteLine("SurfaceSize Aligned " + AlignedData); Console.WriteLine("MipOffsets " + SurfaceSize); Console.WriteLine("size " + size); tex.MipOffsets[mipLevel] = SurfaceSize; if (tex.TileMode == TileMode.LinearAligned) { Pitch = width__ * bpp; if (target == 1) { Pitch = TegraX1Swizzle.round_up(width__ * bpp, 32); } SurfaceSize += Pitch * height__; } else { if (TegraX1Swizzle.pow2_round_up(height__) < linesPerBlockHeight) { blockHeightShift += 1; } Pitch = TegraX1Swizzle.round_up(width__ * bpp, 64); SurfaceSize += Pitch * TegraX1Swizzle.round_up(height__, Math.Max(1, blockHeight >> blockHeightShift) * 8); } byte[] SwizzledData = TegraX1Swizzle.swizzle(width_, height_, depth_, blkWidth, blkHeight, blkDepth, target, bpp, (uint)tex.TileMode, (int)Math.Max(0, tex.BlockHeightLog2 - blockHeightShift), data_); mipmaps.Add(AlignedData.Concat(SwizzledData).ToArray()); } tex.ImageSize = SurfaceSize; return(mipmaps); }
public void Compress(STCompressionMode CompressionMode) { DataBlockOutput.Clear(); foreach (var surface in DecompressedData) { DataBlockOutput.Add(STGenericTexture.CompressBlock(surface, (int)TexWidth, (int)TexHeight, TextureData.ConvertFormat(Format), alphaRef, CompressionMode)); } }
public byte[] GenerateMips(STCompressionMode CompressionMode, int SurfaceLevel = 0) { Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight); if (GammaFix) { Image = BitmapExtension.AdjustGamma(Image, 2.2f); } List <byte[]> mipmaps = new List <byte[]>(); for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) { int MipWidth = Math.Max(1, (int)TexWidth >> mipLevel); int MipHeight = Math.Max(1, (int)TexHeight >> mipLevel); if (mipLevel != 0) { Image = BitmapExtension.Resize(Image, MipWidth, MipHeight); } mipmaps.Add(STGenericTexture.CompressBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, TextureData.ConvertFormat(Format), alphaRef, CompressionMode)); } Image.Dispose(); return(Utils.CombineByteArray(mipmaps.ToArray())); }
public List <byte[]> GenerateMipList(STCompressionMode CompressionMode, bool multiThread, bool bc4Alpha, int SurfaceLevel = 0) { Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight); if (GammaFix) { Image = BitmapExtension.AdjustGamma(Image, 2.2f); } if (bc4Alpha) { Image = BitmapExtension.SetChannel(Image, STChannelType.Alpha, STChannelType.Alpha, STChannelType.Alpha, STChannelType.Alpha); } List <byte[]> mipmaps = new List <byte[]>(); for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) { int MipWidth = Math.Max(1, (int)TexWidth >> mipLevel); int MipHeight = Math.Max(1, (int)TexHeight >> mipLevel); if (mipLevel != 0) { Image = BitmapExtension.Resize(Image, MipWidth, MipHeight); } mipmaps.Add(STGenericTexture.CompressBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, TextureData.ConvertFormat(Format), alphaRef, multiThread, CompressionMode)); } Image.Dispose(); return(mipmaps); }
public void SetupSettings() { if (SelectedTexSettings.Format == SurfaceFormat.Invalid || SelectedIndex == -1) { return; } WidthLabel.Text = $"Width {SelectedTexSettings.TexWidth}"; HeightLabel.Text = $"Height {SelectedTexSettings.TexHeight}"; if (Thread != null && Thread.IsAlive) { Thread.Abort(); } if (formatComboBox.SelectedItem is SurfaceFormat) { SelectedTexSettings.Format = (SurfaceFormat)formatComboBox.SelectedItem; listViewCustom1.Items[SelectedIndex].SubItems[1].Text = SelectedTexSettings.Format.ToString(); } if (SelectedTexSettings.Format == SurfaceFormat.BC7_UNORM || SelectedTexSettings.Format == SurfaceFormat.BC7_SRGB) { compressionModeCB.Visible = true; } else { compressionModeCB.Visible = false; } Bitmap bitmap = Switch_Toolbox.Library.Imaging.GetLoadingImage(); if (compressionModeCB.SelectedIndex == 0) { CompressionMode = STCompressionMode.Fast; } else { CompressionMode = STCompressionMode.Normal; } Thread = new Thread((ThreadStart)(() => { SelectedTexSettings.IsFinishedCompressing = false; ToggleOkButton(false); pictureBox1.Image = bitmap; var mips = SelectedTexSettings.GenerateMipList(CompressionMode); SelectedTexSettings.DataBlockOutput.Clear(); SelectedTexSettings.DataBlockOutput.Add(Utils.CombineByteArray(mips.ToArray())); ToggleOkButton(true); SelectedTexSettings.IsFinishedCompressing = true; if (SelectedTexSettings.DataBlockOutput.Count > 0) { if (SelectedTexSettings.Format == SurfaceFormat.BC5_SNORM) { bitmap = DDSCompressor.DecompressBC5(mips[0], (int)SelectedTexSettings.TexWidth, (int)SelectedTexSettings.TexHeight, true); } else { bitmap = STGenericTexture.DecodeBlockGetBitmap(mips[0], SelectedTexSettings.TexWidth, SelectedTexSettings.TexHeight, TextureData.ConvertFormat(SelectedTexSettings.Format)); } } mips.Clear(); if (pictureBox1.InvokeRequired) { pictureBox1.Invoke((MethodInvoker) delegate { pictureBox1.Image = bitmap; pictureBox1.Refresh(); }); } })); Thread.Start(); }
public byte[] GenerateMips(int SurfaceLevel = 0) { Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight); List <byte[]> mipmaps = new List <byte[]>(); mipmaps.Add(STGenericTexture.CompressBlock(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight, TextureData.ConvertFormat(Format), alphaRef)); //while (Image.Width / 2 > 0 && Image.Height / 2 > 0) // for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) { int width = Image.Width / 2; int height = Image.Height / 2; if (width <= 0) { width = 1; } if (height <= 0) { height = 1; } Image = BitmapExtension.Resize(Image, width, height); mipmaps.Add(STGenericTexture.CompressBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, TextureData.ConvertFormat(Format), alphaRef)); } Image.Dispose(); return(Utils.CombineByteArray(mipmaps.ToArray())); }
public void SetupSettings() { if (SelectedTexSettings.Format == SurfaceFormat.Invalid) { return; } WidthLabel.Text = $"Width {SelectedTexSettings.TexWidth}"; HeightLabel.Text = $"Height {SelectedTexSettings.TexHeight}"; if (formatComboBox.SelectedItem is SurfaceFormat) { SelectedTexSettings.Format = (SurfaceFormat)formatComboBox.SelectedItem; listViewCustom1.SelectedItems[0].SubItems[1].Text = SelectedTexSettings.Format.ToString(); } Bitmap bitmap = Switch_Toolbox.Library.Imaging.GetLoadingImage(); Thread = new Thread((ThreadStart)(() => { ToggleOkButton(false); pictureBox1.Image = bitmap; SelectedTexSettings.Compress(); ToggleOkButton(true); if (SelectedTexSettings.Format == SurfaceFormat.BC5_SNORM) { bitmap = DDSCompressor.DecompressBC5(SelectedTexSettings.DataBlockOutput[0], (int)SelectedTexSettings.TexWidth, (int)SelectedTexSettings.TexHeight, true); } else { bitmap = TextureData.DecodeBlockGetBitmap(SelectedTexSettings.DataBlockOutput[0], SelectedTexSettings.TexWidth, SelectedTexSettings.TexHeight, TextureData.ConvertFormat(SelectedTexSettings.Format)); } if (pictureBox1.InvokeRequired) { pictureBox1.Invoke((MethodInvoker) delegate { pictureBox1.Image = bitmap; pictureBox1.Refresh(); }); } })); Thread.Start(); }