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