예제 #1
0
        public static byte[] Headerize(TPF.Texture texture)
        {
            if (Encoding.ASCII.GetString(texture.Bytes, 0, 4) == "DDS ")
            {
                return(texture.Bytes);
            }

            DDS         dds   = new DDS();
            PIXELFORMAT ddspf = dds.ddspf;

            byte format = texture.Format;

            if (format != 16 && format != 26)
            {
                DDSD dwFlags = DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PIXELFORMAT | DDSD.MIPMAPCOUNT;
                if (format == 0 || format == 1 || format == 3 || format == 5)
                {
                    dwFlags |= DDSD.LINEARSIZE;
                }
                else if (format == 9 || format == 10)
                {
                    dwFlags |= DDSD.PITCH;
                }
                dds.dwFlags = dwFlags;

                dds.dwHeight = texture.Header.Height;
                dds.dwWidth  = texture.Header.Width;

                if (format == 9 || format == 10)
                {
                    dds.dwPitchOrLinearSize = (texture.Header.Width * 32 + 7) / 8;
                }
                //else if (format == 0 || format == 1)
                //    pitch = Math.Max(1, (texture.Header.Width + 3) / 4) * (8 * 8 * 8);
                //else if (format == 5)
                //    pitch = Math.Max(1, (texture.Header.Width + 3) / 4) * (16 * 16 * 8);

                dds.dwDepth       = 1;
                dds.dwMipMapCount = texture.Mipmaps;

                DDPF ddspfdwFlags = 0;
                if (format == 0 || format == 1 || format == 3 || format == 5)
                {
                    ddspfdwFlags |= DDPF.FOURCC;
                }
                else if (format == 9)
                {
                    ddspfdwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB;
                }
                else if (format == 10)
                {
                    ddspfdwFlags |= DDPF.RGB;
                }
                ddspf.dwFlags = ddspfdwFlags;

                if (format == 0 || format == 1)
                {
                    ddspf.SetFourCCAsString("DXT1");
                }
                else if (format == 3)
                {
                    ddspf.SetFourCCAsString("DXT3");
                }
                else if (format == 5)
                {
                    ddspf.SetFourCCAsString("DXT5");
                }
                else
                {
                    ddspf.dwFourCC = 0;
                }

                if (format == 9 || format == 10)
                {
                    ddspf.dwRGBBitCount = 32;
                }

                if (format == 9)
                {
                    ddspf.dwRBitMask = 0x00FF0000;
                    ddspf.dwGBitMask = 0x0000FF00;
                    ddspf.dwBBitMask = 0x000000FF;
                    ddspf.dwABitMask = 0xFF000000;
                }
                else if (format == 10)
                {
                    ddspf.dwRBitMask = 0x000000FF;
                    ddspf.dwGBitMask = 0x0000FF00;
                    ddspf.dwBBitMask = 0x00FF0000;
                    ddspf.dwABitMask = 0x00000000;
                }

                DDSCAPS dwCaps = DDSCAPS.TEXTURE;
                if (texture.Type == TPF.TexType.Cubemap)
                {
                    dwCaps |= DDSCAPS.COMPLEX;
                }
                if (texture.Mipmaps > 1)
                {
                    dwCaps |= DDSCAPS.COMPLEX | DDSCAPS.MIPMAP;
                }
                dds.dwCaps = dwCaps;

                if (texture.Type == TPF.TexType.Cubemap)
                {
                    dds.dwCaps2 = CUBEMAP_ALLFACES;
                }
                else if (texture.Type == TPF.TexType.Volume)
                {
                    dds.dwCaps2 = DDSCAPS2.VOLUME;
                }
            }
            else
            {
                //int a = 0;
            }

            return(dds.Write(texture.Bytes));
        }
        public static byte[] Headerize(TPF.Texture texture)
        {
            if (SFEncoding.ASCII.GetString(texture.Bytes, 0, 4) == "DDS ")
            {
                return(texture.Bytes);
            }

            var   dds      = new DDS();
            byte  format   = texture.Format;
            short width    = texture.Header.Width;
            short height   = texture.Header.Height;
            int   mipCount = texture.Mipmaps;

            TPF.TexType type = texture.Type;

            dds.dwFlags = DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PIXELFORMAT | DDSD.MIPMAPCOUNT;
            if (CompressedBPB.ContainsKey(format))
            {
                dds.dwFlags |= DDSD.PITCH;
            }
            else if (UncompressedBPP.ContainsKey(format))
            {
                dds.dwFlags |= DDSD.LINEARSIZE;
            }

            dds.dwHeight = height;
            dds.dwWidth  = width;

            if (CompressedBPB.ContainsKey(format))
            {
                dds.dwPitchOrLinearSize = Math.Max(1, (width + 3) / 4) * CompressedBPB[format];
            }
            else if (UncompressedBPP.ContainsKey(format))
            {
                dds.dwPitchOrLinearSize = (width * UncompressedBPP[format] + 7) / 8;
            }

            if (mipCount == 0)
            {
                mipCount = DetermineMipCount(width, height);
            }
            dds.dwMipMapCount = mipCount;

            dds.dwCaps = DDSCAPS.TEXTURE;
            if (type == TPF.TexType.Cubemap)
            {
                dds.dwCaps |= DDSCAPS.COMPLEX;
            }
            if (mipCount > 1)
            {
                dds.dwCaps |= DDSCAPS.COMPLEX | DDSCAPS.MIPMAP;
            }

            if (type == TPF.TexType.Cubemap)
            {
                dds.dwCaps2 = CUBEMAP_ALLFACES;
            }
            else if (type == TPF.TexType.Volume)
            {
                dds.dwCaps2 = DDSCAPS2.VOLUME;
            }

            PIXELFORMAT ddspf = dds.ddspf;

            if (FourCC.ContainsKey(format) || DX10Formats.Contains(format))
            {
                ddspf.dwFlags = DDPF.FOURCC;
            }
            if (format == 6)
            {
                ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB;
            }
            else if (format == 9)
            {
                ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB;
            }
            else if (format == 10)
            {
                ddspf.dwFlags |= DDPF.RGB;
            }
            else if (format == 16)
            {
                ddspf.dwFlags |= DDPF.ALPHA;
            }
            else if (format == 105)
            {
                ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB;
            }

            if (FourCC.ContainsKey(format))
            {
                ddspf.dwFourCC = FourCC[format];
            }
            else if (DX10Formats.Contains(format))
            {
                ddspf.dwFourCC = "DX10";
            }

            if (format == 6)
            {
                ddspf.dwRGBBitCount = 16;
                ddspf.dwRBitMask    = 0b01111100_00000000;
                ddspf.dwGBitMask    = 0b00000011_11100000;
                ddspf.dwBBitMask    = 0b00000000_00011111;
                ddspf.dwABitMask    = 0b10000000_00000000;
            }
            else if (format == 9)
            {
                ddspf.dwRGBBitCount = 32;
                ddspf.dwRBitMask    = 0x00FF0000;
                ddspf.dwGBitMask    = 0x0000FF00;
                ddspf.dwBBitMask    = 0x000000FF;
                ddspf.dwABitMask    = 0xFF000000;
            }
            else if (format == 10)
            {
                ddspf.dwRGBBitCount = 24;
                ddspf.dwRBitMask    = 0x00FF0000;
                ddspf.dwGBitMask    = 0x0000FF00;
                ddspf.dwBBitMask    = 0x000000FF;
            }
            else if (format == 16)
            {
                ddspf.dwRGBBitCount = 8;
                ddspf.dwABitMask    = 0x000000FF;
            }
            else if (format == 105)
            {
                ddspf.dwRGBBitCount = 32;
                ddspf.dwRBitMask    = 0x000000FF;
                ddspf.dwGBitMask    = 0x0000FF00;
                ddspf.dwBBitMask    = 0x00FF0000;
                ddspf.dwABitMask    = 0xFF000000;
            }

            if (DX10Formats.Contains(format))
            {
                dds.header10            = new HEADER_DXT10();
                dds.header10.dxgiFormat = (DXGI_FORMAT)texture.Header.DXGIFormat;
                if (type == TPF.TexType.Cubemap)
                {
                    dds.header10.miscFlag = RESOURCE_MISC.TEXTURECUBE;
                }
            }

            byte[] bytes      = texture.Bytes;
            int    imageCount = type == TPF.TexType.Cubemap ? 6 : 1;

            List <Image> images = null;

            if (CompressedBPB.ContainsKey(format))
            {
                images = Image.ReadCompressed(bytes, width, height, imageCount, mipCount, 0x80, CompressedBPB[format]);
            }
            else if (UncompressedBPP.ContainsKey(format))
            {
                images = Image.ReadUncompressed(bytes, width, height, imageCount, mipCount, 0x80, UncompressedBPP[format]);
            }

            if (format == 10)
            {
                int texelSize  = -1;
                int texelWidth = -1;
                if (format == 10)
                {
                    texelSize  = 4;
                    texelWidth = width;
                }

                foreach (Image image in images)
                {
                    for (int i = 0; i < image.MipLevels.Count; i++)
                    {
                        byte[] swizzled   = image.MipLevels[i];
                        byte[] unswizzled = DeswizzlePS3(swizzled, texelSize, texelWidth / (int)Math.Pow(2, i));
                        if (format == 10)
                        {
                            byte[] trimmed = new byte[unswizzled.Length / 4 * 3];
                            for (int j = 0; j < unswizzled.Length / 4; j++)
                            {
                                Array.Reverse(unswizzled, j * 4, 4);
                                Array.Copy(unswizzled, j * 4, trimmed, j * 3, 3);
                            }
                            unswizzled = trimmed;
                        }
                        image.MipLevels[i] = unswizzled;
                    }
                }
            }

            if (images != null)
            {
                bytes = Image.Write(images);
            }

            return(dds.Write(bytes));
        }
