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();
        }
Пример #2
0
        public Texture FromBitMap(byte[] data, TextureImporterSettings settings)
        {
            Texture tex = new Texture();

            tex.Height = (uint)settings.TexHeight;
            tex.Width  = (uint)settings.TexWidth;
            var formats = TextureData.GetSurfaceFormat(settings.Format, settings.FormatType);

            tex.Format     = formats.Item1;
            tex.FormatType = formats.Item2;

            tex.Name        = settings.TexName;
            tex.Path        = "";
            tex.TextureData = new List <List <byte[]> >();

            if (settings.MipCount == 0)
            {
                settings.MipCount = 1;
            }

            STChannelType[] channels = STGenericTexture.SetChannelsByFormat(settings.Format);
            tex.ChannelRed      = (ChannelType)channels[0];
            tex.ChannelGreen    = (ChannelType)channels[1];
            tex.ChannelBlue     = (ChannelType)channels[2];
            tex.ChannelAlpha    = (ChannelType)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];

            List <byte[]> arrayFaces = new List <byte[]>();

            if (tex.ArrayLength > 1)
            {
                arrayFaces = DDS.GetArrayFaces(data, tex.ArrayLength);
            }
            else
            {
                arrayFaces.Add(data);
            }

            for (int i = 0; i < tex.ArrayLength; i++)
            {
                List <byte[]> mipmaps = SwizzleSurfaceMipMaps(tex, arrayFaces[i], tex.TileMode);
                tex.TextureData.Add(mipmaps);
                byte[] test = Combine(mipmaps);
                tex.TextureData[i][0] = test;
            }
            return(tex);
        }
Пример #3
0
        public void LoadDDS(string FileName, BntxFile bntxFile, byte[] FileData = null, TextureData tree = null)
        {
            TexName = Path.GetFileNameWithoutExtension(FileName);

            DDS dds = new DDS();

            if (FileData != null)
            {
                dds.Load(new FileReader(new MemoryStream(FileData)));
            }
            else
            {
                dds.Load(new FileReader(FileName));
            }
            MipCount    = dds.header.mipmapCount;
            TexWidth    = dds.header.width;
            TexHeight   = dds.header.height;
            arrayLength = 1;
            if (dds.header.caps2 == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES)
            {
                arrayLength = 6;
            }

            DataBlockOutput.Add(dds.bdata);

            var formats = dds.GetFormat();

            Format     = formats.Item1;
            FormatType = formats.Item2;

            Texture tex = FromBitMap(DataBlockOutput[0], this);

            if (tree != null)
            {
                tree.LoadTexture(tex, 1);
            }
            else
            {
                textureData = new TextureData(tex, bntxFile);
            }
        }
