public void Texture2DContent() { var content = new Texture2DContent(); Assert.NotNull(content.Faces); Assert.AreEqual(1, content.Faces.Count); Assert.NotNull(content.Faces[0]); Assert.AreEqual(0, content.Faces[0].Count); Assert.NotNull(content.Mipmaps); Assert.AreEqual(content.Faces[0], content.Mipmaps); Assert.AreEqual(0, content.Mipmaps.Count); content.Faces[0] = new MipmapChain(new PixelBitmapContent<Color>(2,2)); Assert.AreEqual(content.Faces[0], content.Mipmaps); Assert.AreEqual(1, content.Faces[0].Count); Assert.AreEqual(1, content.Mipmaps.Count); content.Faces[0].Add(new PixelBitmapContent<Color>(1, 1)); Assert.AreEqual(2, content.Faces[0].Count); Assert.AreEqual(2, content.Mipmaps.Count); Assert.Throws<NotSupportedException>(() => content.Faces.Clear()); Assert.Throws<NotSupportedException>(() => content.Faces.RemoveAt(0)); Assert.Throws<NotSupportedException>(() => content.Faces.Add(new MipmapChain())); Assert.Throws<NotSupportedException>(() => content.Faces.Insert(0, new MipmapChain())); Assert.Throws<NotSupportedException>(() => content.Faces.Remove(content.Faces[0])); }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { if(context.TargetPlatform == TargetPlatform.Windows) CreateExEnOutput(input, context); return base.Process(input, context); }
public void ColorKey() { var context = new TestProcessorContext(TargetPlatform.Windows, "dummy.xnb"); var processor = new TextureProcessor { ColorKeyColor = Color.Red, ColorKeyEnabled = true, GenerateMipmaps = false, PremultiplyAlpha = false, ResizeToPowerOfTwo = false, TextureFormat = TextureProcessorOutputFormat.Color }; var face = new PixelBitmapContent<Color>(8, 8); Fill(face, Color.Red); var input = new Texture2DContent(); input.Faces[0] = face; var output = processor.Process(input, context); Assert.NotNull(output); Assert.AreEqual(1, output.Faces.Count); Assert.AreEqual(1, output.Faces[0].Count); Assert.IsAssignableFrom<PixelBitmapContent<Color>>(output.Faces[0][0]); var outFace = (PixelBitmapContent<Color>)output.Faces[0][0]; Assert.AreEqual(8, outFace.Width); Assert.AreEqual(8, outFace.Height); for (var y=0; y < outFace.Height; y++) for (var x = 0; x < outFace.Width; x++) Assert.AreEqual(Color.Transparent, outFace.GetPixel(x, y)); }
/// <summary> /// Converts a DigitalRune <see cref="Texture"/> to an XNA <see cref="TextureContent"/>. /// </summary> /// <param name="texture">The <see cref="Texture"/>.</param> /// <param name="identity">The content identity.</param> /// <returns>The <see cref="TextureContent"/>.</returns> public static TextureContent ToContent(Texture texture, ContentIdentity identity) { var description = texture.Description; switch (description.Dimension) { case TextureDimension.Texture1D: case TextureDimension.Texture2D: { var textureContent = new Texture2DContent { Identity = identity }; for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++) { var image = texture.Images[texture.GetImageIndex(mipIndex, 0, 0)]; textureContent.Mipmaps.Add(ToContent(image)); } return textureContent; } case TextureDimension.TextureCube: { var textureContent = new TextureCubeContent { Identity = identity }; for (int faceIndex = 0; faceIndex < 6; faceIndex++) { for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++) { var image = texture.Images[texture.GetImageIndex(mipIndex, faceIndex, 0)]; textureContent.Faces[faceIndex].Add(ToContent(image)); } } return textureContent; } case TextureDimension.Texture3D: { var textureContent = new Texture3DContent { Identity = identity }; for (int zIndex = 0; zIndex < description.Depth; zIndex++) { textureContent.Faces.Add(new MipmapChain()); for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++) { var image = texture.Images[texture.GetImageIndex(mipIndex, 0, zIndex)]; textureContent.Faces[zIndex].Add(ToContent(image)); } } return textureContent; } } throw new InvalidOperationException("Invalid texture dimension."); }
public void Mipmap() { var context = new TestProcessorContext(TargetPlatform.Windows, "dummy.xnb"); var processor = new TextureProcessor { ColorKeyEnabled = false, GenerateMipmaps = true, PremultiplyAlpha = false, ResizeToPowerOfTwo = false, TextureFormat = TextureProcessorOutputFormat.Color }; var face = new PixelBitmapContent<Color>(8, 8); Fill(face, Color.Red); var input = new Texture2DContent(); input.Faces[0] = face; var output = processor.Process(input, context); Assert.NotNull(output); Assert.AreEqual(1, output.Faces.Count); //Assert.AreNotEqual(face, output.Faces[0][0]); var outChain = output.Faces[0]; Assert.AreEqual(4, outChain.Count); var width = 8; var height = 8; foreach (var outFace in outChain) { Assert.AreEqual(width, outFace.Width); Assert.AreEqual(height, outFace.Height); var bitmap = (PixelBitmapContent<Color>)outFace; for (var y = 0; y < height; y++) for (var x = 0; x < width; x++) Assert.AreEqual(Color.Red, bitmap.GetPixel(x, y)); width = width >> 1; height = height >> 1; } }
public SpriteFontContent( Texture2DContent texture, List<Rectangle> glyphs, List<char> characterMap, List<Rectangle> cropping, int verticalSpacing, float horizontalSpacing, List<Vector3> kerning, char? defaultCharacter) { this.Texture = texture; this.Glyphs = glyphs; this.CharacterMap = characterMap; this.Cropping = cropping; this.VerticalSpacing = verticalSpacing; this.HorizontalSpacing = horizontalSpacing; this.Kerning = kerning; this.DefaultCharacter = defaultCharacter; }
public bool AddOutline(Texture2DContent tex) { SurfaceFormat fmt; if (!tex.Mipmaps[0].TryGetFormat(out fmt)) { return false; } if (fmt != SurfaceFormat.Color) { context_.Logger.LogImportantMessage("Converting from format {0} to Color.", fmt.ToString()); tex.ConvertBitmapType(typeof(PixelBitmapContent<Color>)); } byte[] data = tex.Mipmaps[0].GetPixelData(); int n = AddOutline(data, tex.Mipmaps[0].Width, tex.Mipmaps[0].Height); tex.Mipmaps[0].SetPixelData(data); context_.Logger.LogMessage("Converting bitmap {0}x{1} touches {2} pixels.", tex.Mipmaps[0].Width, tex.Mipmaps[0].Height, n); tex.GenerateMipmaps(true); return true; }
private void CreateExEnOutput(Texture2DContent input, ContentProcessorContext context) { ExEnFontWriter.CreateOutputDirectory(input.Identity); // Put the processor in a format suitable for outputting to PNG var originalPremultiply = PremultiplyAlpha; var originalFormat = TextureFormat; PremultiplyAlpha = false; TextureFormat = TextureProcessorOutputFormat.Color; // Build normal size: SpriteFontContent spriteFontContent = base.Process(input, context); ExEnFontWriter.WriteTexture(spriteFontContent, false, context, ExEnFontWriter.AssetOutputFilename(input.Identity, context, "-exenfont.png")); ExEnFontWriter.WriteMetrics(spriteFontContent, context, ExEnFontWriter.AssetOutputFilename(input.Identity, context, "-exenfont.exenfont")); // Check for retina size: string pathAt2x = Path.Combine(Path.GetDirectoryName(input.Identity.SourceFilename), Path.GetFileNameWithoutExtension(input.Identity.SourceFilename) + "@2x" + Path.GetExtension(input.Identity.SourceFilename)); if(File.Exists(pathAt2x)) { var textureImporter = new TextureImporter(); var textureAt2x = (Texture2DContent)textureImporter.Import(pathAt2x, null); context.AddDependency(pathAt2x); var spriteFontContentAt2x = base.Process(textureAt2x, context); ExEnFontWriter.WriteTexture(spriteFontContentAt2x, false, context, ExEnFontWriter.AssetOutputFilename(input.Identity, context, "*****@*****.**")); ExEnFontWriter.WriteMetrics(spriteFontContentAt2x, context, ExEnFontWriter.AssetOutputFilename(input.Identity, context, "*****@*****.**")); } PremultiplyAlpha = originalPremultiply; TextureFormat = originalFormat; }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { // Fallback if we aren't buiding for iOS. var platform = ContentHelper.GetMonoGamePlatform(); if (platform != MonoGamePlatform.iOS) return base.Process(input, context); SpriteFontContent content = base.Process(input, context); // TODO: This is a very lame way of doing this as we're getting compression artifacts twice, but is the quickest way to get // Compressed fonts up and running. The SpriteFontContent/Processor contains a ton // of sealed/internal classes riddled with private fields, so overriding CompressFontTexture // or even Process is tricky. This works for now, but should be replaced when the content pipeline // moves a bit further var texWidth = input.Faces[0][0].Width; var texHeight = input.Faces[0][0].Height; // Resize to square, power of two if necessary. if (texWidth != texHeight) { texHeight = texWidth = Math.Max(texHeight, texWidth); var resizedBitmap = (BitmapContent)Activator.CreateInstance(typeof(PixelBitmapContent<Color>), new object[] { texWidth, texHeight }); var textureRegion = new Rectangle(0, 0, input.Faces[0][0].Width, input.Faces[0][0].Height); BitmapContent.Copy(input.Faces[0][0], textureRegion, resizedBitmap, textureRegion); input.Faces[0].Clear(); input.Faces[0].Add(resizedBitmap); } else input.ConvertBitmapType(typeof(PixelBitmapContent<Color>)); MGTextureProcessor.ConvertToPVRTC(input, 1, true, MGCompressionMode.PVRTCFourBitsPerPixel); return content; }
public static void CompressPngToTexture2DContent( ParsedPath pngFileName, string compressionType, out Texture2DContent textureContent) { PngFile pngFile = PngFileReader.ReadFile(pngFileName); SquishMethod? squishMethod = null; SurfaceFormat surfaceFormat = SurfaceFormat.Color; switch (compressionType.ToLower()) { case "dxt1": squishMethod = SquishMethod.Dxt1; surfaceFormat = SurfaceFormat.Dxt1; break; case "dxt3": squishMethod = SquishMethod.Dxt3; surfaceFormat = SurfaceFormat.Dxt3; break; case "dxt5": squishMethod = SquishMethod.Dxt5; surfaceFormat = SurfaceFormat.Dxt5; break; default: case "none": surfaceFormat = SurfaceFormat.Color; break; } BitmapContent bitmapContent; if (surfaceFormat != SurfaceFormat.Color) { byte[] rgbaData = Squish.CompressImage( pngFile.RgbaData, pngFile.Width, pngFile.Height, squishMethod.Value, SquishFit.IterativeCluster, SquishMetric.Default, SquishExtra.None); bitmapContent = new BitmapContent(surfaceFormat, pngFile.Width, pngFile.Height, rgbaData); } else { bitmapContent = new BitmapContent(SurfaceFormat.Color, pngFile.Width, pngFile.Height, pngFile.RgbaData); } textureContent = new Texture2DContent(bitmapContent); }
static internal TextureContent Import(string filename, ContentImporterContext context) { var identity = new ContentIdentity(filename); TextureContent output = null; using (var reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read))) { // Read signature ("DDS ") var valid = reader.ReadByte() == 0x44; valid = valid && reader.ReadByte() == 0x44; valid = valid && reader.ReadByte() == 0x53; valid = valid && reader.ReadByte() == 0x20; if (!valid) throw new ContentLoadException("Invalid file signature"); var header = new DdsHeader(); // Read DDS_HEADER header.dwSize = reader.ReadUInt32(); if (header.dwSize != 124) throw new ContentLoadException("Invalid DDS_HEADER dwSize value"); header.dwFlags = (Ddsd)reader.ReadUInt32(); header.dwHeight = reader.ReadUInt32(); header.dwWidth = reader.ReadUInt32(); header.dwPitchOrLinearSize = reader.ReadUInt32(); header.dwDepth = reader.ReadUInt32(); header.dwMipMapCount = reader.ReadUInt32(); // The next 11 DWORDs are reserved and unused for (int i = 0; i < 11; ++i) reader.ReadUInt32(); // Read DDS_PIXELFORMAT header.ddspf.dwSize = reader.ReadUInt32(); if (header.ddspf.dwSize != 32) throw new ContentLoadException("Invalid DDS_PIXELFORMAT dwSize value"); header.ddspf.dwFlags = (Ddpf)reader.ReadUInt32(); header.ddspf.dwFourCC = (FourCC)reader.ReadUInt32(); header.ddspf.dwRgbBitCount = reader.ReadUInt32(); header.ddspf.dwRBitMask = reader.ReadUInt32(); header.ddspf.dwGBitMask = reader.ReadUInt32(); header.ddspf.dwBBitMask = reader.ReadUInt32(); header.ddspf.dwABitMask = reader.ReadUInt32(); // Continue reading DDS_HEADER header.dwCaps = (DdsCaps)reader.ReadUInt32(); header.dwCaps2 = (DdsCaps2)reader.ReadUInt32(); // dwCaps3 unused reader.ReadUInt32(); // dwCaps4 unused reader.ReadUInt32(); // dwReserved2 unused reader.ReadUInt32(); // Check for the existence of the DDS_HEADER_DXT10 struct next if (header.ddspf.dwFlags == Ddpf.FourCC && header.ddspf.dwFourCC == FourCC.Dx10) { throw new ContentLoadException("Unsupported DDS_HEADER_DXT10 struct found"); } int faceCount = 1; int mipMapCount = (int)(header.dwCaps.HasFlag(DdsCaps.MipMap) ? header.dwMipMapCount : 1); if (header.dwCaps.HasFlag(DdsCaps.Complex)) { if (header.dwCaps2.HasFlag(DdsCaps2.Cubemap)) { if (!header.dwCaps2.HasFlag(DdsCaps2.CubemapAllFaces)) throw new ContentLoadException("Incomplete cubemap in DDS file"); faceCount = 6; output = new TextureCubeContent() { Identity = identity }; } else { output = new Texture2DContent() { Identity = identity }; } } else { output = new Texture2DContent() { Identity = identity }; } bool rbSwap; var format = GetSurfaceFormat(ref header.ddspf, out rbSwap); for (int f = 0; f < faceCount; ++f) { var w = (int)header.dwWidth; var h = (int)header.dwHeight; var mipMaps = new MipmapChain(); for (int m = 0; m < mipMapCount; ++m) { var content = CreateBitmapContent(format, w, h); var byteCount = GetBitmapSize(format, w, h); var bytes = reader.ReadBytes(byteCount); content.SetPixelData(bytes); mipMaps.Add(content); w = MathHelper.Max(1, w / 2); h = MathHelper.Max(1, h / 2); } output.Faces[f] = mipMaps; } } return output; }
public void ColorConversion() { var context = new TestProcessorContext(TargetPlatform.Windows, "dummy.xnb"); var processor = new FontTextureProcessor { FirstCharacter = '0', PremultiplyAlpha = false }; var face = new PixelBitmapContent<Color>(32, 9); var O = Color.Transparent.PackedValue; var M = Color.Fuchsia.PackedValue; var R = Color.Red.PackedValue; var G = Color.Green.PackedValue; var B = Color.Blue.PackedValue; var W = Color.White.PackedValue; var pixelData = new[] { M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, O, O, O, O, O, O, M, M, O, O, O, O, O, O, M, M, O, O, O, O, O, O, M, M, O, O, O, O, O, O, M, M, O, O, W, W, O, O, M, M, O, O, O, R, O, O, M, M, O, G, G, G, O, O, M, M, O, B, B, B, B, O, M, M, O, W, O, O, W, O, M, M, O, O, R, R, O, O, M, M, O, O, O, O, G, O, M, M, O, O, O, B, O, O, M, M, O, W, O, O, W, O, M, M, O, O, O, R, O, O, M, M, O, O, G, G, O, O, M, M, O, O, B, B, O, O, M, M, O, W, O, O, W, O, M, M, O, O, O, R, O, O, M, M, O, G, O, O, O, O, M, M, O, O, O, O, B, O, M, M, O, O, W, W, O, O, M, M, O, R, R, R, R, O, M, M, O, G, G, G, G, O, M, M, O, B, B, B, O, O, M, M, O, O, O, O, O, O, M, M, O, O, O, O, O, O, M, M, O, O, O, O, O, O, M, M, O, O, O, O, O, O, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, }; var pixelBytes = new byte[face.Width * 4 * face.Height]; Buffer.BlockCopy(pixelData, 0, pixelBytes, 0, pixelData.Length * 4); face.SetPixelData(pixelBytes); var input = new Texture2DContent(); input.Faces[0] = face; var output = processor.Process(input, context); Assert.NotNull(output); Assert.AreEqual(output.CharacterMap[0], '0'); Assert.AreEqual(output.CharacterMap[1], '1'); Assert.AreEqual(output.CharacterMap[2], '2'); Assert.AreEqual(output.CharacterMap[3], '3'); Assert.AreEqual(1, output.Texture.Faces.Count); Assert.AreEqual(1, output.Texture.Faces[0].Count); Assert.IsAssignableFrom<PixelBitmapContent<Color>>(output.Texture.Faces[0][0]); var outFace = (PixelBitmapContent<Color>)output.Texture.Faces[0][0]; for (var i = 0; i < 4; ++i) { // (2, 2, 4, 5) is the top,left and width,height of the first glyph. All test glyphs are 4x5 var inRect = new Rectangle(i * 8 + 2, 2, 4, 5); var outRect = output.Glyphs[i]; Assert.AreEqual(inRect.Width, outRect.Width); Assert.AreEqual(inRect.Height, outRect.Height); for (var y = 0; y < inRect.Height; ++y) for (var x = 0; x < inRect.Width; ++x) Assert.AreEqual(pixelData[(x + inRect.Left) + (y + inRect.Top) * face.Width], outFace.GetPixel(x + outRect.Left, y + outRect.Top).PackedValue); } Assert.AreEqual(new Rectangle(1, 1, 6, 7), output.Cropping[0]); Assert.AreEqual(new Rectangle(1, 1, 6, 7), output.Cropping[1]); Assert.AreEqual(new Rectangle(1, 1, 6, 7), output.Cropping[2]); Assert.AreEqual(new Rectangle(1, 1, 6, 7), output.Cropping[3]); }