Beispiel #1
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));
        }
Beispiel #2
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.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 (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 == 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 = DDS_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));
        }
Beispiel #3
0
        private static byte[] RebuildPixelData(byte[] bytes, byte format, short width, short height, int mipCount, TPF.TexType type)
        {
            int imageCount    = type == TPF.TexType.Cubemap ? 6 : 1;
            int padDimensions = 1;

            if (format == 102)
            {
                padDimensions = 32;
            }

            List <Image> images;

            if (CompressedBPB.ContainsKey(format))
            {
                images = Image.ReadCompressed(bytes, width, height, padDimensions, imageCount, mipCount, 0x80, CompressedBPB[format]);
            }
            else if (UncompressedBPP.ContainsKey(format))
            {
                images = Image.ReadUncompressed(bytes, width, height, padDimensions, imageCount, mipCount, 0x80, UncompressedBPP[format]);
            }
            else
            {
                throw new NotSupportedException($"Cannot decompose format {format}.");
            }

            if (format == 10 || format == 102)
            {
                int texelSize = -1;
                if (format == 10)
                {
                    texelSize = 4;
                }
                else if (format == 102)
                {
                    texelSize = 16;
                }

                foreach (Image image in images)
                {
                    for (int i = 0; i < image.MipLevels.Count; i++)
                    {
                        int scale = (int)Math.Pow(2, i);
                        image.MipLevels[i] = DeswizzleMipLevel(image.MipLevels[i], format, texelSize, width / scale, height / scale, padDimensions);
                    }
                }
            }

            return(Image.Write(images));
        }