Пример #4
0
        private void ReadGx2(FileReader reader)
        {
            reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;

            header = new GTXHeader();
            header.Read(reader);

            Console.WriteLine("header size " + header.HeaderSize);

            uint surfBlockType;
            uint dataBlockType;
            uint mipBlockType;

            if (header.MajorVersion == 6)
            {
                surfBlockType = 0x0A;
                dataBlockType = 0x0B;
                mipBlockType  = 0x0C;
            }
            else if (header.MajorVersion == 7)
            {
                surfBlockType = 0x0B;
                dataBlockType = 0x0C;
                mipBlockType  = 0x0D;
            }
            else
            {
                throw new Exception($"Unsupported GTX version {header.MajorVersion}");
            }

            if (header.GpuVersion != 2)
            {
                throw new Exception($"Unsupported GPU version {header.GpuVersion}");
            }

            reader.Position = header.HeaderSize;

            bool blockB = false;
            bool blockC = false;

            uint ImageInfo = 0;
            uint images    = 0;

            while (reader.Position < reader.BaseStream.Length)
            {
                GTXDataBlock block = new GTXDataBlock();
                block.Read(reader);
                blocks.Add(block);

                //Here we use "if" instead of "case" statements as types vary between versions
                if ((uint)block.BlockType == surfBlockType)
                {
                    ImageInfo += 1;
                    blockB     = true;

                    var surface = new SurfaceInfoParse();
                    surface.Read(new FileReader(block.data));

                    if (surface.numMips > 14)
                    {
                        throw new Exception($"Invalid number of mip maps {surface.numMips}!");
                    }

                    TextureData textureData = new TextureData();
                    textureData.surface = surface;
                    textureData.Text    = "Texture" + ImageInfo;
                    Nodes.Add(textureData);
                    textures.Add(textureData);
                }
                else if ((uint)block.BlockType == dataBlockType)
                {
                    images += 1;
                    blockC  = true;

                    data.Add(block.data);
                }
                else if ((uint)block.BlockType == mipBlockType)
                {
                    mipMaps.Add(block.data);
                }
            }
            if (textures.Count != data.Count)
            {
                throw new Exception($"Bad size! {textures.Count} {data.Count}");
            }

            int curTex = 0;
            int curMip = 0;

            foreach (var node in Nodes)
            {
                TextureData tex = (TextureData)node;
                tex.surface.data = data[curTex];
                tex.surface.bpp  = GTX.surfaceGetBitsPerPixel(tex.surface.format) >> 3;

                Console.WriteLine();

                if (tex.surface.numMips > 1)
                {
                    tex.surface.mipData = mipMaps[curMip++];
                }
                else
                {
                    tex.surface.mipData = new byte[0];
                }

                Console.WriteLine("");
                Console.WriteLine("// ----- GX2Surface Info ----- ");
                Console.WriteLine("  dim             = " + tex.surface.dim);
                Console.WriteLine("  width           = " + tex.surface.width);
                Console.WriteLine("  height          = " + tex.surface.height);
                Console.WriteLine("  depth           = " + tex.surface.depth);
                Console.WriteLine("  numMips         = " + tex.surface.numMips);
                Console.WriteLine("  format          = " + tex.surface.format);
                Console.WriteLine("  aa              = " + tex.surface.aa);
                Console.WriteLine("  use             = " + tex.surface.use);
                Console.WriteLine("  imageSize       = " + tex.surface.imageSize);
                Console.WriteLine("  mipSize         = " + tex.surface.mipSize);
                Console.WriteLine("  tileMode        = " + tex.surface.tileMode);
                Console.WriteLine("  swizzle         = " + tex.surface.swizzle);
                Console.WriteLine("  alignment       = " + tex.surface.alignment);
                Console.WriteLine("  pitch           = " + tex.surface.pitch);
                Console.WriteLine("  bits per pixel  = " + (tex.surface.bpp << 3));
                Console.WriteLine("  bytes per pixel = " + tex.surface.bpp);
                Console.WriteLine("  data size       = " + tex.surface.data.Length);
                Console.WriteLine("  mip size        = " + tex.surface.mipData.Length);
                Console.WriteLine("  realSize        = " + tex.surface.imageSize);

                List <byte[]> mips = GTX.Decode(tex.surface);
                tex.Surfaces.Add(new STGenericTexture.Surface()
                {
                    mipmaps = mips
                });
                tex.RenderableTex.LoadOpenGLTexture(tex);
                curTex++;
            }
        }
        public List <byte[]> GenerateMipList(STCompressionMode CompressionMode, int SurfaceLevel = 0)
        {
            Bitmap Image = BitmapExtension.GetBitmap(DecompressedData[SurfaceLevel], (int)TexWidth, (int)TexHeight);

            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(mipmaps);
        }
        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);
        }