예제 #3
0
            internal void WriteHeader(BinaryWriterEx bw, int index, TPFPlatform platform, byte flag2)
            {
                if (platform == TPFPlatform.PC)
                {
                    DDS dds = new DDS(Bytes);
                    if (dds.dwCaps2.HasFlag(DDS.DDSCAPS2.CUBEMAP))
                    {
                        Type = TexType.Cubemap;
                    }
                    else if (dds.dwCaps2.HasFlag(DDS.DDSCAPS2.VOLUME))
                    {
                        Type = TexType.Volume;
                    }
                    else
                    {
                        Type = TexType.Texture;
                    }
                    Mipmaps = (byte)dds.dwMipMapCount;
                }

                bw.ReserveUInt32($"FileData{index}");
                bw.ReserveInt32($"FileSize{index}");

                bw.WriteByte(Format);
                bw.WriteByte((byte)Type);
                bw.WriteByte(Mipmaps);
                bw.WriteByte(Flags1);

                if (platform != TPFPlatform.PC)
                {
                    bw.WriteInt16(Header.Width);
                    bw.WriteInt16(Header.Height);

                    if (platform == TPFPlatform.Xbox360)
                    {
                        bw.WriteInt32(0);
                    }
                    else if (platform == TPFPlatform.PS3)
                    {
                        bw.WriteInt32(Header.Unk1);
                        if (flag2 != 0)
                        {
                            bw.WriteInt32(Header.Unk2);
                        }
                    }
                    else if (platform == TPFPlatform.PS4 || platform == TPFPlatform.Xbone)
                    {
                        bw.WriteInt32(Header.TextureCount);
                        bw.WriteInt32(Header.Unk2);
                    }
                }

                bw.ReserveUInt32($"FileName{index}");
                bw.WriteInt32(FloatStruct == null ? 0 : 1);

                if (platform == TPFPlatform.PS4 || platform == TPFPlatform.Xbone)
                {
                    bw.WriteInt32(Header.DXGIFormat);
                }

                if (FloatStruct != null)
                {
                    FloatStruct.Write(bw);
                }
            }
