/// <summary> /// Process converts the encoded normals to the NormalizedByte4 format and /// generates mipmaps. /// </summary> /// <param name="input"></param> /// <param name="context"></param> /// <returns></returns> public override TextureContent Process(TextureContent input, ContentProcessorContext context) { Texture2DContent result = new Texture2DContent(); if (input.Faces[0][0] is PixelBitmapContent <Alpha8> ) { return(input); } input.ConvertBitmapType(typeof(PixelBitmapContent <Vector3>)); PixelBitmapContent <Vector3> source = input.Faces[0][0] as PixelBitmapContent <Vector3>; PixelBitmapContent <Alpha8> bitmap = new PixelBitmapContent <Alpha8>(source.Width, source.Height); for (int y = 0; y < source.Height; ++y) { for (int x = 0; x < source.Width; ++x) { Vector3 src = source.GetPixel(x, y); bitmap.SetPixel(x, y, new Alpha8( 0.3f * src.X + 0.59f * src.Y + 0.11f * src.Z)); } } result.Mipmaps.Add(bitmap); return(result); }
void CompressDefault <T>(TargetPlatform platform, Color color, int width = 16, int height = 16) { var context = new TestProcessorContext(platform, "dummy.xnb"); var processor = new TextureProcessor { ColorKeyEnabled = false, GenerateMipmaps = true, PremultiplyAlpha = false, ResizeToPowerOfTwo = false, TextureFormat = TextureProcessorOutputFormat.Compressed }; var face = new PixelBitmapContent <Color>(width, height); Fill(face, color); var input = new Texture2DContent(); input.Faces[0] = face; var output = processor.Process(input, context); Assert.NotNull(output); Assert.AreEqual(1, output.Faces.Count, "Expected number of faces"); Assert.AreEqual(5, output.Faces[0].Count, "Expected number of mipmaps"); Assert.IsAssignableFrom <T>(output.Faces[0][0], "Incorrect pixel format"); }
/// <summary> /// Called by the XNA Framework when importing a 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) { var output = new Texture2DContent(); output._bitmap = new Bitmap(filename); var width = output._bitmap.Width; var height = output._bitmap.Height; // Force the input's pixelformat to ARGB32, so we can have a common pixel format to deal with. if (output._bitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Format32bppArgb) { var bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); using (var graphics = System.Drawing.Graphics.FromImage(bitmap)) { graphics.DrawImage(output._bitmap, 0, 0, width, height); } output._bitmap = bitmap; } var imageData = output._bitmap.GetData(); var bitmapContent = new PixelBitmapContent <Color>(width, height); bitmapContent.SetPixelData(imageData); output.Faces.Add(new MipmapChain(bitmapContent)); return(output); }
public unsafe static Texture2DContent Build(Stream dataStream) { using (var rawImage = SixLabors.ImageSharp.Image.Load(dataStream)) using (var image = rawImage.CloneAs <Rgba32>()) { var pixels = image.GetPixelSpan(); var imageData = new int[pixels.Length]; fixed(int *imageDataPointer = imageData) { var casted = new Span <Rgba32>(imageDataPointer, imageData.Length); pixels.CopyTo(casted); } //We're only supporting R8G8B8A8 right now, so texel size in bytes is always 4. //We don't compute mips during at content time. We could, but... there's not much reason to. //The font builder does because it uses a nonstandard mip process, but this builder is expected to be used to with normal data. var content = new Texture2DContent(image.Width, image.Height, 1, sizeof(Rgba32)); var data = (Rgba32 *)content.Pin(); //Copy the image data into the Texture2DContent. for (int rowIndex = 0; rowIndex < image.Height; ++rowIndex) { var sourceRow = image.GetPixelRowSpan(rowIndex); var targetRow = data + content.GetRowOffsetForMip0(rowIndex); Unsafe.CopyBlockUnaligned(ref *(byte *)targetRow, ref Unsafe.As <Rgba32, byte>(ref sourceRow[0]), (uint)(sizeof(Rgba32) * image.Width)); } content.Unpin(); return(content); } }
internal static void WriteTexture(object spriteFontContent, bool alphaOnly, ContentProcessorContext context, string filename) { dynamic sfc = ExposedObject.From(spriteFontContent); // Get a copy of the texture in Color format Texture2DContent originalTexture = sfc.Texture; BitmapContent originalBitmap = originalTexture.Mipmaps[0]; PixelBitmapContent <Color> colorBitmap = new PixelBitmapContent <Color>( originalBitmap.Width, originalBitmap.Height); BitmapContent.Copy(originalBitmap, colorBitmap); Bitmap bitmap = new Bitmap(colorBitmap.Width, colorBitmap.Height, PixelFormat.Format32bppArgb); for (int x = 0; x < colorBitmap.Width; x++) { for (int y = 0; y < colorBitmap.Height; y++) { Color c = colorBitmap.GetPixel(x, y); if (alphaOnly) { c.R = 255; c.G = 255; c.B = 255; // Undo premultiplication } bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(c.A, c.R, c.G, c.B)); } } bitmap.Save(filename, ImageFormat.Png); bitmap.Dispose(); context.AddOutputFile(filename); }
public override TextureContent Import(string filename, ContentImporterContext context) { // load raw data FileStream reader = File.OpenRead(filename); int width = 257; int height = 257; byte[] bytes = new byte[reader.Length]; reader.Read(bytes, 0, bytes.Length); reader.Close(); // import into standard XNA bitmap container PixelBitmapContent <Color> bitmapContent = new PixelBitmapContent <Color>(width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { bitmapContent.SetPixel(x, y, new Color(bytes[(y * width) + x], 0, 0)); } } // create and return one-mipmap-level Texture2DContent content = new Texture2DContent { Identity = new ContentIdentity(filename) }; content.Mipmaps.Add(bitmapContent); return(content); }
private static TextureContent Compress(Type bitmapContentType, Texture texture, ContentIdentity identity) { // Let MonoGame's BitmapContent handle the compression. 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)]; var sourceBitmap = TextureHelper.ToContent(image); var targetBitmap = (BitmapContent)Activator.CreateInstance(bitmapContentType, image.Width, image.Height); BitmapContent.Copy(sourceBitmap, targetBitmap); textureContent.Mipmaps.Add(targetBitmap); } 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)]; var sourceBitmap = TextureHelper.ToContent(image); var targetBitmap = (BitmapContent)Activator.CreateInstance(bitmapContentType, image.Width, image.Height); BitmapContent.Copy(sourceBitmap, targetBitmap); textureContent.Faces[faceIndex].Add(targetBitmap); } } 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)]; var sourceBitmap = TextureHelper.ToContent(image); var targetBitmap = (BitmapContent)Activator.CreateInstance(bitmapContentType, image.Width, image.Height); BitmapContent.Copy(sourceBitmap, targetBitmap); textureContent.Faces[zIndex].Add(targetBitmap); } } return textureContent; } } throw new InvalidOperationException("Invalid texture dimension."); }
protected string BuildTexture(BitmapContent bitmap, IDictionary <string, object> processorParameters = null) { TextureContent texture = new Texture2DContent(); texture.Faces[0] = new MipmapChain(bitmap); return(BuildObject(texture, "TextureProcessor", processorParameters)); }
/// <summary> /// Construye el mapa de alturas a partir de la textura especificada /// </summary> /// <param name="terrain">Textura con el mapa de alturas del terreno</param> /// <param name="cellScale">Escala de alturas</param> /// <param name="context">Contexto</param> /// <returns>Devuelve el mapa de alturas generado</returns> private HeightMap BuildHeightMap(Texture2DContent terrain, float cellScale, ContentProcessorContext context) { if (terrain.Mipmaps.Count > 0) { BitmapContent heightMapContent = terrain.Mipmaps[0]; // Sólo se soportan texturas cuadradas if (heightMapContent.Width == heightMapContent.Height) { byte[] pixelData = heightMapContent.GetPixelData(); // Construir el mapa de alturas return(HeightMap.FromData( pixelData, heightMapContent.Height, heightMapContent.Width, cellScale)); } else { //Sólo se soportan texturas cuadradas throw new NotImplementedException(); } } else { throw new PipelineException("El archivo de mapa de alturas no tiene el formato correcto. No se encuentra la imagen"); } }
public static SpriteFont Compile(GraphicsDevice g, string file, out IDisposable gR) { FontDescriptionImporter ei = new FontDescriptionImporter(); FontDescription ec = ei.Import(file, new XNADynImporterContext()); FontDescriptionProcessor ep = new FontDescriptionProcessor(); var cec = ep.Process(ec, new XNADynProcessorContext()); // Get Private Texture Texture2DContent texC = sfcTexture.GetValue(cec) as Texture2DContent; MipmapChain o = txcMipmaps.GetValue(texC, null) as MipmapChain; BitmapContent texBMP = o[0]; SurfaceFormat sf; if (!texBMP.TryGetFormat(out sf)) { throw new InvalidContentException("Could Not Obtain The Surface Format Of The SpriteFont"); } Texture2D texture = new Texture2D(g, texBMP.Width, texBMP.Height, false, sf); texture.SetData(texBMP.GetPixelData()); // Get Private Glyph Data List <Rectangle> glyphs = sfcGlyphs.GetValue(cec) as List <Rectangle>; List <Rectangle> cropping = sfcCropping.GetValue(cec) as List <Rectangle>; List <char> charMap = sfcCharMap.GetValue(cec) as List <char>; int lineSpacing = (int)sfcLineSpacing.GetValue(cec); float spacing = (float)sfcSpacing.GetValue(cec); List <Vector3> kerning = sfcKerning.GetValue(cec) as List <Vector3>; char? defaultChar = sfcDefaultChar.GetValue(cec) as char?; // Invoke Private SpriteFont Constructor gR = texture; return(sfConstructor.Invoke(new object[] { texture, glyphs, cropping, charMap, lineSpacing, spacing, kerning, defaultChar }) as SpriteFont); }
public unsafe RenderableImage(Device device, DeviceContext context, Texture2DContent imageContent, bool srgb = false, string debugName = null) { Content = imageContent; if (imageContent.TexelSizeInBytes != 4) { throw new ArgumentException("The renderable image assumes an R8G8B8A8_UNorm or texture."); } Debug.Assert(imageContent.MipLevels == 1, "We ignore any mip levels stored in the content; if the content pipeline output them, something's likely mismatched."); Texture = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, Format = srgb ? SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb : SharpDX.DXGI.Format.R8G8B8A8_UNorm, Height = imageContent.Height, Width = imageContent.Width, MipLevels = (int)MathF.Floor(MathF.Log(MathF.Min(imageContent.Width, imageContent.Height), 2)) + 1, OptionFlags = ResourceOptionFlags.GenerateMipMaps, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), Usage = ResourceUsage.Default }); Texture.DebugName = debugName; SRV = new ShaderResourceView(device, Texture); SRV.DebugName = debugName + " SRV"; UploadContentToTexture(context); }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { string defFile = Path.ChangeExtension(input.Identity.SourceFilename, "txt"); if (File.Exists(defFile)) { List <CharacterRange> ranges = new List <CharacterRange>(); string txt = File.ReadAllText(defFile); CharacterRange range = null; foreach (char item in txt) { Characters.Add(item); if (range == null) { range = new CharacterRange(item); } else { if (!range.Extend(item)) { ranges.Add(range); range = new CharacterRange(item); } } } StringBuilder rangeText = new StringBuilder(); ranges.Add(range); ranges.ForEach(r => rangeText.Append(r + ";")); File.WriteAllText(defFile.Insert(defFile.Length - 4, "-ranges"), rangeText.ToString(0, rangeText.Length - 1)); } return(base.Process(input, context)); }
private AbstractTile ParseTileNode(XmlNode tileNode, LevelSet project, Dictionary <int, object> objectIdDictionary) { SimpleTile2DTransitionObject tile = new SimpleTile2DTransitionObject(); tile.Name = tileNode.Attributes["name"].Value; int id = Convert.ToInt32(tileNode.Attributes["id"].Value); int height = Convert.ToInt32(tileNode.Attributes["height"].Value); int width = Convert.ToInt32(tileNode.Attributes["width"].Value); objectIdDictionary[id] = tile; Texture2DContent textureContent = new Texture2DContent(); foreach (XmlNode childNode in tileNode.ChildNodes) { if (childNode.Name == "contents") { byte[] binaryData = Convert.FromBase64String(childNode.InnerText); PixelBitmapContent <Color> rawData = new PixelBitmapContent <Color>(width, height); rawData.SetPixelData(binaryData); textureContent.Mipmaps = new MipmapChain(rawData); } } tile.TextureContent = textureContent; return(tile); }
public override TextureContent Import(string filename, ContentImporterContext context) { // load tiff data m_pReader = new BinaryReader(File.OpenRead(filename)); int nOffsetFirstIFD = ReadHeader(); ReadAllIfds(nOffsetFirstIFD); m_pReader.Close(); // import into standard XNA bitmap container PixelBitmapContent <float> bitmapContent = new PixelBitmapContent <float>(m_nWidth, m_nHeight); for (int y = 0; y < m_nHeight; y++) { for (int x = 0; x < m_nWidth; x++) { bitmapContent.SetPixel(x, y, m_pImageData[(y * m_nWidth) + x]); } } // create and return one-mipmap-level Texture2DContent content = new Texture2DContent(); content.Mipmaps.Add(bitmapContent); return(content); }
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])); }
void CompressDefault <T>(TargetPlatform platform, Color color) { var context = new TestProcessorContext(platform, "dummy.xnb"); var processor = new TextureProcessor { ColorKeyEnabled = false, GenerateMipmaps = false, PremultiplyAlpha = false, ResizeToPowerOfTwo = false, TextureFormat = TextureProcessorOutputFormat.Compressed }; var face = new PixelBitmapContent <Color>(16, 16); Fill(face, color); 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 <T>(output.Faces[0][0]); }
public override Texture2DContent Process(List <byte[]> input, ContentProcessorContext context) { for (int p = 0; p < input.Count; ++p) { if (input[p].Length != Height * Width * sizeof(float) * 3 / (1 << (2 * p))) { throw new InvalidContentException("The number of bytes in one or more of the images does not correlate with the product of the Height and Width properties."); } } MipmapChain imageChain = new MipmapChain(); int mip = 0; for (; mip < input.Count; ++mip) { byte[] paddedBytes = new byte[input[mip].Length / 3 * 4]; int srcIndex = 0; int destIndex = 0; while (srcIndex < input[mip].Length) { paddedBytes[destIndex++] = input[mip][srcIndex++]; if (srcIndex % 12 == 0) { for (int x = 0; x < 4; ++x) { paddedBytes[destIndex++] = 0; } } } int mipReduction = 1 << mip; BitmapContent image = new PixelBitmapContent <Vector4>(Width / mipReduction, Height / mipReduction); image.SetPixelData(paddedBytes); imageChain.Add(image); } // Check to see if this is a partial mipmap chain: if (imageChain.Count > 1) { // Just fill the rest of the chain with anything to satisfy the validator that the chain is complete. while ((Math.Max(Height, Width) >> (mip - 1)) > 1) { int mipReduction = 1 << mip; int mipHeight = Math.Max(Height / mipReduction, 1); int mipWidth = Math.Max(Width / mipReduction, 1); byte[] bytes = new byte[mipHeight * mipWidth * sizeof(float) * 4]; BitmapContent image = new PixelBitmapContent <Vector4>(mipWidth, mipHeight); image.SetPixelData(bytes); imageChain.Add(image); ++mip; } } Texture2DContent outputTC = new Texture2DContent(); outputTC.Mipmaps = imageChain; return(outputTC); }
public override BitmapFontProcessorResult Process(BitmapFontFile bitmapFontFile, ContentProcessorContext context) { try { context.Logger.LogMessage("Processing BMFont, Kerning pairs: {0}", bitmapFontFile.Kernings.Count); var result = new BitmapFontProcessorResult(bitmapFontFile); result.PackTexturesIntoXnb = PackTexturesIntoXnb; foreach (var fontPage in bitmapFontFile.Pages) { // find our texture so we can embed it in the xnb asset var imageFile = Path.Combine(Path.GetDirectoryName(bitmapFontFile.File), fontPage.File); context.Logger.LogMessage("looking for image file: {0}", imageFile); if (!File.Exists(imageFile)) { throw new Exception(string.Format("Could not locate font atlas file {0} relative to folder {1}", fontPage.File, Directory.GetCurrentDirectory())); } if (PackTexturesIntoXnb) { context.Logger.LogMessage("Found texture: {0}. Packing into xnb", imageFile); var textureReference = new ExternalReference <TextureContent>(imageFile); var texture = context.BuildAndLoadAsset <TextureContent, TextureContent>(textureReference, "TextureProcessor"); var textureContent = new Texture2DContent(); textureContent.Mipmaps.Add(texture.Faces[0][0]); if (CompressTextures) { textureContent.ConvertBitmapType(typeof(Dxt5BitmapContent)); } result.Textures.Add(textureContent); } else { var textureFilename = PathHelper.MakeRelativePath(Directory.GetCurrentDirectory(), imageFile) .Replace("Content/", string.Empty); textureFilename = Path.ChangeExtension(textureFilename, null); context.Logger.LogMessage( "Not writing texture but it is expected to exist and be processed: {0}", textureFilename); result.TextureNames.Add(textureFilename); result.TextureOrigins.Add(new Vector2(fontPage.X, fontPage.Y)); } } return(result); } catch (Exception ex) { context.Logger.LogMessage("Error {0}", ex); throw; } }
/// <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 WpfSpriteFontContent() { Texture = new Texture2DContent(); Glyphs = new List <Rectangle>(); Cropping = new List <Rectangle>(); CharacterMap = new List <char>(); Kerning = new List <Vector3>(); }
internal FontContent(BitmapContent texture, int height, Dictionary <char, Glyph> glyphs, SortedDictionary <uint, int> kerningPairs) { this.texture = new Texture2DContent(); this.texture.Mipmaps = texture; this.height = height; this.glyphs = glyphs; this.kerningPairs = kerningPairs; }
public override TextureContent Import(string filename, ContentImporterContext context) { Texture2DContent output; if (Path.GetExtension(filename) != ".slmc") { throw new InvalidContentException("File type not supported."); } var images = ImportSLMC(filename, context); if (images.Count < 1) { throw new InvalidContentException("Element 'channels' must have at least one 'image'."); } if (images.Count > 4) { throw new InvalidContentException("No more than 4 images are supported."); } int width = images[0].Mipmaps[0].Width; int height = images[0].Mipmaps[0].Height; // validate size foreach (var image in images) { if (image.Mipmaps[0].Width != width || image.Mipmaps[0].Height != height) { throw new InvalidContentException("Images must be of the same size."); } } var pixelCount = width * height; var byteCount = pixelCount * 4; byte[] data = new byte[byteCount]; for (int i = 0; i < images.Count; i++) { var image = images[i]; var face = image.Faces[0][0]; var pixelData = face.GetPixelData(); for (int d = 0; d < pixelCount; d++) { data[d * 4 + i] = pixelData[d * 4]; } } var bitmap = new PixelBitmapContent <Color>(width, height); bitmap.SetPixelData(data); output = new Texture2DContent(); output.Faces[0].Add(bitmap); return(output); }
public override TextureContent Import(string filename, ContentImporterContext context) { using (FileStream file = new FileStream(filename, FileMode.Open)) { byte[] bytes = new byte[file.Length]; file.Read(bytes, 0, (int)file.Length); bool bit16 = false; // Figure out file size if (Width <= 0 || Height <= 0) { Width = (int)Math.Sqrt(file.Length); Height = (int)(file.Length / Width); if (Width * Height != file.Length) { Width = (int)Math.Sqrt(file.Length / 2); Height = (int)(file.Length / 2 / Width); bit16 = true; } if (Width * Height * 2 == file.Length) { context.Logger.LogWarning(null, new ContentIdentity(filename), "Input texture not a raw grayscale texture, or the specified width and height do not match."); } } // Create texture int i = 0; PixelBitmapContent <float> bitmap = new PixelBitmapContent <float>(Width, Height); for (int y = 0; y < Height; ++y) { for (int x = 0; x < Width; ++x) { if (bit16) { bitmap.SetPixel(x, y, 1.0f * (ushort)((bytes[i++] | bytes[i++] << 8)) / ushort.MaxValue); } else { bitmap.SetPixel(x, y, 1.0f * bytes[i++] / byte.MaxValue); } } } Texture2DContent result = new Texture2DContent(); result.Mipmaps = new MipmapChain(bitmap); return(result); } }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { if (context.TargetPlatform == TargetPlatform.Windows) { CreateExEnOutput(input, context); } return(base.Process(input, context)); }
public void MipmapNonSquareNonPowerOfTwo() { var context = new TestProcessorContext(TargetPlatform.Windows, "dummy.xnb"); var processor = new TextureProcessor { ColorKeyEnabled = false, GenerateMipmaps = true, PremultiplyAlpha = false, ResizeToPowerOfTwo = false, TextureFormat = TextureProcessorOutputFormat.Color }; var width = 23; var height = 5; var face = new PixelBitmapContent <Color>(width, height); 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); var outChain = output.Faces[0]; Assert.AreEqual(5, outChain.Count); 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)); } } if (width > 1) { width /= 2; } if (height > 1) { height /= 2; } } }
/// <summary> /// Called by the XNA Framework when importing a 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) { var output = new Texture2DContent { Identity = new ContentIdentity(filename) }; #if WINDOWS || MACOS // TODO: This is a pretty lame way to do this. It would be better // if we could completely get rid of the System.Drawing.Bitmap // class and replace it with FreeImage, but some other processors/importers // such as Font rely on Bitmap. Soon, we should completely remove any references // to System.Drawing.Bitmap and replace it with FreeImage. For now // this is the quickest way to add support for virtually every input Texture // format without breaking functionality in other places. var fBitmap = FreeImage.LoadEx(filename); var info = FreeImage.GetInfoHeaderEx(fBitmap); // creating a System.Drawing.Bitmap from a >= 64bpp image isn't // supported. if (info.biBitCount > 32) { var temp = FreeImage.ConvertTo32Bits(fBitmap); // The docs are unclear on what's happening here... // If a new bitmap is created or if the old is just converted. // UnloadEx doesn't throw any exceptions if it's called multiple // times on the same bitmap, so just being cautious here. FreeImage.UnloadEx(ref fBitmap); fBitmap = temp; } var systemBitmap = FreeImage.GetBitmap(fBitmap); FreeImage.UnloadEx(ref fBitmap); #else var systemBitmap = new Bitmap(filename); #endif var height = systemBitmap.Height; var width = systemBitmap.Width; // Force the input's pixelformat to ARGB32, so we can have a common pixel format to deal with. if (systemBitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Format32bppArgb) { var bitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); using (var graphics = System.Drawing.Graphics.FromImage(bitmap)) { graphics.DrawImage(systemBitmap, 0, 0, width, height); } systemBitmap = bitmap; } output.Faces[0].Add(systemBitmap.ToXnaBitmap(true)); systemBitmap.Dispose(); return(output); }
public unsafe RenderableImage(Device device, DeviceContext context, Texture2DContent imageContent, bool srgb = false, string debugName = null) { if (imageContent.TexelSizeInBytes != 4) { throw new ArgumentException("The renderable image assumes an R8G8B8A8_UNorm or texture."); } Debug.Assert(imageContent.MipLevels == 1, "We ignore any mip levels stored in the content; if the content pipeline output them, something's likely mismatched."); Initialize(device, imageContent.Width, imageContent.Height, srgb, debugName); Content = imageContent; UploadContentToTexture(context); }
public RenderableImage(Texture2DContent imageContent, bool srgb = false, string debugName = null) { if (imageContent.TexelSizeInBytes != 4) { throw new ArgumentException("The renderable image assumes an R8G8B8A8_UNorm or texture."); } Debug.Assert(imageContent.MipLevels == 1, "We ignore any mip levels stored in the content; if the content pipeline output them, something's likely mismatched."); Content = imageContent; this.srgb = srgb; DebugName = debugName; UploadContentToTexture(); }
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); }
/// <summary> /// The compile. /// </summary> /// <param name="asset"> /// The asset. /// </param> /// <param name="platform"> /// The platform. /// </param> public void Compile(TextureAsset asset, TargetPlatform platform) { if (asset.RawData == null) { return; } var output = new Texture2DContent(); var bitmap = new Bitmap(new MemoryStream(asset.RawData)); var width = bitmap.Width; var height = bitmap.Height; if (bitmap.PixelFormat == PixelFormat.Format8bppIndexed) { throw new InvalidDataException( "8-bit indexed PNGs do not convert correctly (at least under Mono) to 32-bit ARGB. Save " + "your PNG files in a non-indexed format, such as 24-bit or 32-bit ARGB."); } if (bitmap.PixelFormat != PixelFormat.Format32bppArgb) { var newBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); using (var graphics = Graphics.FromImage(newBitmap)) graphics.DrawImage(bitmap, 0, 0, width, height); bitmap = newBitmap; } output.Faces[0] = new MipmapChain(bitmap.ToXnaBitmap(true)); bitmap.Dispose(); var manager = new PipelineManager( Environment.CurrentDirectory, Environment.CurrentDirectory, Environment.CurrentDirectory); var dictionary = new OpaqueDataDictionary(); var processor = manager.CreateProcessor("TextureProcessor", dictionary); var context = new DummyContentProcessorContext(TargetPlatformCast.ToMonoGamePlatform(platform)); var content = processor.Process(output, context); asset.PlatformData = new PlatformData { Platform = platform, Data = this.CompileAndGetBytes(content) }; try { asset.ReloadTexture(); } catch (NoAssetContentManagerException) { } }