Пример #7
0
        private void ReadGx2(FileReader reader)
        {
            reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;

            header = new GTXHeader();
            header.Read(reader);

            Console.WriteLine("header size " + header.HeaderSize);

            uint surfBlockType;
            uint dataBlockType;
            uint mipBlockType;
            uint vertexShaderHeader    = 0x03;
            uint vertexShaderProgram   = 0x05;
            uint pixelShaderHeader     = 0x06;
            uint pixelShaderProgram    = 0x07;
            uint geometryShaderHeader  = 0x08;
            uint geometryShaderProgram = 0x09;
            uint userDataBlock         = 0x10;

            if (header.MajorVersion == 6 && header.MinorVersion == 0)
            {
                surfBlockType = 0x0A;
                dataBlockType = 0x0B;
                mipBlockType  = 0x0C;
            }
            else if (header.MajorVersion == 6 || header.MajorVersion == 7)
            {
                surfBlockType = 0x0B;
                dataBlockType = 0x0C;
                mipBlockType  = 0x0D;
            }
            else
            {
                throw new Exception($"Unsupported GTX version {header.MajorVersion}");
            }

            if (header.GpuVersion != 2)
            {
                throw new Exception($"Unsupported GPU version {header.GpuVersion}");
            }

            reader.Position = header.HeaderSize;

            bool blockB = false;
            bool blockC = false;

            uint ImageInfo = 0;
            uint images    = 0;

            while (reader.Position < reader.BaseStream.Length)
            {
                Console.WriteLine("BLOCK POS " + reader.Position + " " + reader.BaseStream.Length);
                GTXDataBlock block = new GTXDataBlock();
                block.Read(reader);
                blocks.Add(block);

                bool BlockIsEmpty = block.BlockType == BlockType.AlignData ||
                                    block.BlockType == BlockType.EndOfFile;

                //Here we use "if" instead of "case" statements as types vary between versions
                if ((uint)block.BlockType == surfBlockType)
                {
                    ImageInfo += 1;
                    blockB     = true;

                    var surface = new SurfaceInfoParse();
                    surface.Read(new FileReader(block.data));

                    if (surface.tileMode == 0 || surface.tileMode > 16)
                    {
                        throw new Exception($"Invalid tileMode {surface.tileMode}!");
                    }

                    if (surface.numMips > 14)
                    {
                        throw new Exception($"Invalid number of mip maps {surface.numMips}!");
                    }

                    TextureData textureData = new TextureData();
                    textureData.surface    = surface;
                    textureData.MipCount   = surface.numMips;
                    textureData.ArrayCount = surface.depth;
                    textureData.Text       = "Texture" + ImageInfo;
                    Nodes.Add(textureData);
                    textures.Add(textureData);
                }
                else if ((uint)block.BlockType == dataBlockType)
                {
                    images += 1;
                    blockC  = true;

                    data.Add(block.data);
                }
                else if ((uint)block.BlockType == mipBlockType)
                {
                    mipMaps.Add(block.data);
                }
                else if ((uint)block.BlockType == vertexShaderHeader)
                {
                    Nodes.Add(new BlockDisplay(block.data)
                    {
                        Text = "Vertex Shader Header"
                    });
                }
                else if ((uint)block.BlockType == vertexShaderProgram)
                {
                    Nodes.Add(new BlockDisplay(block.data)
                    {
                        Text = "Vertex Shader Program"
                    });
                }
                else if ((uint)block.BlockType == pixelShaderHeader)
                {
                    Nodes.Add(new BlockDisplay(block.data)
                    {
                        Text = "Pixel Shader Header"
                    });
                }
                else if ((uint)block.BlockType == pixelShaderProgram)
                {
                    Nodes.Add(new BlockDisplay(block.data)
                    {
                        Text = "Pixel Shader Program"
                    });
                }
                else if ((uint)block.BlockType == geometryShaderHeader)
                {
                    Nodes.Add(new BlockDisplay(block.data)
                    {
                        Text = "Geometry Shader Header"
                    });
                }
                else if ((uint)block.BlockType == geometryShaderProgram)
                {
                    Nodes.Add(new BlockDisplay(block.data)
                    {
                        Text = "Geometry Shader Program"
                    });
                }
                else if (!BlockIsEmpty)
                {
                    Nodes.Add(new BlockDisplay(block.data)
                    {
                        Text = $"Block Type {block.BlockType.ToString("X")}"
                    });
                }
            }
            if (textures.Count != data.Count)
            {
                throw new Exception($"Bad size! {textures.Count} {data.Count}");
            }

            int curTex = 0;
            int curMip = 0;

            foreach (var node in Nodes)
            {
                if (node is TextureData)
                {
                    TextureData tex = (TextureData)node;

                    tex.surface.data = data[curTex];
                    tex.surface.bpp  = GX2.surfaceGetBitsPerPixel(tex.surface.format) >> 3;
                    tex.Format       = FTEX.ConvertFromGx2Format((Syroot.NintenTools.Bfres.GX2.GX2SurfaceFormat)tex.surface.format);
                    tex.Width        = tex.surface.width;
                    tex.Height       = tex.surface.height;

                    if (tex.surface.numMips > 1)
                    {
                        tex.surface.mipData = mipMaps[curMip++];
                    }
                    else
                    {
                        tex.surface.mipData = new byte[0];
                    }

                    if (tex.surface.mipData == null)
                    {
                        tex.surface.numMips = 1;
                    }

                    curTex++;
                }
            }
        }
 public void LoadTexture(TextureData tex)
 {
     TextureData.BRTI_Texture renderedTex = tex.renderedGLTex;
     bntxEditor1.LoadProperty(tex);
 }
