예제 #1
0
        public static SBSurface Open(string FilePath)
        {
            using (BinaryReader reader = new BinaryReader(new FileStream(FilePath, FileMode.Open)))
            {
                // TODO: Why are there empty streams?
                if (reader.BaseStream.Length == 0)
                {
                    return(null);
                }

                SBSurface surface = new SBSurface();

                reader.BaseStream.Position = reader.BaseStream.Length - 0xB0;

                int[] mipmapSizes = new int[16];
                for (int i = 0; i < mipmapSizes.Length; i++)
                {
                    mipmapSizes[i] = reader.ReadInt32();
                }

                reader.ReadChars(4); // TNX magic

                string texName = ReadTexName(reader);
                surface.Name = texName;

                surface.Width  = reader.ReadInt32();
                surface.Height = reader.ReadInt32();
                surface.Depth  = reader.ReadInt32();

                var Format = (NUTEX_FORMAT)reader.ReadByte();

                reader.ReadByte();

                ushort Padding = reader.ReadUInt16();
                reader.ReadUInt32();

                int MipCount  = reader.ReadInt32();
                int Alignment = reader.ReadInt32();
                surface.ArrayCount = reader.ReadInt32();
                int    ImageSize    = reader.ReadInt32();
                char[] Magic        = reader.ReadChars(4);
                int    MajorVersion = reader.ReadInt16();
                int    MinorVersion = reader.ReadInt16();

                if (pixelFormatByNuTexFormat.ContainsKey(Format))
                {
                    surface.PixelFormat = pixelFormatByNuTexFormat[Format];
                }

                if (internalFormatByNuTexFormat.ContainsKey(Format))
                {
                    surface.InternalFormat = internalFormatByNuTexFormat[Format];
                }

                surface.PixelType = GetPixelType(Format);

                reader.BaseStream.Position = 0;
                byte[] ImageData = reader.ReadBytes(ImageSize);

                for (int array = 0; array < surface.ArrayCount; array++)
                {
                    MipArray arr = new MipArray();
                    for (int i = 0; i < MipCount; i++)
                    {
                        byte[] deswiz = SwitchSwizzler.GetImageData(surface, ImageData, array, i, MipCount);
                        arr.Mipmaps.Add(deswiz);
                    }
                    surface.Arrays.Add(arr);
                }

                return(surface);
            }
        }
예제 #2
0
        public static SBSurface Import(string FileName)
        {
            SBSurface surface = new SBSurface();

            using (BinaryReaderExt reader = new BinaryReaderExt(new FileStream(FileName, FileMode.Open)))
            {
                DDS_Header header = new DDS_Header();
                header.Read(reader);

                surface.Name   = Path.GetFileNameWithoutExtension(FileName);
                surface.Width  = header.dwWidth;
                surface.Height = header.dwHeight;
                if (header.dwFlags.HasFlag(DDSD.DEPTH))
                {
                    surface.Depth = header.dwDepth;
                }
                else
                {
                    surface.Depth = 1;
                }

                if (header.ddspf.dwFourCC == 0x31545844)
                {
                    surface.InternalFormat = InternalFormat.CompressedRgbaS3tcDxt1Ext;
                }
                else
                if (header.ddspf.dwFourCC == 0x30315844)
                {
                    surface.InternalFormat = DXGItoInternal(header.DXT10Header.dxgiFormat);
                    if (surface.InternalFormat == 0)
                    {
                        System.Windows.Forms.MessageBox.Show("DDS format not supported " + header.DXT10Header.dxgiFormat);

                        return(null);
                    }
                }
                else
                {
                    if (((FourCC_DXGI)header.ddspf.dwFourCC) == FourCC_DXGI.D3DFMT_A32B32G32R32F)
                    {
                        surface.InternalFormat = InternalFormat.Rgba32f;
                        surface.PixelFormat    = PixelFormat.Rgba;
                        surface.PixelType      = PixelType.Float;
                    }
                    else
                    {
                        System.Windows.Forms.MessageBox.Show("DDS format not supported " + header.ddspf.dwFourCC.ToString("X"));
                        return(null);
                    }
                }


                // TODO: read other mips
                int w = surface.Width;
                int h = surface.Height;
                //SBConsole.WriteLine(header.dwCaps.ToString() + " " + header.dwCaps2.ToString() + " " + header.dwFlags.ToString());
                for (int array = 0; array < (header.dwCaps2.HasFlag(DDSCAPS2.CUBEMAP_ALLFACES) ? 6 : 1); array++)
                {
                    w = surface.Width;
                    h = surface.Height;
                    var mip = new MipArray();

                    for (int i = 0; i < (header.dwFlags.HasFlag(DDSD.MIPMAPCOUNT) ? header.dwMipMapCount : 1); i++)
                    {
                        var mipSize = Math.Max(1, ((w + 3) / 4)) * Math.Max(1, ((h + 3) / 4)) * (int)TextureFormatInfo.GetBPP(surface.InternalFormat);

                        if (mipSize % TextureFormatInfo.GetBPP(surface.InternalFormat) != 0)
                        {
                            mipSize += (int)(TextureFormatInfo.GetBPP(surface.InternalFormat) - (mipSize % TextureFormatInfo.GetBPP(surface.InternalFormat)));
                        }

                        var data = reader.ReadBytes(mipSize);

                        mip.Mipmaps.Add(data);
                        w /= 2;
                        h /= 2;
                    }

                    surface.Arrays.Add(mip);
                }
                if (reader.Position != reader.BaseStream.Length)
                {
                    SBConsole.WriteLine("Warning: error reading dds " + reader.Position.ToString("X"));
                }
            }



            return(surface);
        }