protected override void PlatformCompressTexture( ContentProcessorContext context, TextureContent content, TextureProcessorOutputFormat format, bool isSpriteFont) { format = GetTextureFormatForPlatform(format, context.TargetPlatform); // Make sure we're in a floating point format content.ConvertBitmapType(typeof(PixelBitmapContent <RgbaVector>)); switch (format) { case TextureProcessorOutputFormat.AtcCompressed: GraphicsUtil.CompressAti(content, isSpriteFont); break; case TextureProcessorOutputFormat.Color16Bit: GraphicsUtil.CompressColor16Bit(content); break; case TextureProcessorOutputFormat.DxtCompressed: GraphicsUtil.CompressDxt(context, content, isSpriteFont); break; case TextureProcessorOutputFormat.Etc1Compressed: GraphicsUtil.CompressEtc1(context, content, isSpriteFont); break; case TextureProcessorOutputFormat.PvrCompressed: GraphicsUtil.CompressPvrtc(context, content, isSpriteFont); break; } }
public static void CompressDxt(ContentProcessorContext context, TextureContent content, bool isSpriteFont) { var face = content.Faces[0][0]; if (context.TargetProfile == GraphicsProfile.Reach) { if (!IsPowerOfTwo(face.Width) || !IsPowerOfTwo(face.Height)) { throw new PipelineException( "DXT compression requires width and height must " + "be powers of two in Reach graphics profile."); } } // Test the alpha channel to figure out if we have alpha. var alphaRange = CalculateAlphaRange(face); // TODO: This isn't quite right. // // We should be generating DXT1 textures for cutout alpha // as DXT1 supports 1bit alpha and it uses less memory. // // XNA never generated DXT3 for textures... it always picked // between DXT1 for cutouts and DXT5 for fractional alpha. // // DXT3 however can produce better results for high frequency // alpha like a chain link fence where is DXT5 is better for // low frequency alpha like clouds. I don't know how we can // pick the right thing in this case without a hint. if (isSpriteFont) { CompressFontDXT3(content); } else if (alphaRange == AlphaRange.Opaque) { content.ConvertBitmapType(typeof(Dxt1BitmapContent)); } else if (alphaRange == AlphaRange.Cutout) { content.ConvertBitmapType(typeof(Dxt3BitmapContent)); } else { content.ConvertBitmapType(typeof(Dxt5BitmapContent)); } }
public static void CompressColor16Bit(TextureContent content) { var face = content.Faces[0][0]; var alphaRange = CalculateAlphaRange(face); if (alphaRange == AlphaRange.Opaque) { content.ConvertBitmapType(typeof(PixelBitmapContent <Bgr565>)); } else if (alphaRange == AlphaRange.Cutout) { content.ConvertBitmapType(typeof(PixelBitmapContent <Bgra5551>)); } else { content.ConvertBitmapType(typeof(PixelBitmapContent <Bgra4444>)); } }
public static void CompressAti(TextureContent content, bool isSpriteFont) { // If sharp alpha is required (for a font texture page), use 16-bit color instead of PVR if (isSpriteFont) { CompressColor16Bit(content); return; } var face = content.Faces[0][0]; var alphaRange = CalculateAlphaRange(face); if (alphaRange == AlphaRange.Full) { content.ConvertBitmapType(typeof(AtcExplicitBitmapContent)); } else { content.ConvertBitmapType(typeof(AtcInterpolatedBitmapContent)); } }
public static void CompressEtc1(ContentProcessorContext context, TextureContent content, bool isSpriteFont) { // If sharp alpha is required (for a font texture page), use 16-bit color instead of PVR if (isSpriteFont) { CompressColor16Bit(content); return; } var face = content.Faces[0][0]; var alphaRange = CalculateAlphaRange(face); // Use BGRA4444 for textures with non-opaque alpha values if (alphaRange != AlphaRange.Opaque) { content.ConvertBitmapType(typeof(PixelBitmapContent <Bgra4444>)); } else { // PVR SGX does not handle non-POT ETC1 textures. // https://code.google.com/p/libgdx/issues/detail?id=1310 // Since we already enforce POT for PVR and DXT in Reach, we will also enforce POT for ETC1 if (!IsPowerOfTwo(face.Width) || !IsPowerOfTwo(face.Height)) { context.Logger.LogWarning( null, content.Identity, "ETC1 compression requires width and height to be powers of two due to " + "hardware restrictions on some devices. Falling back to BGR565."); content.ConvertBitmapType(typeof(PixelBitmapContent <Bgr565>)); } else { content.ConvertBitmapType(typeof(Etc1BitmapContent)); } } }
public static void CompressPvrtc(ContentProcessorContext context, TextureContent content, bool isSpriteFont) { // If sharp alpha is required (for a font texture page), use 16-bit color instead of PVR if (isSpriteFont) { CompressColor16Bit(content); return; } // Calculate number of mip levels int width = content.Faces[0][0].Height; int height = content.Faces[0][0].Width; if (IsPowerOfTwo(width) && IsPowerOfTwo(height) && width == height) { var face = content.Faces[0][0]; var alphaRange = CalculateAlphaRange(face); if (alphaRange == AlphaRange.Opaque) { content.ConvertBitmapType(typeof(PvrtcRgb4BitmapContent)); } else { content.ConvertBitmapType(typeof(PvrtcRgba4BitmapContent)); } } else { context.Logger.LogWarning( null, content.Identity, "PVR compression requires width and height to " + "be powers of two and equal. Falling back to 16-bit color."); CompressColor16Bit(content); } }
/// <summary> /// Performs conversion of the texture content to the correct format. /// </summary> /// <param name="context">The processor context.</param> /// <param name="content">The content to be compressed.</param> /// <param name="format">The user requested format for compression.</param> /// <param name="isSpriteFont">If the texture has represents a sprite font, i.e. is greyscale and has sharp black/white contrast.</param> public void ConvertTexture( ContentProcessorContext context, TextureContent content, TextureProcessorOutputFormat format, bool isSpriteFont) { // We do nothing in this case. if (format == TextureProcessorOutputFormat.NoChange) { return; } // If this is color just make sure the format is right and return it. if (format == TextureProcessorOutputFormat.Color) { content.ConvertBitmapType(typeof(PixelBitmapContent <Color>)); return; } // Handle this common compression format. if (format == TextureProcessorOutputFormat.Color16Bit) { GraphicsUtil.CompressColor16Bit(content); return; } try { // All other formats require platform specific choices. PlatformCompressTexture(context, content, format, isSpriteFont); } catch (EntryPointNotFoundException ex) { context.Logger.LogImportantMessage("Could not find the entry point to compress the texture. " + ex.ToString()); throw; } catch (DllNotFoundException ex) { context.Logger.LogImportantMessage("Could not compress texture. Required shared lib is missing. " + ex.ToString()); throw; } catch (Exception ex) { context.Logger.LogImportantMessage("Could not convert texture. " + ex.ToString()); throw; } }