Пример #9
0
 public void RemoveTexture(TextureData textureData)
 {
     Nodes.Remove(textureData);
     Textures.Remove(textureData.Text);
     Viewport.Instance.UpdateViewport();
 }
Пример #10
0
 public void Compress()
 {
     DataBlockOutput.Clear();
     foreach (var surface in DecompressedData)
     {
         DataBlockOutput.Add(STGenericTexture.CompressBlock(surface,
                                                            (int)TexWidth, (int)TexHeight, TextureData.ConvertFormat(Format), alphaRef));
     }
 }
        public void InitializeTextureListView(FMAT material)
        {
            textureRefListView.Items.Clear();
            textureRefListView.SmallImageList = textureImageList;
            textureRefListView.FullRowSelect  = true;

            foreach (MatTexture tex in material.textures)
            {
                ListViewItem item = new ListViewItem();
                item.Text = tex.Name;
                item.SubItems.Add(tex.SamplerName);

                if (material.shaderassign.samplers.ContainsValue(tex.SamplerName))
                {
                    var FragSampler = material.shaderassign.samplers.FirstOrDefault(x => x.Value == tex.SamplerName).Key;
                    item.SubItems.Add(FragSampler.ToString());
                }

                textureRefListView.Items.Add(item);
            }

            textureImageList.Images.Clear();

            int CurTex = 0;

            if (PluginRuntime.bntxContainers.Count == 0 &&
                PluginRuntime.ftexContainers.Count == 0)
            {
                foreach (ListViewItem item in textureRefListView.Items)
                {
                    AddBlankTexture(item, item.Text, CurTex++);
                }
            }
            bool FoundTexture = false;

            foreach (ListViewItem item in textureRefListView.Items)
            {
                foreach (BinaryTextureContainer bntx in PluginRuntime.bntxContainers)
                {
                    if (bntx.Textures.ContainsKey(item.Text))
                    {
                        FoundTexture = true;

                        TextureData tex = bntx.Textures[item.Text];
                        TextureData.BRTI_Texture renderedTex = tex.renderedGLTex;
                        Bitmap temp = tex.GLTextureToBitmap(renderedTex, renderedTex.display);

                        textureImageList.Images.Add(tex.Text, temp);

                        item.ImageIndex = CurTex++;

                        var dummy = textureImageList.Handle;
                        temp.Dispose();
                    }
                }
                foreach (FTEXContainer ftexCont in PluginRuntime.ftexContainers)
                {
                    if (ftexCont.Textures.ContainsKey(item.Text))
                    {
                        FoundTexture = true;

                        FTEX tex = ftexCont.Textures[item.Text];
                        FTEX.RenderableTex renderedTex = tex.renderedTex;
                        Bitmap             temp        = tex.GLTextureToBitmap(renderedTex, renderedTex.display);

                        textureImageList.Images.Add(tex.Text, temp);

                        item.ImageIndex = CurTex++;

                        var dummy = textureImageList.Handle;
                        temp.Dispose();
                    }
                }
                if (FoundTexture == false)
                {
                    AddBlankTexture(item, item.Text, CurTex++);
                }
            }
        }
Пример #12
0
        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();
        }
