Example #1
0
        private void WriteHeader(BinaryWriter bw)
        {
            var ddsHeader = new DDS_HEADER();

            ddsHeader.dwSize             = ddsHeader.GetSize();
            ddsHeader.dwHeaderFlags      = DDS.DDS_HEADER_FLAGS_TEXTURE | DDS.DDS_HEADER_FLAGS_LINEARSIZE | DDS.DDS_HEADER_FLAGS_MIPMAP;
            ddsHeader.dwHeight           = _height;
            ddsHeader.dwWidth            = _width;
            ddsHeader.dwMipMapCount      = _numMips;
            ddsHeader.PixelFormat.dwSize = ddsHeader.PixelFormat.GetSize();
            ddsHeader.dwDepth            = 1;
            ddsHeader.dwSurfaceFlags     = DDS.DDS_SURFACE_FLAGS_TEXTURE | DDS.DDS_SURFACE_FLAGS_MIPMAP;

            switch ((DXGI_FORMAT)_format)
            {
            case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM:
                ddsHeader.PixelFormat.dwFlags  = DDS.DDS_FOURCC;
                ddsHeader.PixelFormat.dwFourCC = DDS.MAKEFOURCC('D', 'X', 'T', '1');
                ddsHeader.dwPitchOrLinearSize  = (uint)(_width * _height / 2);    // 4bpp
                break;

            case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM:
                ddsHeader.PixelFormat.dwFlags  = DDS.DDS_FOURCC;
                ddsHeader.PixelFormat.dwFourCC = DDS.MAKEFOURCC('D', 'X', 'T', '3');
                ddsHeader.dwPitchOrLinearSize  = (uint)(_width * _height);    // 8bpp
                break;

            case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM:
                ddsHeader.PixelFormat.dwFlags  = DDS.DDS_FOURCC;
                ddsHeader.PixelFormat.dwFourCC = DDS.MAKEFOURCC('D', 'X', 'T', '5');
                ddsHeader.dwPitchOrLinearSize  = (uint)(_width * _height);    // 8bpp
                break;

            case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM:
                ddsHeader.PixelFormat.dwFlags = DDS.DDS_FOURCC;
                if (_bsa.UseATIFourCC)
                {
                    ddsHeader.PixelFormat.dwFourCC = DDS.MAKEFOURCC('A', 'T', 'I', '2');     // this is more correct but the only thing I have found that supports it is the nvidia photoshop plugin
                }
                else
                {
                    ddsHeader.PixelFormat.dwFourCC = DDS.MAKEFOURCC('B', 'C', '5', 'U');
                }
                ddsHeader.dwPitchOrLinearSize = (uint)(_width * _height);     // 8bpp
                break;

            case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB:
                ddsHeader.PixelFormat.dwFlags  = DDS.DDS_FOURCC;
                ddsHeader.PixelFormat.dwFourCC = DDS.MAKEFOURCC('D', 'X', '1', '0');
                ddsHeader.dwPitchOrLinearSize  = (uint)(_width * _height / 2);    // 4bpp
                break;

            case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB:
            case DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16:
            case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM:
            case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM:
            case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM:
            case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB:
                ddsHeader.PixelFormat.dwFlags  = DDS.DDS_FOURCC;
                ddsHeader.PixelFormat.dwFourCC = DDS.MAKEFOURCC('D', 'X', '1', '0');
                ddsHeader.dwPitchOrLinearSize  = (uint)(_width * _height);    // 8bpp
                break;

            case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM:
            case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
                ddsHeader.PixelFormat.dwFlags       = DDS.DDS_RGBA;
                ddsHeader.PixelFormat.dwRGBBitCount = 32;
                ddsHeader.PixelFormat.dwRBitMask    = 0x000000FF;
                ddsHeader.PixelFormat.dwGBitMask    = 0x0000FF00;
                ddsHeader.PixelFormat.dwBBitMask    = 0x00FF0000;
                ddsHeader.PixelFormat.dwABitMask    = 0xFF000000;
                ddsHeader.dwPitchOrLinearSize       = (uint)(_width * _height * 4); // 32bpp
                break;

            case DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM:
            case DXGI_FORMAT.DXGI_FORMAT_B8G8R8X8_UNORM:
                ddsHeader.PixelFormat.dwFlags       = DDS.DDS_RGBA;
                ddsHeader.PixelFormat.dwRGBBitCount = 32;
                ddsHeader.PixelFormat.dwRBitMask    = 0x00FF0000;
                ddsHeader.PixelFormat.dwGBitMask    = 0x0000FF00;
                ddsHeader.PixelFormat.dwBBitMask    = 0x000000FF;
                ddsHeader.PixelFormat.dwABitMask    = 0xFF000000;
                ddsHeader.dwPitchOrLinearSize       = (uint)(_width * _height * 4); // 32bpp
                break;

            case DXGI_FORMAT.DXGI_FORMAT_R8_UNORM:
                ddsHeader.PixelFormat.dwFlags       = DDS.DDS_RGB;
                ddsHeader.PixelFormat.dwRGBBitCount = 8;
                ddsHeader.PixelFormat.dwRBitMask    = 0xFF;
                ddsHeader.dwPitchOrLinearSize       = (uint)(_width * _height); // 8bpp
                break;

            default:
                throw new Exception("Unsupported DDS header format. File: " + FullPath);
            }

            bw.Write((uint)DDS.DDS_MAGIC);
            ddsHeader.Write(bw);

            switch ((DXGI_FORMAT)_format)
            {
            case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB:
            case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB:
            case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM:
            case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM:
            case DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16:
            case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM:
            case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB:
                var dxt10 = new DDS_HEADER_DXT10()
                {
                    dxgiFormat        = _format,
                    resourceDimension = (uint)DXT10_RESOURCE_DIMENSION.DIMENSION_TEXTURE2D,
                    miscFlag          = 0,
                    arraySize         = 1,
                    miscFlags2        = DDS.DDS_ALPHA_MODE_UNKNOWN
                };
                dxt10.Write(bw);
                break;
            }
        }