public static void WriteHeader(Stream stream, DDS_HEADER header, DDS_HEADER_DXT10 dxt10header) { stream.Write(BitConverter.GetBytes(DDS_MAGIC), 0, 4); WriteStruct(header, stream); if (header.ddspf.dwFourCC == MAKEFOURCC('D', 'X', '1', '0')) { WriteStruct(dxt10header, stream); } }
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); }
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); }