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