Пример #1
0
        public static (DdsHeader, DdsHeaderDxt10) InitializeCompressed(int width, int height, DXGI_FORMAT format)
        {
            DdsHeader      header      = new DdsHeader();
            DdsHeaderDxt10 dxt10Header = new DdsHeaderDxt10();

            header.dwSize        = 124;
            header.dwFlags       = HeaderFlags.REQUIRED;
            header.dwWidth       = (uint)width;
            header.dwHeight      = (uint)height;
            header.dwDepth       = 1;
            header.dwMipMapCount = 1;
            header.dwCaps        = HeaderCaps.DDSCAPS_TEXTURE;

            if (format == DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM)
            {
                header.ddsPixelFormat = new DdsPixelFormat()
                {
                    dwSize   = 32,
                    dwFlags  = PixelFormatFlags.DDPF_FOURCC,
                    dwFourCC = DdsPixelFormat.DXT1
                };
            }
            else if (format == DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM)
            {
                header.ddsPixelFormat = new DdsPixelFormat()
                {
                    dwSize   = 32,
                    dwFlags  = PixelFormatFlags.DDPF_FOURCC,
                    dwFourCC = DdsPixelFormat.DXT3
                };
            }
            else if (format == DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM)
            {
                header.ddsPixelFormat = new DdsPixelFormat()
                {
                    dwSize   = 32,
                    dwFlags  = PixelFormatFlags.DDPF_FOURCC,
                    dwFourCC = DdsPixelFormat.DXT5
                };
            }
            else
            {
                header.ddsPixelFormat = new DdsPixelFormat()
                {
                    dwSize   = 32,
                    dwFlags  = PixelFormatFlags.DDPF_FOURCC,
                    dwFourCC = DdsPixelFormat.DX10
                };
                dxt10Header.arraySize         = 1;
                dxt10Header.dxgiFormat        = format;
                dxt10Header.resourceDimension = D3D10_RESOURCE_DIMENSION.D3D10_RESOURCE_DIMENSION_TEXTURE2D;
            }

            return(header, dxt10Header);
        }
Пример #2
0
        public static DdsFile Load(Stream s)
        {
            using (BinaryReader br = new BinaryReader(s, Encoding.UTF8, true))
            {
                var magic = br.ReadUInt32();
                if (magic != 0x20534444U)
                {
                    throw new FormatException("The file does not contain a dds file.");
                }
                DdsHeader      header      = br.ReadStruct <DdsHeader>();
                DdsHeaderDxt10 dxt10Header = default;
                if (header.dwSize != 124)
                {
                    throw new FormatException("The file header contains invalid dwSize.");
                }

                bool dxt10Format = header.ddsPixelFormat.IsDxt10Format;

                DdsFile output;

                if (dxt10Format)
                {
                    dxt10Header = br.ReadStruct <DdsHeaderDxt10>();
                    output      = new DdsFile(header, dxt10Header);
                }
                else
                {
                    output = new DdsFile(header);
                }

                uint mipMapCount = (header.dwCaps & HeaderCaps.DDSCAPS_MIPMAP) != 0 ? header.dwMipMapCount : 1;
                uint faceCount   = ((header.dwCaps2 & HeaderCaps2.DDSCAPS2_CUBEMAP) != 0) ? (uint)6 : (uint)1;
                uint width       = header.dwWidth;
                uint height      = header.dwHeight;

                for (int face = 0; face < faceCount; face++)
                {
                    uint sizeInBytes = Math.Max(1, ((width + 3) / 4)) * Math.Max(1, ((height + 3) / 4));
                    if (!dxt10Format)
                    {
                        if (header.ddsPixelFormat.IsDxt1To5CompressedFormat)
                        {
                            if (header.ddsPixelFormat.DxgiFormat == DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM)
                            {
                                sizeInBytes *= 8;
                            }
                            else
                            {
                                sizeInBytes *= 16;
                            }
                        }
                        else
                        {
                            sizeInBytes = header.dwPitchOrLinearSize * height;
                        }
                    }
                    else if (dxt10Header.dxgiFormat.IsCompressedFormat())
                    {
                        sizeInBytes = (uint)(sizeInBytes * dxt10Header.dxgiFormat.GetByteSize());
                    }
                    else
                    {
                        sizeInBytes = header.dwPitchOrLinearSize * height;
                    }
                    output.Faces.Add(new DdsFace(width, height, sizeInBytes, (int)mipMapCount));

                    for (int mip = 0; mip < mipMapCount; mip++)
                    {
                        uint mipWidth  = header.dwWidth / (uint)(Math.Pow(2, mip));
                        uint mipHeight = header.dwHeight / (uint)(Math.Pow(2, mip));

                        if (mip > 0)                         //Calculate new byteSize
                        {
                            sizeInBytes = Math.Max(1, ((mipWidth + 3) / 4)) * Math.Max(1, ((mipHeight + 3) / 4));
                            if (!dxt10Format)
                            {
                                if (header.ddsPixelFormat.IsDxt1To5CompressedFormat)
                                {
                                    if (header.ddsPixelFormat.DxgiFormat == DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM)
                                    {
                                        sizeInBytes *= 8;
                                    }
                                    else
                                    {
                                        sizeInBytes *= 16;
                                    }
                                }
                                else
                                {
                                    sizeInBytes = header.dwPitchOrLinearSize / (uint)(Math.Pow(2, mip)) * mipHeight;
                                }
                            }
                            else if (dxt10Header.dxgiFormat.IsCompressedFormat())
                            {
                                sizeInBytes = (uint)(sizeInBytes * dxt10Header.dxgiFormat.GetByteSize());
                            }
                            else
                            {
                                sizeInBytes = header.dwPitchOrLinearSize / (uint)(Math.Pow(2, mip)) * mipHeight;
                            }
                        }
                        byte[] data = new byte[sizeInBytes];
                        br.Read(data);
                        output.Faces[face].MipMaps[mip] = new DdsMipMap(data, mipWidth, mipHeight);
                    }
                }

                return(output);
            }
        }
Пример #3
0
 public DdsFile(DdsHeader header, DdsHeaderDxt10 dxt10Header)
 {
     this.Header      = header;
     this.Dxt10Header = dxt10Header;
 }