private static void CompressPvrtc(TextureContent content, bool generateMipmaps, bool premultipliedAlpha) { // TODO: Once uncompressed mipmap generation is supported, first use NVTT to generate mipmaps, // then compress them withthe PVRTC tool, so we have the same implementation of mipmap generation // across platforms. // Calculate number of mip levels var width = content.Faces[0][0].Height; var height = content.Faces[0][0].Width; var numberOfMipLevels = 1; if (generateMipmaps) { while (height != 1 || width != 1) { height = Math.Max(height / 2, 1); width = Math.Max(width / 2, 1); numberOfMipLevels++; } } IntPtr dataSizesPtr = IntPtr.Zero; var texDataPtr = ManagedPVRTC.ManagedPVRTC.CompressTexture(content.Faces[0][0].GetPixelData(), content.Faces[0][0].Height, content.Faces[0][0].Width, numberOfMipLevels, premultipliedAlpha, true, ref dataSizesPtr); // Store the size of each mip level var dataSizesArray = new int[numberOfMipLevels]; Marshal.Copy(dataSizesPtr, dataSizesArray, 0, dataSizesArray.Length); var levelSize = 0; byte[] levelData; var sourceWidth = content.Faces[0][0].Width; var sourceHeight = content.Faces[0][0].Height; content.Faces[0].Clear(); for (int x = 0; x < numberOfMipLevels; x++) { levelSize = dataSizesArray[x]; levelData = new byte[levelSize]; Marshal.Copy(texDataPtr, levelData, 0, levelSize); var levelWidth = Math.Max(sourceWidth >> x, 1); var levelHeight = Math.Max(sourceHeight >> x, 1); var bmpContent = new PvrtcBitmapContent(4, sourceWidth, sourceHeight); bmpContent.SetPixelData(levelData); content.Faces[0].Add(bmpContent); texDataPtr = IntPtr.Add(texDataPtr, levelSize); } }
private static void CompressPvrtc(TextureContent content, bool generateMipmaps, bool premultipliedAlpha) { // TODO: Once uncompressed mipmap generation is supported, first use NVTT to generate mipmaps, // then compress them withthe PVRTC tool, so we have the same implementation of mipmap generation // across platforms. // Calculate number of mip levels var width = content.Faces[0][0].Height; var height = content.Faces[0][0].Width; if (!IsPowerOfTwo(width) || !IsPowerOfTwo(height)) throw new PipelineException("PVRTC Compressed textures width and height must be powers of two."); if (width != height) throw new PipelineException("PVRTC Compressed textures must be square. i.e width == height."); var numberOfMipLevels = 1; if (generateMipmaps) { while (height != 1 || width != 1) { height = Math.Max(height / 2, 1); width = Math.Max(width / 2, 1); numberOfMipLevels++; } } IntPtr dataSizesPtr = IntPtr.Zero; var texDataPtr = ManagedPVRTC.ManagedPVRTC.CompressTexture(content.Faces[0][0].GetPixelData(), content.Faces[0][0].Height, content.Faces[0][0].Width, numberOfMipLevels, premultipliedAlpha, true, ref dataSizesPtr); // Store the size of each mip level var dataSizesArray = new int[numberOfMipLevels]; Marshal.Copy(dataSizesPtr, dataSizesArray, 0, dataSizesArray.Length); var levelSize = 0; byte[] levelData; var sourceWidth = content.Faces[0][0].Width; var sourceHeight = content.Faces[0][0].Height; content.Faces[0].Clear(); for (int x = 0; x < numberOfMipLevels; x++) { levelSize = dataSizesArray[x]; levelData = new byte[levelSize]; Marshal.Copy(texDataPtr, levelData, 0, levelSize); var levelWidth = Math.Max(sourceWidth >> x, 1); var levelHeight = Math.Max(sourceHeight >> x, 1); var bmpContent = new PvrtcBitmapContent(4, sourceWidth, sourceHeight); bmpContent.SetPixelData(levelData); content.Faces[0].Add(bmpContent); texDataPtr = IntPtr.Add(texDataPtr, levelSize); } }