Beispiel #1
0
 private static void WriteHeader(Stream stream, DDS_HEADER header, DDS_HEADER_DXT10 dxt10header)
 {
     stream.Write(BitConverter.GetBytes(DDS_MAGIC), 0, 4);
     stream.WriteStruct(header);
     if (header.ddspf.dwFourCC == MAKEFOURCC('D', 'X', '1', '0'))
     {
         stream.WriteStruct(dxt10header);
     }
 }
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     = /*metadata.Format == EFormat.BC7_UNORM;*/ metadata.Dx10; //TODO
            // for BC7_UNORM, R8_UINT

            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 dx10header = new DDS_HEADER_DXT10()
            {
                dxgiFormat        = DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM,
                resourceDimension = D3D10_RESOURCE_DIMENSION.D3D10_RESOURCE_DIMENSION_TEXTURE2D,
                miscFlag          = 0,
                arraySize         = metadata.Slicecount,
                miscFlags2        = 0
            };

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

            // pixelformat
            {
                // dwFourCC
                if (dxt10)
                {
                    ddspf.dwFourCC = MAKEFOURCC('D', 'X', '1', '0');
                }
                else
                {
                    switch (format)
                    {
                    case EFormat.R32G32B32A32_FLOAT:
                        ddspf.dwFourCC = 116;
                        break;

                    case EFormat.R16G16B16A16_FLOAT:
                        ddspf.dwFourCC = 113;
                        break;

                    case EFormat.R10G10B10A2_UNORM:
                        throw new NotImplementedException();

                    case EFormat.R32_UINT:
                        throw new NotImplementedException();

                    case EFormat.R8G8_UNORM:
                        SetPixelmask(DDSPF_A8L8, ref ddspf);
                        break;

                    case EFormat.R16_FLOAT:
                        ddspf.dwFourCC = 111;
                        break;

                    case EFormat.R8_UNORM:
                    case EFormat.R8_UINT:
                        SetPixelmask(DDSPF_L8, ref ddspf);
                        break;

                    case EFormat.A8_UNORM:
                        SetPixelmask(DDSPF_A8, ref ddspf);
                        break;

                    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;

                    default:
                        throw new MissingFormatException($"Missing format: {format}");
                    }
                }

                // 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 (ddspf.dwRBitMask != 0 && ddspf.dwGBitMask == 0 && ddspf.dwBBitMask == 0 && ddspf.dwABitMask == 0)
                {
                    ddspf.dwFlags |= DDPF_LUMINANCE;
                }

                header.ddspf = ddspf;
            }

            // dwPitchOrLinearSize
            uint p   = 0;
            var  bpp = ddspf.dwRGBBitCount;

            switch (format)
            {
            case EFormat.R8_UNORM:
                header.dwPitchOrLinearSize = (width * bpp + 7) / 8;
                break;

            case EFormat.R32G32B32A32_FLOAT:
            case EFormat.R16G16B16A16_FLOAT:
            case EFormat.R10G10B10A2_UNORM:
            case EFormat.R32_UINT:
            case EFormat.R8_UINT:
            case EFormat.R8G8_UNORM:
            case EFormat.R16_FLOAT:
            case EFormat.A8_UNORM:
            case EFormat.R8G8B8A8_UNORM:
                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;

            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.R32G32B32A32_FLOAT:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT;
                    break;

                case EFormat.R16G16B16A16_FLOAT:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT;
                    break;

                case EFormat.R10G10B10A2_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UNORM;
                    break;

                case EFormat.R8G8B8A8_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM;
                    break;

                case EFormat.R32_UINT:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R32_UINT;
                    break;

                case EFormat.R8G8_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM;
                    break;

                case EFormat.R16_FLOAT:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R16_FLOAT;
                    break;

                case EFormat.R8_UINT:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R8_UINT;
                    break;

                case EFormat.R8_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R8_UNORM;
                    break;

                case EFormat.A8_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_A8_UNORM;
                    break;

                case EFormat.BC1_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM;
                    break;

                case EFormat.BC2_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM;
                    break;

                case EFormat.BC3_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM;
                    break;

                case EFormat.BC4_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM;
                    break;

                case EFormat.BC7_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM;
                    break;

                case EFormat.BC5_UNORM:
                    dx10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC5_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, dx10header);
        }