public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { var output = new SpriteFontContent(); // extract the glyphs from the texture and map them to a list of characters. // we need to call GtCharacterForIndex for each glyph in the Texture to // get the char for that glyph, by default we start at ' ' then '!' and then ASCII // after that. if (input._bitmap == null) { throw new ArgumentNullException("Texture Bitmap cannot be null"); } int linespacing = 0; var glyphs = ExtractGlyphs(input._bitmap, out linespacing); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } var outputBitmap = GlyphPacker.ArrangeGlyphs(glyphs.ToArray(), true, true); //outputBitmap.Save ("fontglyphs.png"); foreach (Glyph glyph in glyphs) { glyph.XAdvance += linespacing; if (!output.CharacterMap.Contains(glyph.Character)) { output.CharacterMap.Add(glyph.Character); } output.Glyphs.Add(new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Cropping.Add(new Rectangle(0, 0, glyph.Subrect.Width, glyph.Subrect.Height)); ABCFloat abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } output.Texture._bitmap = outputBitmap; var bitmapContent = new PixelBitmapContent <Color> (outputBitmap.Width, outputBitmap.Height); bitmapContent.SetPixelData(outputBitmap.GetData()); output.Texture.Faces.Add(new MipmapChain(bitmapContent)); GraphicsUtil.CompressTexture(output.Texture, context, false, false); return(output); }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { var output = new SpriteFontContent(); // extract the glyphs from the texture and map them to a list of characters. // we need to call GtCharacterForIndex for each glyph in the Texture to // get the char for that glyph, by default we start at ' ' then '!' and then ASCII // after that. var systemBitmap = input.Faces[0][0].ToSystemBitmap(); int linespacing = 0; var glyphs = ExtractGlyphs(systemBitmap, out linespacing); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } systemBitmap.Dispose(); systemBitmap = GlyphPacker.ArrangeGlyphs(glyphs.ToArray(), true, true); foreach (Glyph glyph in glyphs) { glyph.XAdvance += linespacing; if (!output.CharacterMap.Contains(glyph.Character)) { output.CharacterMap.Add(glyph.Character); } output.Glyphs.Add(new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Cropping.Add(new Rectangle(0, 0, glyph.Subrect.Width, glyph.Subrect.Height)); ABCFloat abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } output.Texture.Faces.Add(new MipmapChain(systemBitmap.ToXnaBitmap(true))); systemBitmap.Dispose(); GraphicsUtil.CompressTexture(context.TargetProfile, output.Texture, context, false, false, false); return(output); }
public override TextureContent Process(TextureContent input, ContentProcessorContext context) { var bmp = input.Faces[0][0]; if (ColorKeyEnabled) { var data = bmp.GetPixelData(); var idx = 0; for (; idx < data.Length;) { var r = data[idx + 0]; var g = data[idx + 1]; var b = data[idx + 2]; var a = data[idx + 3]; var col = new Color(r, g, b, a); if (col.Equals(ColorKeyColor)) { data[idx + 0] = 0; data[idx + 1] = 0; data[idx + 2] = 0; data[idx + 3] = 0; } idx += 4; } bmp.SetPixelData(data); } if (ResizeToPowerOfTwo) { if (!GraphicsUtil.IsPowerOfTwo(bmp.Width) || !GraphicsUtil.IsPowerOfTwo(bmp.Height)) { input.Resize(GraphicsUtil.GetNextPowerOfTwo(bmp.Width), GraphicsUtil.GetNextPowerOfTwo(bmp.Height)); bmp = input.Faces[0][0]; } } if (PremultiplyAlpha) { var data = bmp.GetPixelData(); var idx = 0; for (; idx < data.Length;) { var r = data[idx + 0]; var g = data[idx + 1]; var b = data[idx + 2]; var a = data[idx + 3]; var col = Color.FromNonPremultiplied(r, g, b, a); data[idx + 0] = col.R; data[idx + 1] = col.G; data[idx + 2] = col.B; data[idx + 3] = col.A; idx += 4; } bmp.SetPixelData(data); } if (TextureFormat == TextureProcessorOutputFormat.NoChange) { return(input); } try { if (TextureFormat == TextureProcessorOutputFormat.DxtCompressed || TextureFormat == TextureProcessorOutputFormat.Compressed) { GraphicsUtil.CompressTexture(context.TargetProfile, input, context, GenerateMipmaps, PremultiplyAlpha, false); } } catch (EntryPointNotFoundException ex) { context.Logger.LogImportantMessage("Could not find the entry point to compress the texture", ex.ToString()); TextureFormat = TextureProcessorOutputFormat.Color; } catch (DllNotFoundException ex) { context.Logger.LogImportantMessage("Could not compress texture. Required shared lib is missing. {0}", ex.ToString()); TextureFormat = TextureProcessorOutputFormat.Color; } catch (Exception ex) { context.Logger.LogImportantMessage("Could not compress texture {0}", ex.ToString()); TextureFormat = TextureProcessorOutputFormat.Color; } if (GenerateMipmaps) { context.Logger.LogMessage("Generating mipmaps."); input.GenerateMipmaps(false); } return(input); }
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context) { var output = new SpriteFontContent(input); var estimatedSurfaceArea = 0; var largestHeight = 0; var widthsAndHeights = new List <Point>(); var fontName = input.FontName; var directory = Path.GetDirectoryName(input.Identity.SourceFilename); if (File.Exists(Path.Combine(directory, fontName + ".ttf"))) { fontName += ".ttf"; } if (File.Exists(Path.Combine(directory, fontName + ".ttc"))) { fontName += ".ttc"; } if (File.Exists(Path.Combine(directory, fontName + ".otf"))) { fontName += ".otf"; } fontName = Path.Combine(directory, fontName); context.Logger.LogMessage("Building Font {0}", fontName); try { Library lib = new Library(); Face face = lib.NewFace(fontName, 0); face.SetCharSize(0, (int)input.Size * 64, 0, 96); if (face.FamilyName == "Microsoft Sans Serif" && input.FontName != "Microsoft Sans Serif") { throw new PipelineException(string.Format("Font {0} is not installed on this computer.", input.FontName)); } foreach (var ch in input.Characters) { uint glyphIndex = face.GetCharIndex(ch); face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal); var width = (int)face.Glyph.Advance.X >> 6; var height = (int)face.Glyph.Metrics.Height >> 6; estimatedSurfaceArea += width; largestHeight = Math.Max(largestHeight, height); widthsAndHeights.Add(new Point(width, height)); } estimatedSurfaceArea *= largestHeight; output.VerticalLineSpacing = largestHeight; // calculate the best height and width for our output texture. // TODO: GetMonoGamePlatform() var texBounds = calculateOutputTextureBounds(estimatedSurfaceArea, true); // Create our texture var outputBitmap = new Bitmap(texBounds.X, texBounds.Y); using (var g = System.Drawing.Graphics.FromImage(outputBitmap)) { g.FillRectangle(Brushes.Transparent, new System.Drawing.Rectangle(0, 0, outputBitmap.Width, outputBitmap.Height)); } int x = 0; int y = 0; // Draw each glyph into the image. for (int i = 0; i < input.Characters.Count; i++) { char c = input.Characters[i]; uint glyphIndex = face.GetCharIndex(c); face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal); face.Glyph.RenderGlyph(RenderMode.Normal); var A = face.Glyph.Metrics.HorizontalBearingX >> 6; var B = face.Glyph.Metrics.Width >> 6; var C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (A + B); int charWidth = (int)(Math.Abs(A) + B + C); if (!input.UseKerning) { charWidth = (int)B; } if (x + charWidth >= outputBitmap.Width) { x = 0; y += largestHeight; } var rect = new Microsoft.Xna.Framework.Rectangle(x, y, charWidth, widthsAndHeights[i].Y); output.Glyphs.Add(rect); // Characters with a negative a kerning value (like j) need to be adjusted, // so (in the case of j) the bottom curve doesn't render outside our source // rect. var renderPoint = new PointF(x, y); if (A < 0) { renderPoint.X += Math.Abs(A); } if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0) { BitmapData data = outputBitmap.LockBits(new System.Drawing.Rectangle((int)renderPoint.X, (int)renderPoint.Y, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte[] pixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows]; Marshal.Copy(face.Glyph.Bitmap.Buffer, pixelAlphas, 0, pixelAlphas.Length); for (int j = 0; j < pixelAlphas.Length; j++) { int pixelOffset = (j / data.Width) * data.Stride + (j % data.Width * 4); Marshal.WriteByte(data.Scan0, pixelOffset + 3, pixelAlphas[j]); } outputBitmap.UnlockBits(data); } output.Cropping.Add(new Microsoft.Xna.Framework.Rectangle(0, (face.Glyph.Metrics.VerticalAdvance >> 6) - face.Glyph.BitmapTop, charWidth, widthsAndHeights[i].Y)); if (!input.UseKerning) { A = 0; C = 0; } output.Kerning.Add(new Vector3(A, B, C)); // Add a 2 pixel spacing between characters x += charWidth + 2; } // Drawing against a transparent black background blends // the 'alpha' pixels against black, leaving a black outline. // Interpolate between black and white // based on it's intensity to covert this 'outline' to // it's grayscale equivalent. var transBlack = Color.Transparent; for (var i = 0; i < outputBitmap.Width; i++) { for (var j = 0; j < outputBitmap.Height; j++) { var px = outputBitmap.GetPixel(i, j); if (px.ColorsEqual(transBlack)) { continue; } var val = px.A / (255.0f); var col = Color.Lerp(Color.Transparent, Color.White, val); px = System.Drawing.Color.FromArgb(px.A, col.R, col.G, col.B); outputBitmap.SetPixel(i, j, px); } } outputBitmap.Save("test.png"); output.Texture._bitmap = outputBitmap; var bitmapContent = new PixelBitmapContent <Color>(texBounds.X, texBounds.Y); bitmapContent.SetPixelData(outputBitmap.GetData()); output.Texture.Faces.Add(new MipmapChain(bitmapContent)); GraphicsUtil.CompressTexture(output.Texture, context, false, false); } catch (Exception ex) { context.Logger.LogImportantMessage("{0}", ex.ToString()); } return(output); }
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context) { var output = new SpriteFontContent(input); var fontName = input.FontName; #if WINDOWS var windowsfolder = Environment.GetFolderPath(Environment.SpecialFolder.Windows); var fontDirectory = Path.Combine(windowsfolder, "Fonts"); fontName = FindFontFileFromFontName(fontName, fontDirectory); if (string.IsNullOrWhiteSpace(fontName)) { fontName = input.FontName; #endif var directory = Path.GetDirectoryName(input.Identity.SourceFilename); var directories = new string[] { directory, "/Library/Fonts", #if WINDOWS fontDirectory, #endif } ; foreach (var dir in directories) { if (File.Exists(Path.Combine(dir, fontName + ".ttf"))) { fontName += ".ttf"; directory = dir; break; } if (File.Exists(Path.Combine(dir, fontName + ".ttc"))) { fontName += ".ttc"; directory = dir; break; } if (File.Exists(Path.Combine(dir, fontName + ".otf"))) { fontName += ".otf"; directory = dir; break; } } fontName = Path.Combine(directory, fontName); #if WINDOWS } #endif context.Logger.LogMessage("Building Font {0}", fontName); try { if (!File.Exists(fontName)) { throw new Exception(string.Format("Could not load {0}", fontName)); } var lineSpacing = 0f; var glyphs = ImportFont(input, out lineSpacing, context, fontName); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } Bitmap outputBitmap = GlyphPacker.ArrangeGlyphs(glyphs, true, true); //outputBitmap.Save ("/Users/Jimmy/Desktop/Cocos2D-XNAImages/fontglyphs.png"); // Adjust line and character spacing. lineSpacing += input.Spacing; foreach (Glyph glyph in glyphs) { glyph.XAdvance += input.Spacing; if (!output.CharacterMap.Contains(glyph.Character)) { output.CharacterMap.Add(glyph.Character); } output.Glyphs.Add(new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Cropping.Add(new Rectangle(0, (int)(glyph.YOffset + glyphs.Select(x => x.YOffset).Max()), glyph.Subrect.Width, glyph.Subrect.Height)); ABCFloat abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } // outputBitmap.Save("/Users/Jimmy/Desktop/Cocos2D-XNAImages/test.png"); output.Texture._bitmap = outputBitmap; var bitmapContent = new PixelBitmapContent <Color>(outputBitmap.Width, outputBitmap.Height); bitmapContent.SetPixelData(outputBitmap.GetData()); output.Texture.Faces.Add(new MipmapChain(bitmapContent)); GraphicsUtil.CompressTexture(output.Texture, context, false, false); } catch (Exception ex) { context.Logger.LogImportantMessage("{0}", ex.ToString()); } return(output); }
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context) { var output = new SpriteFontContent(input); var fontName = input.FontName; #if WINDOWS || LINUX #if WINDOWS var windowsfolder = Environment.GetFolderPath(Environment.SpecialFolder.Windows); var fontDirectory = Path.Combine(windowsfolder, "Fonts"); fontName = FindFontFileFromFontName(fontName, fontDirectory); #elif LINUX fontName = FindFontFileFromFontName(fontName, input.Style.ToString()); #endif if (string.IsNullOrWhiteSpace(fontName)) { fontName = input.FontName; #endif var directory = Path.GetDirectoryName(input.Identity.SourceFilename); List <string> directories = new List <string>(); directories.Add(directory); directories.Add("/Library/Fonts"); #if WINDOWS directories.Add(fontDirectory); #endif foreach (var dir in directories) { if (File.Exists(Path.Combine(dir, fontName + ".ttf"))) { fontName += ".ttf"; directory = dir; break; } if (File.Exists(Path.Combine(dir, fontName + ".ttc"))) { fontName += ".ttc"; directory = dir; break; } if (File.Exists(Path.Combine(dir, fontName + ".otf"))) { fontName += ".otf"; directory = dir; break; } } fontName = Path.Combine(directory, fontName); #if WINDOWS || LINUX } #endif context.Logger.LogMessage("Building Font {0}", fontName); try { if (!File.Exists(fontName)) { throw new Exception(string.Format("Could not load {0}", fontName)); } var lineSpacing = 0f; int yOffsetMin = 0; var glyphs = ImportFont(input, out lineSpacing, out yOffsetMin, context, fontName); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } var compressed = TextureFormat == TextureProcessorOutputFormat.DxtCompressed || TextureFormat == TextureProcessorOutputFormat.Compressed; var systemBitmap = GlyphPacker.ArrangeGlyphs(glyphs, compressed, compressed); //systemBitmap.Save ("fontglyphs.png"); // Adjust line and character spacing. lineSpacing += input.Spacing; output.VerticalLineSpacing = (int)lineSpacing; foreach (var glyph in glyphs) { output.CharacterMap.Add(glyph.Character); var texRect = new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height); output.Glyphs.Add(texRect); var cropping = new Rectangle(0, (int)(glyph.YOffset - yOffsetMin), (int)glyph.XAdvance, output.VerticalLineSpacing); output.Cropping.Add(cropping); // Set the optional character kerning. if (input.UseKerning) { output.Kerning.Add(new Vector3(glyph.CharacterWidths.A, glyph.CharacterWidths.B, glyph.CharacterWidths.C)); } else { output.Kerning.Add(new Vector3(0, texRect.Width, 0)); } } output.Texture.Faces[0].Add(systemBitmap.ToXnaBitmap(true)); systemBitmap.Dispose(); if (compressed) { GraphicsUtil.CompressTexture(context.TargetProfile, output.Texture, context, false, true, true); } } catch (Exception ex) { context.Logger.LogImportantMessage("{0}", ex.ToString()); } return(output); }
public override TextureContent Process(TextureContent input, ContentProcessorContext context) { if (ColorKeyEnabled) { var replaceColor = System.Drawing.Color.FromArgb(0); for (var x = 0; x < input._bitmap.Width; x++) { for (var y = 0; y < input._bitmap.Height; y++) { var col = input._bitmap.GetPixel(x, y); if (col.ColorsEqual(ColorKeyColor)) { input._bitmap.SetPixel(x, y, replaceColor); } } } } var face = input.Faces[0][0]; if (ResizeToPowerOfTwo) { if (!GraphicsUtil.IsPowerOfTwo(face.Width) || !GraphicsUtil.IsPowerOfTwo(face.Height)) { input.Resize(GraphicsUtil.GetNextPowerOfTwo(face.Width), GraphicsUtil.GetNextPowerOfTwo(face.Height)); } } if (PremultiplyAlpha) { for (var x = 0; x < input._bitmap.Width; x++) { for (var y = 0; y < input._bitmap.Height; y++) { var oldCol = input._bitmap.GetPixel(x, y); var preMultipliedColor = Color.FromNonPremultiplied(oldCol.R, oldCol.G, oldCol.B, oldCol.A); input._bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(preMultipliedColor.A, preMultipliedColor.R, preMultipliedColor.G, preMultipliedColor.B)); } } } // Set the first layer input.Faces[0][0].SetPixelData(input._bitmap.GetData()); if (TextureFormat == TextureProcessorOutputFormat.NoChange) { return(input); } try { if (TextureFormat == TextureProcessorOutputFormat.DXTCompressed || TextureFormat == TextureProcessorOutputFormat.Compressed) { context.Logger.LogMessage("Compressing using {0}", TextureFormat); } GraphicsUtil.CompressTexture(input, context, GenerateMipmaps, PremultiplyAlpha); context.Logger.LogMessage("Compression {0} Suceeded", TextureFormat); } catch (EntryPointNotFoundException ex) { context.Logger.LogImportantMessage("Could not find the entry point to compress the texture", ex.ToString()); TextureFormat = TextureProcessorOutputFormat.Color; } catch (DllNotFoundException ex) { context.Logger.LogImportantMessage("Could not compress texture. Required shared lib is missing. {0}", ex.ToString()); TextureFormat = TextureProcessorOutputFormat.Color; } catch (Exception ex) { context.Logger.LogImportantMessage("Could not compress texture {0}", ex.ToString()); TextureFormat = TextureProcessorOutputFormat.Color; } return(input); }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { var output = new SpriteFontContent(); // extract the glyphs from the texture and map them to a list of characters. // we need to call GtCharacterForIndex for each glyph in the Texture to // get the char for that glyph, by default we start at ' ' then '!' and then ASCII // after that. BitmapContent face = input.Faces[0][0]; SurfaceFormat faceFormat; face.TryGetFormat(out faceFormat); if (faceFormat != SurfaceFormat.Color) { var colorFace = new PixelBitmapContent <Color>(face.Width, face.Height); BitmapContent.Copy(face, colorFace); face = colorFace; } var glyphs = ExtractGlyphs((PixelBitmapContent <Color>)face); // Optimize. foreach (var glyph in glyphs) { GlyphCropper.Crop(glyph); output.VerticalLineSpacing = Math.Max(output.VerticalLineSpacing, glyph.Subrect.Height); } var format = GraphicsUtil.GetTextureFormatForPlatform(TextureFormat, context.TargetPlatform); var requiresPOT = GraphicsUtil.RequiresPowerOfTwo(format, context.TargetPlatform, context.TargetProfile); var requiresSquare = GraphicsUtil.RequiresSquare(format, context.TargetPlatform); face = GlyphPacker.ArrangeGlyphs(glyphs.ToArray(), requiresPOT, requiresSquare); foreach (var glyph in glyphs) { output.CharacterMap.Add(glyph.Character); output.Glyphs.Add(new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Cropping.Add(new Rectangle((int)glyph.XOffset, (int)glyph.YOffset, glyph.Width, glyph.Height)); var abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } output.Texture.Faces[0].Add(face); var bmp = output.Texture.Faces[0][0]; if (PremultiplyAlpha) { var data = bmp.GetPixelData(); var idx = 0; for (; idx < data.Length;) { var r = data[idx + 0]; var g = data[idx + 1]; var b = data[idx + 2]; var a = data[idx + 3]; var col = Color.FromNonPremultiplied(r, g, b, a); data[idx + 0] = col.R; data[idx + 1] = col.G; data[idx + 2] = col.B; data[idx + 3] = col.A; idx += 4; } bmp.SetPixelData(data); } if (GraphicsUtil.IsCompressedTextureFormat(format)) { try { GraphicsUtil.CompressTexture(context.TargetProfile, output.Texture, format, context, false, true); } catch (Exception ex) { context.Logger.LogImportantMessage("{0}", ex.ToString()); } } return(output); }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { var output = new SpriteFontContent(); // extract the glyphs from the texture and map them to a list of characters. // we need to call GtCharacterForIndex for each glyph in the Texture to // get the char for that glyph, by default we start at ' ' then '!' and then ASCII // after that. var systemBitmap = input.Faces[0][0].ToSystemBitmap(); var glyphs = ExtractGlyphs(systemBitmap); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); output.VerticalLineSpacing = Math.Max(output.VerticalLineSpacing, glyph.Subrect.Height); } systemBitmap.Dispose(); var compressed = TextureFormat == TextureProcessorOutputFormat.DxtCompressed || TextureFormat == TextureProcessorOutputFormat.Compressed; systemBitmap = GlyphPacker.ArrangeGlyphs(glyphs.ToArray(), compressed, compressed); foreach (Glyph glyph in glyphs) { output.CharacterMap.Add(glyph.Character); output.Glyphs.Add(new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Cropping.Add(new Rectangle((int)glyph.XOffset, (int)glyph.YOffset, glyph.Subrect.Width, glyph.Subrect.Height)); ABCFloat abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } output.Texture.Faces[0].Add(systemBitmap.ToXnaBitmap(false)); systemBitmap.Dispose(); var bmp = output.Texture.Faces[0][0]; if (PremultiplyAlpha) { var data = bmp.GetPixelData(); var idx = 0; for (; idx < data.Length;) { var r = data[idx + 0]; var g = data[idx + 1]; var b = data[idx + 2]; var a = data[idx + 3]; var col = Color.FromNonPremultiplied(r, g, b, a); data[idx + 0] = col.R; data[idx + 1] = col.G; data[idx + 2] = col.B; data[idx + 3] = col.A; idx += 4; } bmp.SetPixelData(data); } if (compressed) { GraphicsUtil.CompressTexture(context.TargetProfile, output.Texture, context, false, PremultiplyAlpha, true); } return(output); }
public override TextureContent Process(TextureContent input, ContentProcessorContext context) { SurfaceFormat format; if (input.Faces[0][0].TryGetFormat(out format)) { // If it is already a compressed format, we cannot do anything else so just return it if (format.IsCompressedFormat()) { return(input); } } if (ColorKeyEnabled || ResizeToPowerOfTwo || MakeSquare || PremultiplyAlpha) { // Convert to floating point format for modifications. Keep the original format for conversion back later on if required. var originalType = input.Faces[0][0].GetType(); try { input.ConvertBitmapType(typeof(PixelBitmapContent <Vector4>)); } catch (Exception ex) { context.Logger.LogImportantMessage("Could not convert input texture for processing. " + ex.ToString()); throw ex; } for (int f = 0; f < input.Faces.Count; ++f) { var face = input.Faces[f]; for (int m = 0; m < face.Count; ++m) { var bmp = (PixelBitmapContent <Vector4>)face[m]; if (ColorKeyEnabled) { bmp.ReplaceColor(ColorKeyColor.ToVector4(), Vector4.Zero); } if (ResizeToPowerOfTwo) { if (!GraphicsUtil.IsPowerOfTwo(bmp.Width) || !GraphicsUtil.IsPowerOfTwo(bmp.Height) || (MakeSquare && bmp.Height != bmp.Width)) { var newWidth = GraphicsUtil.GetNextPowerOfTwo(bmp.Width); var newHeight = GraphicsUtil.GetNextPowerOfTwo(bmp.Height); if (MakeSquare) { newWidth = newHeight = Math.Max(newWidth, newHeight); } var resized = new PixelBitmapContent <Vector4>(newWidth, newHeight); BitmapContent.Copy(bmp, resized); bmp = resized; } } else if (MakeSquare && bmp.Height != bmp.Width) { var newSize = Math.Max(bmp.Width, bmp.Height); var resized = new PixelBitmapContent <Vector4>(newSize, newSize); BitmapContent.Copy(bmp, resized); } if (PremultiplyAlpha) { for (int y = 0; y < bmp.Height; ++y) { var row = bmp.GetRow(y); for (int x = 0; x < bmp.Width; ++x) { row[x] = Color.FromNonPremultiplied(row[x]).ToVector4(); } } } face[m] = bmp; } } // If no change to the surface format was desired, change it back now before it early outs if (TextureFormat == TextureProcessorOutputFormat.NoChange) { input.ConvertBitmapType(originalType); } } if (TextureFormat == TextureProcessorOutputFormat.NoChange) { return(input); } try { if (TextureFormat != TextureProcessorOutputFormat.Color) { input.ConvertBitmapType(typeof(PixelBitmapContent <Vector4>)); GraphicsUtil.CompressTexture(context.TargetProfile, input, TextureFormat, context, GenerateMipmaps, false); } else { input.ConvertBitmapType(typeof(PixelBitmapContent <Color>)); if (GenerateMipmaps) { input.GenerateMipmaps(false); } } } catch (EntryPointNotFoundException ex) { context.Logger.LogImportantMessage("Could not find the entry point to compress the texture. " + ex.ToString()); throw ex; } catch (DllNotFoundException ex) { context.Logger.LogImportantMessage("Could not compress texture. Required shared lib is missing. " + ex.ToString()); throw ex; } catch (Exception ex) { context.Logger.LogImportantMessage("Could not convert texture. " + ex.ToString()); throw ex; } return(input); }
public override TextureContent Process(TextureContent input, ContentProcessorContext context) { if (ColorKeyEnabled) { var replaceColor = System.Drawing.Color.FromArgb(0); for (var x = 0; x < input._bitmap.Width; x++) { for (var y = 0; y < input._bitmap.Height; y++) { var col = input._bitmap.GetPixel(x, y); if (col.ColorsEqual(ColorKeyColor)) { input._bitmap.SetPixel(x, y, replaceColor); } } } } var face = input.Faces[0][0]; if (ResizeToPowerOfTwo) { if (!GraphicsUtil.IsPowerOfTwo(face.Width) || !GraphicsUtil.IsPowerOfTwo(face.Height)) { input.Resize(GraphicsUtil.GetNextPowerOfTwo(face.Width), GraphicsUtil.GetNextPowerOfTwo(face.Height)); } } if (PremultiplyAlpha) { for (var x = 0; x < input._bitmap.Width; x++) { for (var y = 0; y < input._bitmap.Height; y++) { var oldCol = input._bitmap.GetPixel(x, y); var preMultipliedColor = Color.FromNonPremultiplied(oldCol.R, oldCol.G, oldCol.B, oldCol.A); input._bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(preMultipliedColor.A, preMultipliedColor.R, preMultipliedColor.G, preMultipliedColor.B)); } } } if (GenerateMipmaps) { throw new NotImplementedException(); } // TODO: Set all mip level data input.Faces[0][0].SetPixelData(input._bitmap.GetData()); if (TextureFormat == TextureProcessorOutputFormat.NoChange) { return(input); } if (TextureFormat == TextureProcessorOutputFormat.DXTCompressed || TextureFormat == TextureProcessorOutputFormat.Compressed) { GraphicsUtil.CompressTexture(input, context.TargetPlatform, PremultiplyAlpha); } return(input); }