Exemplo n.º 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];
 }
Exemplo n.º 2
0
        public 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;

            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;
            }

            // dwPitchOrLinearSize
            switch (format)
            {
            case ETextureFormat.TEXFMT_BC1:
            case ETextureFormat.TEXFMT_BC2:
            case ETextureFormat.TEXFMT_BC3:
            case ETextureFormat.TEXFMT_BC4:
            case ETextureFormat.TEXFMT_BC5:
            case ETextureFormat.TEXFMT_BC6H:
            case ETextureFormat.TEXFMT_BC7:
            {
                /*var blocksize = 16;
                 * if (format == ETextureFormat.TEXFMT_BC1 || format == ETextureFormat.TEXFMT_BC4)
                 *  blocksize = 8;
                 *
                 * var f = ((float)width + 3) / 4;
                 * var p =(Math.Max(1, f) * blocksize);
                 * //var p = (uint)(Math.Max(1, ((width + 3) / 4)) * blocksize);*/
                uint p = 0;
                if (format == ETextureFormat.TEXFMT_BC1 || format == ETextureFormat.TEXFMT_BC4)
                {
                    p = width * height / 2;
                }
                else
                {
                    p = width * height;
                }

                header.dwPitchOrLinearSize = (uint)(p);
                header.dwFlags            |= DDSD_LINEARSIZE;
                break;
            }

            case ETextureFormat.TEXFMT_R8G8B8A8:
            default:
            {
                header.dwPitchOrLinearSize = (width * metadata.Bpp + 7) / 8;
                header.dwFlags            |= DDSD_PITCH;
                break;
            }
            }
            // 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;

            // pixelformat
            {
                // dwFourCC
                switch (format)
                {
                case ETextureFormat.TEXFMT_R8G8B8A8:
                {
                    ddspf.dwRGBBitCount = 32;
                    ddspf.dwRBitMask    = 0xff;
                    ddspf.dwGBitMask    = 0xff00;
                    ddspf.dwBBitMask    = 0xff0000;
                    ddspf.dwABitMask    = 0xff000000;

                    /*ddspf.dwRBitMask = 0x0f00;
                    *  ddspf.dwGBitMask = 0x00f0;
                    *  ddspf.dwBBitMask = 0x000f;
                    *  ddspf.dwABitMask = 0xf000;*/
                    break;
                }

                case ETextureFormat.TEXFMT_BC1:
                {
                    ddspf.dwFourCC = MAKEFOURCC('D', 'X', 'T', '1');
                    break;
                }

                case ETextureFormat.TEXFMT_BC2:
                {
                    ddspf.dwFourCC = MAKEFOURCC('D', 'X', 'T', '3'); break;
                }

                case ETextureFormat.TEXFMT_BC3:
                {
                    ddspf.dwFourCC = MAKEFOURCC('D', 'X', 'T', '5'); break;
                }

                case ETextureFormat.TEXFMT_BC4:
                {
                    ddspf.dwFourCC = MAKEFOURCC('A', 'T', 'I', '1'); break;
                }

                case ETextureFormat.TEXFMT_BC5:
                {
                    ddspf.dwFourCC = MAKEFOURCC('A', 'T', 'I', '2'); break;
                }

                case ETextureFormat.TEXFMT_Float_R16G16B16A16:
                {
                    ddspf.dwFourCC = 113; break;
                }

                case ETextureFormat.TEXFMT_Float_R32G32B32A32:
                {
                    ddspf.dwFourCC = 116; break;
                }

                case ETextureFormat.TEXFMT_BC6H:
                case ETextureFormat.TEXFMT_BC7:
                default:
                {
                    break;
                }
                }
                if (metadata.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;
            }

            // 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 (metadata.DXT10)
            {
                // dxgiFormat
                switch (format)
                {
                case ETextureFormat.TEXFMT_R8G8B8A8: dxt10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM;
                    break;

                case ETextureFormat.TEXFMT_Float_R16G16B16A16: dxt10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT;
                    break;

                case ETextureFormat.TEXFMT_Float_R32G32B32A32:
                    dxt10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT;
                    break;

                case ETextureFormat.TEXFMT_BC1:
                    dxt10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM;
                    break;

                case ETextureFormat.TEXFMT_BC2:
                    dxt10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM;
                    break;

                case ETextureFormat.TEXFMT_BC3:
                    dxt10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM;
                    break;

                case ETextureFormat.TEXFMT_BC4:
                    dxt10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM;
                    break;

                case ETextureFormat.TEXFMT_BC5:
                    dxt10header.dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM;
                    break;

                case ETextureFormat.TEXFMT_BC6H:
                case ETextureFormat.TEXFMT_BC7:
                default:
                    break;
                }
                // 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);
        }
Exemplo n.º 3
0
        public 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 ETextureFormat.TEXFMT_R8G8B8X8:            SetPixelmask(DDSPF_X8R8G8B8, ref ddspf);            break;
                case ETextureFormat.TEXFMT_R8G8B8A8: SetPixelmask(DDSPF_A8R8G8B8, ref ddspf); break;

                //case ETextureFormat.TEXFMT_R16G16_Uint:         SetPixelmask(DDSPF_G16R16, ref ddspf);              break;
                case ETextureFormat.TEXFMT_BC1: ddspf.dwFourCC = MAKEFOURCC('D', 'X', 'T', '1'); break;

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

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

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

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

                //case ETextureFormat.TEXFMT_Float_R16G16B16A16:  ddspf.dwFourCC = 113;                               break;
                //case ETextureFormat.TEXFMT_Float_R32G32B32A32:  ddspf.dwFourCC = 116;                               break;
                //case ETextureFormat.TEXFMT_BC6H:
                case ETextureFormat.TEXFMT_BC7: dxt10 = true; break;

                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
            switch (format)
            {
            case ETextureFormat.TEXFMT_BC1:
            case ETextureFormat.TEXFMT_BC2:
            case ETextureFormat.TEXFMT_BC3:
            case ETextureFormat.TEXFMT_BC4:
            case ETextureFormat.TEXFMT_BC5:
            //case ETextureFormat.TEXFMT_BC6H:
            case ETextureFormat.TEXFMT_BC7:
            {
                uint p = 0;
                if (format == ETextureFormat.TEXFMT_BC1 || format == ETextureFormat.TEXFMT_BC4)
                {
                    p = width * height / 2;
                }
                else
                {
                    p = width * height;
                }

                header.dwPitchOrLinearSize = (uint)(p);
                header.dwFlags            |= DDSD_LINEARSIZE;
                break;
            }

            case ETextureFormat.TEXFMT_R8G8B8A8:
                //case ETextureFormat.TEXFMT_R8G8B8X8:
                //case ETextureFormat.TEXFMT_R16G16_Uint:
            {
                var bpp = ddspf.dwRGBBitCount;
                header.dwPitchOrLinearSize = (width * bpp + 7) / 8;
                header.dwFlags            |= DDSD_PITCH;
                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 ETextureFormat.TEXFMT_BC7:
                {
                    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);
        }