Beispiel #1
0
 private static void SetPixelmask(Func <uint[]> pfmtfactory, ref DDS_PIXELFORMAT pfmt)
 {
     uint[] masks = pfmtfactory.Invoke();
     pfmt.dwRGBBitCount = masks[0];
     pfmt.dwRBitMask    = masks[1];
     pfmt.dwGBitMask    = masks[2];
     pfmt.dwBBitMask    = masks[3];
     pfmt.dwABitMask    = masks[4];
 }
Beispiel #2
0
        private static (DDS_HEADER, DDS_HEADER_DXT10) GenerateHeader(DDSMetadata metadata)
        {
            var  height    = metadata.Height;
            var  width     = metadata.Width;
            var  mipscount = metadata.Mipscount;
            var  iscubemap = metadata.Iscubemap;
            var  format    = metadata.Format;
            bool dxt10     = false;

            var ddspf = new DDS_PIXELFORMAT()
            {
                dwSize        = PIXELFORMAT_SIZE,
                dwFlags       = 0,
                dwFourCC      = 0,
                dwRGBBitCount = 0,
                dwRBitMask    = 0,
                dwGBitMask    = 0,
                dwBBitMask    = 0,
                dwABitMask    = 0
            };

            var header = new DDS_HEADER()
            {
                dwSize              = HEADER_SIZE,
                dwFlags             = DDS_HEADER_FLAGS_TEXTURE,
                dwHeight            = height,
                dwWidth             = width,
                dwPitchOrLinearSize = 0,
                dwDepth             = 0,
                dwMipMapCount       = 0,
                dwReserved1         = 0,
                dwReserved2         = 0,
                dwReserved3         = 0,
                dwReserved4         = 0,
                dwReserved5         = 0,
                dwReserved6         = 0,
                dwReserved7         = 0,
                dwReserved8         = 0,
                dwReserved9         = 0,
                dwReserved10        = 0,
                dwReserved11        = 0,
                ddspf        = ddspf,
                dwCaps       = DDSCAPS_TEXTURE,
                dwCaps2      = 0,
                dwCaps3      = 0,
                dwCaps4      = 0,
                dwReserved12 = 0,
            };

            var dxt10header = new DDS_HEADER_DXT10()
            {
                dxgiFormat        = 0,
                resourceDimension = D3D10_RESOURCE_DIMENSION.D3D10_RESOURCE_DIMENSION_TEXTURE2D,
                miscFlag          = 0,
                arraySize         = metadata.Slicecount,
                miscFlags2        = 0
            };

            if (mipscount > 0)
            {
                header.dwMipMapCount = mipscount;
            }


            // pixelformat
            {
                // dwFourCC
                switch (format)
                {
                case EFormat.R8G8B8A8_UNORM:
                    SetPixelmask(DDSPF_A8R8G8B8, ref ddspf); break;

                case EFormat.BC1_UNORM:
                    ddspf.dwFourCC = MAKEFOURCC('D', 'X', 'T', '1'); break;

                case EFormat.BC2_UNORM:
                    ddspf.dwFourCC = MAKEFOURCC('D', 'X', 'T', '3'); break;

                case EFormat.BC3_UNORM:
                    ddspf.dwFourCC = MAKEFOURCC('D', 'X', 'T', '5'); break;

                case EFormat.BC4_UNORM:
                    ddspf.dwFourCC = MAKEFOURCC('B', 'C', '4', 'U'); break;

                case EFormat.BC5_UNORM:
                    ddspf.dwFourCC = MAKEFOURCC('B', 'C', '5', 'U'); break;

                case EFormat.BC7_UNORM:
                    dxt10 = true; break;

                //case EFormat.R32G32B32A32_FLOAT:
                //case EFormat.R16G16B16A16_FLOAT:
                //case EFormat.BC6H_UF16:
                default:
                    throw new MissingFormatException($"Missing Format: {format}");
                }
                if (dxt10)
                {
                    ddspf.dwFourCC = MAKEFOURCC('D', 'X', '1', '0');
                }

                // dwflags
                if (ddspf.dwABitMask != 0) // check this
                {
                    ddspf.dwFlags |= DDPF_ALPHAPIXELS;
                }

                /*if (ddspf.dwABitMask != 0)
                 *  ddspf.dwFlags |= DDPF_ALPHA;*///old
                if (ddspf.dwFourCC != 0)
                {
                    ddspf.dwFlags |= DDPF_FOURCC;
                }
                if (ddspf.dwRGBBitCount != 0 && (ddspf.dwRBitMask != 0 || ddspf.dwGBitMask != 0 || ddspf.dwBBitMask != 0))
                {
                    ddspf.dwFlags |= DDPF_RGB;
                }
                if (metadata.Normal)
                {
                    ddspf.dwFlags |= DDPF_NORMAL; //custom nv flag
                }
                header.ddspf = ddspf;
            }

            // dwPitchOrLinearSize
            uint p = 0;

            switch (format)
            {
            case EFormat.R8G8B8A8_UNORM:
                var bpp = ddspf.dwRGBBitCount;
                header.dwPitchOrLinearSize = (width * bpp + 7) / 8;
                header.dwFlags            |= DDSD_PITCH;
                break;

            case EFormat.BC1_UNORM:
            case EFormat.BC4_UNORM:
                p = width * height / 2;     //max(1,width ?4)x max(1,height ?4)x 8 (DXT1)
                header.dwPitchOrLinearSize = (uint)(p);
                header.dwFlags            |= DDSD_LINEARSIZE;
                break;

            case EFormat.BC2_UNORM:
            case EFormat.BC3_UNORM:
            case EFormat.BC5_UNORM:
            case EFormat.BC7_UNORM:
                p = width * height;         //max(1,width ?4)x max(1,height ?4)x 16 (DXT2-5)
                header.dwPitchOrLinearSize = (uint)(p);
                header.dwFlags            |= DDSD_LINEARSIZE;
                break;

            //case EFormat.BC6H_UF16:
            //case EFormat.R32G32B32A32_FLOAT:
            //case EFormat.R16G16B16A16_FLOAT:
            default:
                throw new MissingFormatException($"Missing Format: {format}");
            }
            // unused R8G8_B8G8, G8R8_G8B8, legacy UYVY-packed, and legacy YUY2-packed formats,
            // header.dwPitchOrLinearSize = ((width + 1) >> 1) * 4;

            // depth
            //if (slicecount > 0  && !iscubemap)
            //    header.dwDepth = slicecount;


            // caps
            if (iscubemap || mipscount > 0)
            {
                header.dwCaps |= DDSCAPS_COMPLEX;
            }
            if (mipscount > 0)
            {
                header.dwCaps |= DDSCAPS_MIPMAP;
            }

            // caps2
            if (iscubemap)
            {
                header.dwCaps2 |= DDSCAPS2_CUBEMAP_ALL_FACES | DDSCAPS2_CUBEMAP;
            }
            //if (slicecount > 0)
            //    header.dwCaps2 |= DDSCAPS2_VOLUME;

            // flags
            //if (slicecount > 0)
            //    header.dwFlags |= DDSD_DEPTH;
            if (mipscount > 0)
            {
                header.dwFlags |= DDSD_MIPMAPCOUNT;
            }

            // DXT10
            if (dxt10)
            {
                // dxgiFormat
                switch (format)
                {
                case EFormat.BC7_UNORM:
                {
                    dxt10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM;
                    break;
                }

                default:
                {
                    throw new MissingFormatException($"Missing Format: {format}");
                }
                }
                // resourceDimension
                //if (slicecount > 0)
                //    dxt10header.resourceDimension = D3D10_RESOURCE_DIMENSION.D3D10_RESOURCE_DIMENSION_TEXTURE3D;
                //misc flag
                if (iscubemap)
                {
                    dxt10header.miscFlag |= DDS_RESOURCE_MISC_TEXTURECUBE;
                }
                if (mipscount > 0)
                {
                    dxt10header.miscFlag |= D3D10_RESOURCE_MISC_GENERATE_MIPS;
                }
                // array size
                if (iscubemap)
                {
                    dxt10header.arraySize = metadata.Slicecount;
                }
                // miscFlags2
            }

            return(header, dxt10header);
        }