protected virtual ExternalReference <CompiledEffectContent> OnBuildEffect(ExternalReference <EffectContent> effect, ContentProcessorContext context) { #if MONOGAME return(context.BuildAsset <EffectContent, CompiledEffectContent>(effect, typeof(EffectProcessor).Name)); #else if (string.IsNullOrEmpty(ContentHelper.GetMonoGamePlatform())) { return(context.BuildAsset <EffectContent, CompiledEffectContent>(effect, typeof(EffectProcessor).Name)); } else { return(context.BuildAsset <EffectContent, CompiledEffectContent>(effect, "MGEffectProcessor")); } #endif }
/// <summary> /// Called by the XNA Framework when importing an texture file to be used as a game asset. This /// is the method called by the XNA Framework when an asset is to be imported into an object /// that can be recognized by the Content Pipeline. /// </summary> /// <param name="filename">Name of a game asset file.</param> /// <param name="context"> /// Contains information for importing a game asset, such as a logger interface. /// </param> /// <returns>Resulting game asset.</returns> public override TextureContent Import(string filename, ContentImporterContext context) { string extension = Path.GetExtension(filename); if (extension != null) { Texture texture = null; if (extension.Equals(".DDS", StringComparison.OrdinalIgnoreCase)) { using (var stream = File.OpenRead(filename)) texture = DdsHelper.Load(stream, DdsFlags.ForceRgb | DdsFlags.ExpandLuminance); } else if (extension.Equals(".TGA", StringComparison.OrdinalIgnoreCase)) { using (var stream = File.OpenRead(filename)) texture = TgaHelper.Load(stream); } if (texture != null) { #if !MONOGAME // When using the XNA content pipeline, check for MonoGame content. if (!string.IsNullOrEmpty(ContentHelper.GetMonoGamePlatform())) #endif { // These formats are not (yet) available in MonoGame. switch (texture.Description.Format) { case DataFormat.B5G5R5A1_UNORM: // (16-bit TGA files.) case DataFormat.R8_UNORM: case DataFormat.A8_UNORM: texture = texture.ConvertTo(DataFormat.R8G8B8A8_UNORM); break; } } // Convert DigitalRune Texture to XNA TextureContent. var identity = new ContentIdentity(filename, "DigitalRune"); return(TextureHelper.ToContent(texture, identity)); } } return(base.Import(filename, context)); }
//-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- /// <summary> /// Processes a texture. /// </summary> /// <param name="input">The texture content to process.</param> /// <param name="context">Context for the specified processor.</param> /// <returns>The converted texture content.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="input"/> or <paramref name="context"/> is <see langword="null"/>. /// </exception> public override TextureContent Process(TextureContent input, ContentProcessorContext context) { if (input == null) { throw new ArgumentNullException("input"); } if (context == null) { throw new ArgumentNullException("context"); } // Linear vs. sRGB: // XNA does not support _SRGB texture formats. Texture processing is designed // for non-sRGB formats. (sRGB formats require a different order of operations! // See section "Alpha Blending" in DigitalRune KB.) try { var mipmapChain = input.Faces[0]; // Mipmap chain. var level0 = mipmapChain[0]; // Most detailed mipmap level. int width = level0.Width; int height = level0.Height; // Early out? if (!ColorKeyEnabled && (!GenerateMipmaps || (width == 1 && height == 1) || // Does not need mipmaps mipmapChain.Count > 1) && // or already has mipmaps. !PremultiplyAlpha && (!ResizeToPowerOfTwo || (MathHelper.IsPowerOf2(width) && MathHelper.IsPowerOf2(height))) && !ScaleAlphaToCoverage) { if (Format == DRTextureFormat.NoChange) { // No processing required. return(input); } SurfaceFormat surfaceFormat; if (!level0.TryGetFormat(out surfaceFormat)) { throw new InvalidContentException("Surface format is not supported.", input.Identity); } if ((Format == DRTextureFormat.Color && surfaceFormat == SurfaceFormat.Color) || (Format == DRTextureFormat.Dxt && IsDxt(surfaceFormat))) { // No processing required. return(input); } } var texture = TextureHelper.ToTexture(input); var sourceFormat = texture.Description.Format; // Apply color keying. if (ColorKeyEnabled) { // Apply color keying in RGBA 8:8:8:8. texture = texture.ConvertTo(DataFormat.R8G8B8A8_UNORM); TextureHelper.ApplyColorKey(texture, ColorKeyColor.R, ColorKeyColor.G, ColorKeyColor.B, ColorKeyColor.A); } // Normal maps require special treatment (no sRGB, etc.). bool isNormalMap = (Format == DRTextureFormat.Normal || Format == DRTextureFormat.NormalInvertY); if (isNormalMap) { InputGamma = 1.0f; OutputGamma = 1.0f; PremultiplyAlpha = false; } // Check whether alpha channel is used. bool hasAlpha = false; // true if alpha channel != 1. bool hasFractionalAlpha = false; // true if alpha channel has 0 < alpha < 1. if (!isNormalMap) { if (GenerateMipmaps || ResizeToPowerOfTwo || PremultiplyAlpha || Format == DRTextureFormat.Dxt) { try { TextureHelper.HasAlpha(texture, out hasAlpha, out hasFractionalAlpha); } catch (NotSupportedException) { // HasAlpha() does not support the current format. Convert and try again. texture = texture.ConvertTo(DataFormat.R32G32B32A32_FLOAT); TextureHelper.HasAlpha(texture, out hasAlpha, out hasFractionalAlpha); } } } // Convert to high-precision, floating-point format for processing. texture = texture.ConvertTo(DataFormat.R32G32B32A32_FLOAT); if (!isNormalMap) { // Convert texture from gamma space to linear space. TextureHelper.GammaToLinear(texture, InputGamma); } else { // Convert normal map from [0, 1] to [-1, 1]. TextureHelper.UnpackNormals(texture); } // The resize filter needs to consider alpha if the image is not already // premultiplied. PremultiplyAlpha indicates that the source image has // alpha, but is not yet premultiplied. (Premultiplication happen at the // end.) bool alphaTransparency = hasAlpha && PremultiplyAlpha; if (ResizeToPowerOfTwo || context.TargetProfile == GraphicsProfile.Reach && Format == DRTextureFormat.Dxt) { // Resize to power-of-two. int expectedWidth = RoundUpToPowerOfTwo(texture.Description.Width); int expectedHeight = RoundUpToPowerOfTwo(texture.Description.Height); if (expectedWidth != texture.Description.Width || expectedHeight != texture.Description.Height) { texture = texture.Resize(expectedWidth, expectedHeight, texture.Description.Depth, ResizeFilter.Kaiser, alphaTransparency, TextureAddressMode.Clamp); } } if (Format == DRTextureFormat.Dxt || Format == DRTextureFormat.Normal || Format == DRTextureFormat.NormalInvertY) { // Resize to multiple of four. int expectedWidth = RoundToMultipleOfFour(texture.Description.Width); int expectedHeight = RoundToMultipleOfFour(texture.Description.Height); if (expectedWidth != texture.Description.Width || expectedHeight != texture.Description.Height) { texture = texture.Resize(expectedWidth, expectedHeight, texture.Description.Depth, ResizeFilter.Kaiser, alphaTransparency, TextureAddressMode.Clamp); } } if (GenerateMipmaps && texture.Description.MipLevels <= 1) { // Generate mipmaps. texture.GenerateMipmaps(ResizeFilter.Box, alphaTransparency, TextureAddressMode.Repeat); } // For debugging: // ColorizeMipmaps(texture); if (!isNormalMap) { if (ScaleAlphaToCoverage) { TextureHelper.ScaleAlphaToCoverage(texture, ReferenceAlpha, /* data not yet premultiplied */ false); } // Convert texture from linear space to gamma space. TextureHelper.LinearToGamma(texture, OutputGamma); // Premultiply alpha. if (hasAlpha && PremultiplyAlpha) { TextureHelper.PremultiplyAlpha(texture); } } else { // Renormalize normal map and convert to DXT5nm. TextureHelper.ProcessNormals(texture, Format == DRTextureFormat.NormalInvertY); } #if !MONOGAME // No PVRTC in XNA build. string mgPlatform = ContentHelper.GetMonoGamePlatform(); if (!string.IsNullOrEmpty(mgPlatform) && mgPlatform.ToUpperInvariant() == "IOS") { Format = DRTextureFormat.Color; } #endif // Convert to from floating-point format to requested output format. switch (Format) { case DRTextureFormat.NoChange: texture = texture.ConvertTo(sourceFormat); input = TextureHelper.ToContent(texture, input.Identity); break; case DRTextureFormat.Color: texture = texture.ConvertTo(DataFormat.R8G8B8A8_UNORM); input = TextureHelper.ToContent(texture, input.Identity); break; case DRTextureFormat.Dxt: if (texture.Description.Dimension == TextureDimension.Texture3D) { texture = texture.ConvertTo(DataFormat.R8G8B8A8_UNORM); input = TextureHelper.ToContent(texture, input.Identity); } else { #if MONOGAME input = Compress(context, texture, hasAlpha, hasFractionalAlpha, PremultiplyAlpha, input.Identity); #else if (hasFractionalAlpha) { texture = texture.ConvertTo(DataFormat.BC3_UNORM); } else { texture = texture.ConvertTo(DataFormat.BC1_UNORM); } input = TextureHelper.ToContent(texture, input.Identity); #endif } break; case DRTextureFormat.Normal: case DRTextureFormat.NormalInvertY: #if MONOGAME input = Compress(context, texture, true, true, false, input.Identity); #else texture = texture.ConvertTo(DataFormat.BC3_UNORM); input = TextureHelper.ToContent(texture, input.Identity); #endif break; default: throw new NotSupportedException("The specified output format is not supported."); } } catch (Exception ex) { throw new InvalidContentException(ex.Message, input.Identity); } return(input); }