예제 #4
0
        public static byte[] Headerize(TPF.Texture texture)
        {
            if (SFEncoding.ASCII.GetString(texture.Bytes, 0, 4) == "DDS ")
            {
                return(texture.Bytes);
            }

            var   dds      = new DDS();
            byte  format   = texture.Format;
            short width    = texture.Header.Width;
            short height   = texture.Header.Height;
            int   mipCount = texture.Mipmaps;

            TPF.TexType type = texture.Type;

            dds.dwFlags = DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PIXELFORMAT | DDSD.MIPMAPCOUNT;
            if (CompressedBPB.ContainsKey(format))
            {
                dds.dwFlags |= DDSD.LINEARSIZE;
            }
            else if (UncompressedBPP.ContainsKey(format))
            {
                dds.dwFlags |= DDSD.PITCH;
            }

            dds.dwHeight = height;
            dds.dwWidth  = width;

            if (CompressedBPB.ContainsKey(format))
            {
                dds.dwPitchOrLinearSize = Math.Max(1, (width + 3) / 4) * CompressedBPB[format];
            }
            else if (UncompressedBPP.ContainsKey(format))
            {
                dds.dwPitchOrLinearSize = (width * UncompressedBPP[format] + 7) / 8;
            }

            // This line serves only to remind me that I didn't forget about dwDepth, I left it 0 on purpose.
            dds.dwDepth = 0;

            if (mipCount == 0)
            {
                mipCount = DetermineMipCount(width, height);
            }
            dds.dwMipMapCount = mipCount;

            dds.dwCaps = DDSCAPS.TEXTURE;
            if (type == TPF.TexType.Cubemap)
            {
                dds.dwCaps |= DDSCAPS.COMPLEX;
            }
            if (mipCount > 1)
            {
                dds.dwCaps |= DDSCAPS.COMPLEX | DDSCAPS.MIPMAP;
            }

            if (type == TPF.TexType.Cubemap)
            {
                dds.dwCaps2 = CUBEMAP_ALLFACES;
            }
            else if (type == TPF.TexType.Volume)
            {
                dds.dwCaps2 = DDSCAPS2.VOLUME;
            }

            PIXELFORMAT ddspf = dds.ddspf;

            if (FourCC.ContainsKey(format) || DX10Formats.Contains(format))
            {
                ddspf.dwFlags = DDPF.FOURCC;
            }
            if (format == 6)
            {
                ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB;
            }
            else if (format == 9)
            {
                ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB;
            }
            else if (format == 10)
            {
                ddspf.dwFlags |= DDPF.RGB;
            }
            else if (format == 16)
            {
                ddspf.dwFlags |= DDPF.ALPHA;
            }
            else if (format == 105)
            {
                ddspf.dwFlags |= DDPF.ALPHAPIXELS | DDPF.RGB;
            }

            if (FourCC.ContainsKey(format))
            {
                ddspf.dwFourCC = FourCC[format];
            }
            else if (DX10Formats.Contains(format))
            {
                ddspf.dwFourCC = "DX10";
            }

            if (format == 6)
            {
                ddspf.dwRGBBitCount = 16;
                ddspf.dwRBitMask    = 0b01111100_00000000;
                ddspf.dwGBitMask    = 0b00000011_11100000;
                ddspf.dwBBitMask    = 0b00000000_00011111;
                ddspf.dwABitMask    = 0b10000000_00000000;
            }
            else if (format == 9)
            {
                ddspf.dwRGBBitCount = 32;
                ddspf.dwRBitMask    = 0x00FF0000;
                ddspf.dwGBitMask    = 0x0000FF00;
                ddspf.dwBBitMask    = 0x000000FF;
                ddspf.dwABitMask    = 0xFF000000;
            }
            else if (format == 10)
            {
                ddspf.dwRGBBitCount = 24;
                ddspf.dwRBitMask    = 0x00FF0000;
                ddspf.dwGBitMask    = 0x0000FF00;
                ddspf.dwBBitMask    = 0x000000FF;
            }
            else if (format == 16)
            {
                ddspf.dwRGBBitCount = 8;
                ddspf.dwABitMask    = 0x000000FF;
            }
            else if (format == 105)
            {
                ddspf.dwRGBBitCount = 32;
                ddspf.dwRBitMask    = 0x000000FF;
                ddspf.dwGBitMask    = 0x0000FF00;
                ddspf.dwBBitMask    = 0x00FF0000;
                ddspf.dwABitMask    = 0xFF000000;
            }

            if (DX10Formats.Contains(format))
            {
                dds.header10            = new HEADER_DXT10();
                dds.header10.dxgiFormat = (DXGI_FORMAT)texture.Header.DXGIFormat;
                if (type == TPF.TexType.Cubemap)
                {
                    dds.header10.miscFlag = RESOURCE_MISC.TEXTURECUBE;
                }
            }

            byte[] bytes = RebuildPixelData(texture.Bytes, format, width, height, mipCount, type);
            return(dds.Write(bytes));
        }