Пример #14
0
        public override void Replace(string FileName)
        {
            var bntxFile = new BNTX();
            var tex      = new TextureData();

            tex.Replace(FileName, MipCount, 0, Format);

            //If it's null, the operation is cancelled
            if (tex.Texture == null)
            {
                return;
            }

            var surfacesNew = tex.GetSurfaces();
            var surfaces    = GetSurfaces();

            if (LimitFileSize)
            {
                if (surfaces[0].mipmaps[0].Length < surfacesNew[0].mipmaps[0].Length)
                {
                    if (surfaces[0].mipmaps[0].Length != surfacesNew[0].mipmaps[0].Length)
                    {
                        throw new Exception($"Image must be the same size! {surfaces[0].mipmaps[0].Length}");
                    }

                    if (mipSizes[0].Length != surfacesNew[0].mipmaps.Count)
                    {
                        throw new Exception($"Mip map count must be the same! {mipSizes[0].Length}");
                    }

                    if (Width != tex.Texture.Width || Height != tex.Texture.Height)
                    {
                        throw new Exception("Image size must be the same!");
                    }
                }

                Width    = tex.Texture.Width;
                Height   = tex.Texture.Height;
                MipCount = tex.Texture.MipCount;
            }
            else
            {
                Width      = tex.Texture.Width;
                Height     = tex.Texture.Height;
                MipCount   = tex.Texture.MipCount;
                ArrayCount = tex.Texture.ArrayLength;
                Depth      = tex.Texture.Depth;

                Format    = tex.Format;
                NutFormat = ConvertGenericToNutFormat(tex.Format);

                mipSizes = TegraX1Swizzle.GenerateMipSizes(tex.Format, tex.Width, tex.Height, tex.Depth, tex.ArrayCount, tex.MipCount, (uint)ImageData.Length);
            }

            List <byte[]> data = new List <byte[]>();

            foreach (var array in tex.Texture.TextureData)
            {
                data.Add(Utils.CombineByteArray(array.ToArray()));
            }

            var output = Utils.CombineByteArray(data.ToArray());

            ImageData = SetImageData(output);

            data.Clear();
            surfacesNew.Clear();
            surfaces.Clear();

            UpdateEditor();
        }
        public byte[] GenerateMips(STCompressionMode CompressionMode, bool multiThread, 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, multiThread, CompressionMode));
            }
            Image.Dispose();

            return(Utils.CombineByteArray(mipmaps.ToArray()));
        }
        public void SetupSettings(TextureImporterSettings setting, bool setFormat = true)
        {
            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 && setFormat)
            {
                setting.SurfaceDim = (SurfaceDim)formatComboBox.SelectedItem;
            }


            if (formatComboBox.SelectedItem is SurfaceFormat && setFormat)
            {
                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;
            }

            if (setting.Format == SurfaceFormat.BC4_UNORM || setting.Format == SurfaceFormat.BC4_SNORM)
            {
                chkBC4Alpha.Enabled = true;
            }
            else
            {
                chkBC4Alpha.Enabled = 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, MultiThreading, chkBC4Alpha.Checked);

                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 (chkBC4Alpha.Checked)
                    {
                        bitmap = BitmapExtension.SetChannel(bitmap, STChannelType.Red,
                                                            STChannelType.Red, STChannelType.Red, STChannelType.Red);
                    }
                }

                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 void Compress(STCompressionMode CompressionMode, bool multiThread)
 {
     DataBlockOutput.Clear();
     foreach (var surface in DecompressedData)
     {
         DataBlockOutput.Add(STGenericTexture.CompressBlock(surface,
                                                            (int)TexWidth, (int)TexHeight, TextureData.ConvertFormat(Format), alphaRef, multiThread, CompressionMode));
     }
 }
Пример #18
0
 public void LoadTexture(TextureData tex)
 {
     TextureData.BRTI_Texture renderedTex = tex.renderedGLTex;
     bntxEditor1.LoadPicture(tex.GLTextureToBitmap(renderedTex, renderedTex.display));
     bntxEditor1.LoadProperty(tex);
 }
Пример #19
0
        public override void Replace(string FileName)
        {
            if (IsSwizzled)
            {
                var tex = new TextureData();
                tex.Replace(FileName, MipCount, 0, Format);

                //If it's null, the operation is cancelled
                if (tex.Texture == null)
                {
                    return;
                }

                List <byte[]> data = new List <byte[]>();
                foreach (var array in tex.Texture.TextureData)
                {
                    data.Add(array[0]);
                }

                var output = CreateBuffer(data);

                Width    = tex.Texture.Width;
                Height   = tex.Texture.Height;
                MipCount = tex.Texture.MipCount;
                // ArrayCount = tex.Texture.ArrayLength;
                // Depth = tex.Texture.Depth;

                Format    = tex.Format;
                NutFormat = ConvertGenericToNutFormat(tex.Format);

                mipSizes = TegraX1Swizzle.GenerateMipSizes(tex.Format, tex.Width, tex.Height, tex.Depth, tex.ArrayCount, tex.MipCount, (uint)ImageData.Length);

                ImageData = SetImageData(output);

                data.Clear();
            }
            else
            {
                GenericTextureImporterList     importer = new GenericTextureImporterList(SupportedFormats);
                GenericTextureImporterSettings settings = new GenericTextureImporterSettings();

                if (Utils.GetExtension(FileName) == ".dds" ||
                    Utils.GetExtension(FileName) == ".dds2")
                {
                    settings.LoadDDS(FileName);
                    importer.LoadSettings(new List <GenericTextureImporterSettings>()
                    {
                        settings,
                    });
                    ApplySettings(settings);
                    UpdateEditor();
                }
                else
                {
                    settings.LoadBitMap(FileName);
                    importer.LoadSettings(new List <GenericTextureImporterSettings>()
                    {
                        settings,
                    });

                    if (importer.ShowDialog() == DialogResult.OK)
                    {
                        if (settings.GenerateMipmaps && !settings.IsFinishedCompressing)
                        {
                            settings.DataBlockOutput.Clear();
                            settings.DataBlockOutput.Add(settings.GenerateMips(importer.CompressionMode, importer.MultiThreading));
                        }

                        ApplySettings(settings);
                        UpdateEditor();
                    }
                }
            }

            UpdateEditor();
        }
