private void InitWithDDSBitmap(BinaryReader reader) { UInt32 magic = reader.ReadUInt32(); UInt32 size = reader.ReadUInt32(); if (magic != DDSMagic || size != 124) { throw new InvalidDataException("Invalid DDS file header"); } // UInt32 flags = reader.ReadUInt32(); int height = reader.ReadInt32(); int width = reader.ReadInt32(); int pitchOrLinearSize = (int)reader.ReadUInt32(); // UInt32 depth = reader.ReadUInt32(); UInt32 mipMapCount = reader.ReadUInt32(); reader.ReadBytes(11 * 4); // Read pixel format reader.ReadUInt32(); // Structure size (32 bytes) DDSPFFlags pfFlags = (DDSPFFlags)reader.ReadUInt32(); UInt32 pfFourCC = reader.ReadUInt32(); // UInt32 pfRGBBitCount = reader.ReadUInt32(); // UInt32 pfRBitMask = reader.ReadUInt32(); // UInt32 pfGBitMask = reader.ReadUInt32(); // UInt32 pfBBitMask = reader.ReadUInt32(); // UInt32 pfABitMask = reader.ReadUInt32(); // read the rest of header // UInt32 caps = reader.ReadUInt32(); // UInt32 caps2 = reader.ReadUInt32(); // UInt32 caps3 = reader.ReadUInt32(); // UInt32 caps4 = reader.ReadUInt32(); // UInt32 reserved2 = reader.ReadUInt32(); Format format; if ((pfFlags & DDSPFFlags.RGB) != 0) { format = Format.R8G8B8A8_UNorm; } else { switch ((DDSFourCC)pfFourCC) { case DDSFourCC.DXT1: format = Format.BC1_RGB_UNorm_Block; break; case DDSFourCC.DXT3: format = Format.BC2_UNorm_Block; break; case DDSFourCC.DXT5: format = Format.BC3_UNorm_Block; break; default: throw new InvalidDataException("Unsupported texture format"); } } SurfaceSize = ImageSize = new Size(width, height); mipMapCount = 1; if (mipMapCount > 1 && mipMapCount != GraphicsUtility.CalculateMipLevelCount(width, height)) { throw new NotSupportedException(); } Action deferredCommands = () => EnsurePlatformTexture(format, width, height, mipMapCount > 1); MemoryUsed = 0; for (int level = 0; level < mipMapCount; level++) { var levelCopy = level; var buffer = ReadTextureData(reader, GraphicsUtility.CalculateMipLevelDataSize(levelCopy, format, width, height)); deferredCommands += () => platformTexture.SetData(levelCopy, buffer); } Window.Current.InvokeOnRendering(deferredCommands); }
private void InitWithKTXTexture(BinaryReader reader) { var identifier = reader.ReadBytes(12); if (identifier[1] != 'K' || identifier[2] != 'T' || identifier[3] != 'X') { throw new InvalidDataException("Invalid KTX header"); } var endiannes = reader.ReadUInt32(); if (endiannes != 0x04030201) { throw new InvalidDataException("Unsupported endiannes"); } var glType = reader.ReadInt32(); var glTypeSize = reader.ReadInt32(); var glFormat = reader.ReadInt32(); var glInternalFormat = reader.ReadInt32(); var glBaseInternalFormat = reader.ReadInt32(); var pixelWidth = reader.ReadInt32(); var pixelHeight = reader.ReadInt32(); var pixelDepth = reader.ReadInt32(); var numberOfArrayElements = reader.ReadInt32(); var numberOfFaces = reader.ReadInt32(); var numberOfMipmapLevels = Math.Max(1, reader.ReadInt32()); var bytesOfKeyValueData = reader.ReadInt32(); reader.ReadBytes(bytesOfKeyValueData); if (numberOfArrayElements != 0) { throw new InvalidDataException("Array textures are not supported"); } if (numberOfFaces != 1) { throw new InvalidDataException("Cubemap textures are not supported"); } if (pixelDepth != 0) { throw new InvalidDataException("3D Textures are not supported"); } if ((pixelWidth & 3) != 0 || (pixelHeight & 3) != 0) { throw new InvalidDataException("Texture dimensions should multiple of 4"); } if (numberOfMipmapLevels > 1 && numberOfMipmapLevels != GraphicsUtility.CalculateMipLevelCount(pixelWidth, pixelHeight)) { throw new InvalidDataException(); } var format = ConvertGLFormat(glInternalFormat, glBaseInternalFormat, glFormat, glType); var etcFormat = format == Format.ETC1_R8G8B8_UNorm_Block || format == Format.ETC2_R8G8B8_UNorm_Block || format == Format.ETC2_R8G8B8A1_UNorm_Block || format == Format.ETC2_R8G8B8A8_UNorm_Block; SurfaceSize = ImageSize = new Size(pixelWidth, pixelHeight); Action deferredCommands = null; for (int level = 0; level < numberOfMipmapLevels; level++) { var levelCopy = level; var dataLength = reader.ReadInt32(); var data = ReadTextureData(reader, dataLength); GraphicsUtility.CalculateMipLevelSize(levelCopy, pixelWidth, pixelHeight, out var levelWidth, out var levelHeight); MemoryUsed = 0; deferredCommands += () => { var formatFeatures = PlatformRenderer.Context.GetFormatFeatures(format); if (etcFormat && (formatFeatures & FormatFeatures.Sample) == 0) { var rgba8Data = Marshal.AllocHGlobal(levelWidth * levelHeight * 4); try { Etc2Decoder.Decode(data, rgba8Data, levelWidth, levelHeight, format); EnsurePlatformTexture(Format.R8G8B8A8_UNorm, pixelWidth, pixelHeight, numberOfMipmapLevels > 1); platformTexture.SetData(levelCopy, rgba8Data); } finally { Marshal.FreeHGlobal(rgba8Data); } } else { EnsurePlatformTexture(format, pixelWidth, pixelHeight, numberOfMipmapLevels > 1); platformTexture.SetData(levelCopy, data); } }; } Window.Current.InvokeOnRendering(deferredCommands); }
private void InitWithPVRTexture(BinaryReader reader) { var version = reader.ReadUInt32(); if (version != PVRMagic) { throw new Exception("Invalid PVR header"); } reader.ReadUInt32(); // flags var pvrFormat = (PVRFormat)reader.ReadUInt64(); reader.ReadUInt32(); // color space reader.ReadUInt32(); // channel type var height = reader.ReadInt32(); var width = reader.ReadInt32(); reader.ReadUInt32(); // depth reader.ReadUInt32(); // num surfaces reader.ReadUInt32(); // num faces var numMipmaps = reader.ReadInt32(); var metaDataSize = reader.ReadInt32(); if (metaDataSize > 0) { reader.ReadChars(metaDataSize); } Format format; switch (pvrFormat) { case PVRFormat.ETC1: format = Format.ETC1_R8G8B8_UNorm_Block; break; case PVRFormat.PVRTC_2_RGBA: format = Format.PVRTC1_2Bpp_UNorm_Block; break; case PVRFormat.PVRTC_4_RGBA: format = Format.PVRTC1_4Bpp_UNorm_Block; break; case PVRFormat.RGB565: format = Format.R5G6B5_UNorm_Pack16; break; case PVRFormat.RGBA4444: format = Format.R4G4B4A4_UNorm_Pack16; break; case PVRFormat.RGBA8888: format = Format.R8G8B8A8_UNorm; break; default: throw new NotSupportedException(); } SurfaceSize = ImageSize = new Size(width, height); if (numMipmaps > 1 && numMipmaps != GraphicsUtility.CalculateMipLevelCount(width, height)) { throw new NotSupportedException(); } Action deferredCommands = () => EnsurePlatformTexture(format, width, height, numMipmaps > 1); MemoryUsed = 0; for (int level = 0; level < numMipmaps; level++) { var levelCopy = level; var buffer = ReadTextureData(reader, GraphicsUtility.CalculateMipLevelDataSize(levelCopy, format, width, height)); deferredCommands += () => platformTexture.SetData(levelCopy, buffer); } Window.Current.InvokeOnRendering(deferredCommands); }