Пример #20
0
        private void ReadGx2(FileReader reader)
        {
            reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;

            header = new GTXHeader();
            header.Read(reader);

            Console.WriteLine("header size " + header.HeaderSize);

            uint surfBlockType;
            uint dataBlockType;
            uint mipBlockType;

            if (header.MajorVersion == 6)
            {
                surfBlockType = 0x0A;
                dataBlockType = 0x0B;
                mipBlockType  = 0x0C;
            }
            else if (header.MajorVersion == 7)
            {
                surfBlockType = 0x0B;
                dataBlockType = 0x0C;
                mipBlockType  = 0x0D;
            }
            else
            {
                throw new Exception($"Unsupported GTX version {header.MajorVersion}");
            }

            if (header.GpuVersion != 2)
            {
                throw new Exception($"Unsupported GPU version {header.GpuVersion}");
            }

            reader.Position = header.HeaderSize;

            bool blockB = false;
            bool blockC = false;

            uint ImageInfo = 0;
            uint images    = 0;

            while (reader.Position < reader.BaseStream.Length)
            {
                GTXDataBlock block = new GTXDataBlock();
                block.Read(reader);
                blocks.Add(block);

                //Here we use "if" instead of "case" statements as types vary between versions
                if ((uint)block.BlockType == surfBlockType)
                {
                    ImageInfo += 1;
                    blockB     = true;

                    var surface = new SurfaceInfoParse();
                    surface.Read(new FileReader(block.data));

                    if (surface.numMips > 14)
                    {
                        throw new Exception($"Invalid number of mip maps {surface.numMips}!");
                    }

                    TextureData textureData = new TextureData();
                    textureData.surface    = surface;
                    textureData.MipCount   = surface.numMips;
                    textureData.ArrayCount = surface.numArray;
                    textureData.Text       = "Texture" + ImageInfo;
                    Nodes.Add(textureData);
                    textures.Add(textureData);
                }
                else if ((uint)block.BlockType == dataBlockType)
                {
                    images += 1;
                    blockC  = true;

                    data.Add(block.data);
                }
                else if ((uint)block.BlockType == mipBlockType)
                {
                    mipMaps.Add(block.data);
                }
            }
            if (textures.Count != data.Count)
            {
                throw new Exception($"Bad size! {textures.Count} {data.Count}");
            }

            int curTex = 0;
            int curMip = 0;

            foreach (var node in Nodes)
            {
                TextureData tex = (TextureData)node;

                tex.surface.data = data[curTex];
                tex.surface.bpp  = GTX.surfaceGetBitsPerPixel(tex.surface.format) >> 3;
                tex.Format       = FTEX.ConvertFromGx2Format((Syroot.NintenTools.Bfres.GX2.GX2SurfaceFormat)tex.surface.format);
                tex.Width        = tex.surface.width;
                tex.Height       = tex.surface.height;

                if (tex.surface.numMips > 1)
                {
                    tex.surface.mipData = mipMaps[curMip++];
                }
                else
                {
                    tex.surface.mipData = new byte[0];
                }

                if (tex.surface.mipData == null)
                {
                    tex.surface.numMips = 1;
                }

                curTex++;
            }
            reader.Close();
            reader.Dispose();
        }