コード例 #1
0
    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.");
    }
コード例 #2
0
        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);
        }
コード例 #3
0
        public void BitmapCompressFullResize()
        {
            var b1 = new PixelBitmapContent <Color>(16, 16);

            Fill(b1, Color.Red);
            var b2 = new Dxt1BitmapContent(8, 8);

            BitmapContent.Copy(b1, b2);
        }
コード例 #4
0
        /// <summary>
        /// Once the arranging is complete, copies the bitmap data for each
        /// sprite to its chosen position in the single larger output bitmap.
        /// </summary>
        static BitmapContent CopySpritesToOutput(List <ArrangedSprite> sprites,
                                                 IList <BitmapContent> sourceSprites,
                                                 ICollection <Rectangle> outputSprites,
                                                 int width, int height)
        {
            BitmapContent output = new PixelBitmapContent <Color>(width, height);

            foreach (ArrangedSprite sprite in sprites)
            {
                BitmapContent source = sourceSprites[sprite.Index];

                int x = sprite.X;
                int y = sprite.Y;

                int w = source.Width;
                int h = source.Height;

                // Copy the main sprite data to the output sheet.
                BitmapContent.Copy(source, new Rectangle(0, 0, w, h),
                                   output, new Rectangle(x + 1, y + 1, w, h));

                // Copy a border strip from each edge of the sprite, creating
                // a one pixel padding area to avoid filtering problems if the
                // sprite is scaled or rotated.
                BitmapContent.Copy(source, new Rectangle(0, 0, 1, h),
                                   output, new Rectangle(x, y + 1, 1, h));

                BitmapContent.Copy(source, new Rectangle(w - 1, 0, 1, h),
                                   output, new Rectangle(x + w + 1, y + 1, 1, h));

                BitmapContent.Copy(source, new Rectangle(0, 0, w, 1),
                                   output, new Rectangle(x + 1, y, w, 1));

                BitmapContent.Copy(source, new Rectangle(0, h - 1, w, 1),
                                   output, new Rectangle(x + 1, y + h + 1, w, 1));

                // Copy a single pixel from each corner of the sprite,
                // filling in the corners of the one pixel padding area.
                BitmapContent.Copy(source, new Rectangle(0, 0, 1, 1),
                                   output, new Rectangle(x, y, 1, 1));

                BitmapContent.Copy(source, new Rectangle(w - 1, 0, 1, 1),
                                   output, new Rectangle(x + w + 1, y, 1, 1));

                BitmapContent.Copy(source, new Rectangle(0, h - 1, 1, 1),
                                   output, new Rectangle(x, y + h + 1, 1, 1));

                BitmapContent.Copy(source, new Rectangle(w - 1, h - 1, 1, 1),
                                   output, new Rectangle(x + w + 1, y + h + 1, 1, 1));

                // Remember where we placed this sprite.
                outputSprites.Add(new Rectangle(x + 1, y + 1, w, h));
            }

            return(output);
        }
コード例 #5
0
        void BitmapCompressFullResize <T>(T color1)
            where T : struct, IEquatable <T>
        {
            var b1 = new PixelBitmapContent <T>(16, 16);

            Fill(b1, color1);
            var b2 = new Dxt1BitmapContent(8, 8);

            BitmapContent.Copy(b1, b2);
        }
コード例 #6
0
        static BitmapContent BitmapConvert(Type bitmapType, Color color, int w, int h)
        {
            var b1 = new PixelBitmapContent <Color>(w, h);

            Fill(b1, color);
            var b2 = (BitmapContent)Activator.CreateInstance(bitmapType, b1.Width, b1.Height);

            BitmapContent.Copy(b1, b2);
            return(b2);
        }
コード例 #7
0
        private List <Glyph> ExtractGlyphs(PixelBitmapContent <Color> bitmap)
        {
            var glyphs  = new List <Glyph>();
            var regions = new List <Rectangle>();

            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    if (bitmap.GetPixel(x, y) != transparentPixel)
                    {
                        // if we don't have a region that has this pixel already
                        var re = regions.Find(r => {
                            return(r.Contains(x, y));
                        });
                        if (re == Rectangle.Empty)
                        {
                            // we have found the top, left of a image.
                            // we now need to scan for the 'bounds'
                            int top    = y;
                            int bottom = y;
                            int left   = x;
                            int right  = x;
                            while (bitmap.GetPixel(right, bottom) != transparentPixel)
                            {
                                right++;
                            }
                            while (bitmap.GetPixel(left, bottom) != transparentPixel)
                            {
                                bottom++;
                            }
                            // we got a glyph :)
                            regions.Add(new Rectangle(left, top, right - left, bottom - top));
                            x = right;
                        }
                        else
                        {
                            x += re.Width;
                        }
                    }
                }
            }

            for (int i = 0; i < regions.Count; i++)
            {
                var rect      = regions[i];
                var newBitmap = new PixelBitmapContent <Color>(rect.Width, rect.Height);
                BitmapContent.Copy(bitmap, rect, newBitmap, new Rectangle(0, 0, rect.Width, rect.Height));
                var glyph = new Glyph(GetCharacterForIndex(i), newBitmap);
                glyph.CharacterWidths.B = glyph.Bitmap.Width;
                glyphs.Add(glyph);
                //newbitmap.Save (GetCharacterForIndex(i)+".png", System.Drawing.Imaging.ImageFormat.Png);
            }
            return(glyphs);
        }
コード例 #8
0
        private MipmapChain CreateFace(BitmapContent bitmapContent, int w, int h, int xOffset)
        {
            PixelBitmapContent <Color> result;

            result = new PixelBitmapContent <Color>(w, h);

            Rectangle sourceRegion = new Rectangle(xOffset, 0, w, h);

            Rectangle destinationRegion = new Rectangle(0, 0, w, h);

            BitmapContent.Copy(bitmapContent, sourceRegion, result, destinationRegion);

            return(result);
        }
コード例 #9
0
        private static void RenderAtlas(TextureAtlasContent output)
        {
            var outputBmp = new PixelBitmapContent <Color>(output.Width, output.Height);

            foreach (var sprite in output.DestinationSprites)
            {
                var srcBmp  = sprite.Texture.Faces[0][0];
                var srcRect = new Rectangle(0, 0, srcBmp.Width, srcBmp.Height);
                BitmapContent.Copy(srcBmp, srcRect, outputBmp, sprite.Bounds);
            }
            var mipmapChain = new MipmapChain(outputBmp);

            output.Texture.Mipmaps = mipmapChain;
        }
コード例 #10
0
        private static BitmapContent ConvertBitmap(BitmapContent source, Type newType, int width, int height)
        {
            BitmapContent content;

            try
            {
                content = (BitmapContent)Activator.CreateInstance(newType, new object[] { width, height });
            }
            catch (TargetInvocationException exception)
            {
                throw new Exception(exception.InnerException.Message);
            }
            BitmapContent.Copy(source, content);
            return(content);
        }
コード例 #11
0
        public void BitmapCopyFullResize()
        {
            var b1 = new PixelBitmapContent <Color>(8, 8);

            Fill(b1, Color.Red);
            var b2 = new PixelBitmapContent <Color>(4, 4);

            BitmapContent.Copy(b1, b2);

            for (var y = 0; y < b2.Height; y++)
            {
                for (var x = 0; x < b2.Width; x++)
                {
                    Assert.AreEqual(Color.Red, b2.GetPixel(x, y));
                }
            }
        }
コード例 #12
0
        public override SpriteFontContent Process(FontDescription 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);
            FieldInfo         TextureField = typeof(SpriteFontContent).GetField("texture", BindingFlags.Instance | BindingFlags.NonPublic);
            Texture2DContent  texture      = (Texture2DContent)TextureField.GetValue(content);

            // 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  = ContentHelper.NextPOT(texture.Faces[0][0].Width);
            var texHeight = ContentHelper.NextPOT(texture.Faces[0][0].Height);

            // Resize to square, power of two if necessary.
            if (texWidth != texHeight || texture.Faces[0][0].Width != texture.Faces[0][0].Height || texWidth != texture.Faces[0][0].Width || texHeight != texture.Faces[0][0].Height)
            {
                texHeight = texWidth = Math.Max(texHeight, texWidth);
                var resizedBitmap = (BitmapContent)Activator.CreateInstance(typeof(PixelBitmapContent <Color>), new object[] { texWidth, texHeight });
                var textureRegion = new Rectangle(0, 0, texture.Faces[0][0].Width, texture.Faces[0][0].Height);
                BitmapContent.Copy(texture.Faces[0][0], textureRegion, resizedBitmap, textureRegion);

                texture.Faces[0].Clear();
                texture.Faces[0].Add(resizedBitmap);

                context.Logger.LogImportantMessage(string.Format("Resized font texture {0} to {1}x{2}", input.Name, resizedBitmap.Width, resizedBitmap.Height));
            }
            else
            {
                texture.ConvertBitmapType(typeof(PixelBitmapContent <Color>));
            }

            MGTextureProcessor.ConvertToPVRTC(texture, 1, true, MGCompressionMode.PVRTCFourBitsPerPixel);

            return(content);
        }
コード例 #13
0
        void BitmapCopyFullNoResize <T>(T color1)
            where T : struct, IEquatable <T>
        {
            var b1 = new PixelBitmapContent <T>(8, 8);

            Fill(b1, color1);
            var b2 = new PixelBitmapContent <T>(8, 8);

            BitmapContent.Copy(b1, b2);

            for (var y = 0; y < b2.Height; y++)
            {
                for (var x = 0; x < b2.Width; x++)
                {
                    Assert.AreEqual(color1, b2.GetPixel(x, y));
                }
            }
        }
コード例 #14
0
        void BitmapCopyFullResize <T>(T color1, IEqualityComparer <T> comparer)
            where T : struct, IEquatable <T>
        {
            var b1 = new PixelBitmapContent <T>(8, 8);

            Fill(b1, color1);
            var b2 = new PixelBitmapContent <T>(4, 4);

            BitmapContent.Copy(b1, b2);

            for (var y = 0; y < b2.Height; y++)
            {
                for (var x = 0; x < b2.Width; x++)
                {
                    Assert.That(color1, Is.EqualTo(b2.GetPixel(x, y)).Using(comparer));
                }
            }
        }
コード例 #15
0
        /// <summary>
        /// The four side faces of the cubemap are easy to create: we just copy
        /// out the appropriate region from the middle of the source bitmap.
        /// </summary>
        static BitmapContent CreateSideFace(PixelBitmapContent <Color> source,
                                            int cubeSide)
        {
            PixelBitmapContent <Color> result;

            result = new PixelBitmapContent <Color>(cubemapSize, cubemapSize);

            Rectangle sourceRegion = new Rectangle(source.Width * cubeSide / 4,
                                                   source.Height / 3,
                                                   source.Width / 4,
                                                   source.Height / 3);

            Rectangle destinationRegion = new Rectangle(0, 0, cubemapSize, cubemapSize);

            BitmapContent.Copy(source, sourceRegion, result, destinationRegion);

            return(result);
        }
コード例 #16
0
        public void BitmapCopyRegionResize()
        {
            var b1 = new PixelBitmapContent <Color>(8, 8);

            Fill(b1, Color.Red);
            var b2 = new PixelBitmapContent <Color>(8, 8);

            Fill(b2, Color.Blue);
            BitmapContent.Copy(b1, new Rectangle(0, 0, 4, 4), b2, new Rectangle(0, 0, 3, 6));

            for (var y = 0; y < b2.Height; y++)
            {
                for (var x = 0; x < b2.Width; x++)
                {
                    Assert.AreEqual(x < 3 && y < 6 ? Color.Red : Color.Blue, b2.GetPixel(x, y));
                }
            }
        }
コード例 #17
0
ファイル: SpritePacker.cs プロジェクト: Babelz/jamipeli
        /// <summary>
        /// Once the arranging is complete, copies the bitmap data for each
        /// sprite to its chosen position in the single larger output bitmap.
        /// </summary>
        static BitmapContent CopySpritesToOutput(List <ArrangedSprite> p_sprites, IList <BitmapContent> p_sourceSprites, ICollection <Rectangle> p_outputSprites, int p_width, int p_height)
        {
            BitmapContent l_output = new PixelBitmapContent <Color>(p_width, p_height);

            foreach (ArrangedSprite l_sprite in p_sprites)
            {
                BitmapContent l_source = p_sourceSprites[l_sprite.Index];

                int l_x = l_sprite.X;
                int l_y = l_sprite.Y;

                int l_width  = l_source.Width;
                int l_height = l_source.Height;

                // Copy the main sprite data to the output sheet.
                BitmapContent.Copy(l_source, new Rectangle(0, 0, l_width, l_height), l_output, new Rectangle(l_x + 1, l_y + 1, l_width, l_height));

                // Copy a border strip from each edge of the sprite, creating
                // a one pixel padding area to avoid filtering problems if the
                // sprite is scaled or rotated.
                BitmapContent.Copy(l_source, new Rectangle(0, 0, 1, l_height), l_output, new Rectangle(l_x, l_y + 1, 1, l_height));

                BitmapContent.Copy(l_source, new Rectangle(l_width - 1, 0, 1, l_height), l_output, new Rectangle(l_x + l_width + 1, l_y + 1, 1, l_height));

                BitmapContent.Copy(l_source, new Rectangle(0, 0, l_width, 1), l_output, new Rectangle(l_x + 1, l_y, l_width, 1));

                BitmapContent.Copy(l_source, new Rectangle(0, l_height - 1, l_width, 1), l_output, new Rectangle(l_x + 1, l_y + l_height + 1, l_width, 1));

                // Copy a single pixel from each corner of the sprite,
                // filling in the corners of the one pixel padding area.
                BitmapContent.Copy(l_source, new Rectangle(0, 0, 1, 1), l_output, new Rectangle(l_x, l_y, 1, 1));

                BitmapContent.Copy(l_source, new Rectangle(l_width - 1, 0, 1, 1), l_output, new Rectangle(l_x + l_width + 1, l_y, 1, 1));

                BitmapContent.Copy(l_source, new Rectangle(0, l_height - 1, 1, 1), l_output, new Rectangle(l_x, l_y + l_height + 1, 1, 1));

                BitmapContent.Copy(l_source, new Rectangle(l_width - 1, l_height - 1, 1, 1), l_output, new Rectangle(l_x + l_width + 1, l_y + l_height + 1, 1, 1));

                // Remember where we placed this sprite.
                p_outputSprites.Add(new Rectangle(l_x + 1, l_y + 1, l_width, l_height));
            }

            return(l_output);
        }
コード例 #18
0
        void BitmapCopyMoveRegionNoResize <T>(T color1, T color2)
            where T : struct, IEquatable <T>
        {
            var b1 = new PixelBitmapContent <T>(8, 8);

            Fill(b1, color1);
            var b2 = new PixelBitmapContent <T>(8, 8);

            Fill(b2, color2);
            BitmapContent.Copy(b1, new Rectangle(0, 0, 4, 4), b2, new Rectangle(4, 4, 4, 4));

            for (var y = 0; y < b2.Height; y++)
            {
                for (var x = 0; x < b2.Width; x++)
                {
                    Assert.AreEqual(x >= 4 && y >= 4 ? color1 : color2, b2.GetPixel(x, y));
                }
            }
        }
コード例 #19
0
        void BitmapCopyRegionResize <T>(T color1, T color2, IEqualityComparer <T> comparer)
            where T : struct, IEquatable <T>
        {
            var b1 = new PixelBitmapContent <T>(8, 8);

            Fill(b1, color1);
            var b2 = new PixelBitmapContent <T>(8, 8);

            Fill(b2, color2);
            BitmapContent.Copy(b1, new Rectangle(0, 0, 4, 4), b2, new Rectangle(0, 0, 3, 6));

            for (var y = 0; y < b2.Height; y++)
            {
                for (var x = 0; x < b2.Width; x++)
                {
                    Assert.That(x < 3 && y < 6 ? color1 : color2, Is.EqualTo(b2.GetPixel(x, y)).Using(comparer));
                }
            }
        }
コード例 #20
0
        public void BitmapConvertFullNoResize()
        {
            var b1 = new PixelBitmapContent <Color>(8, 8);

            Fill(b1, Color.Red);
            var b2 = new PixelBitmapContent <Bgr565>(8, 8);

            BitmapContent.Copy(b1, b2);

            var packed = new Bgr565(1.0f, 0.0f, 0.0f);

            for (var y = 0; y < b2.Height; y++)
            {
                for (var x = 0; x < b2.Width; x++)
                {
                    Assert.AreEqual(packed, b2.GetPixel(x, y));
                }
            }
        }
コード例 #21
0
        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);
        }
コード例 #22
0
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            var face    = input.Faces.First();
            var src     = face[0];
            var columns = src.Width / GridWidth;
            var rows    = src.Height / GridHeight;

            var dst = new PixelBitmapContent <Color>(src.Width + columns * 2, src.Height + rows * 2);

            for (int r = 0; r < rows; r++)
            {
                for (int c = 0; c < columns; c++)
                {
                    var srcRect = new Rectangle
                    {
                        X      = c * GridWidth,
                        Y      = r * GridHeight,
                        Width  = GridWidth,
                        Height = GridHeight
                    };
                    var dstRect = new Rectangle
                    {
                        X      = c * (GridWidth + Padding * 2),
                        Y      = r * (GridHeight + Padding * 2),
                        Width  = (GridWidth + Padding * 2),
                        Height = (GridHeight + Padding * 2)
                    };

                    BitmapContent.Copy(src, srcRect, dst, dstRect);
                    dstRect.Inflate(-Padding, -Padding);
                    BitmapContent.Copy(src, srcRect, dst, dstRect);
                }
            }

            face[0] = dst;
            return(base.Process(input, context));
        }
コード例 #23
0
        /// <summary>
        /// The top and bottom cubemap faces will have a nasty discontinuity
        /// in the middle where the four source image flaps meet. We can cover
        /// this up by applying a blur filter to the problematic area.
        /// </summary>
        static BitmapContent BlurCubemapFace(PixelBitmapContent <Color> source)
        {
            // Create two temporary bitmaps.
            PixelBitmapContent <Vector4> temp1, temp2;

            temp1 = new PixelBitmapContent <Vector4>(cubemapSize, cubemapSize);
            temp2 = new PixelBitmapContent <Vector4>(cubemapSize, cubemapSize);

            // Antialias by shrinking the larger generated image to the final size.
            BitmapContent.Copy(source, temp1);

            // Apply the blur in two passes, first horizontally, then vertically.
            ApplyBlurPass(temp1, temp2, 1, 0);
            ApplyBlurPass(temp2, temp1, 0, 1);

            // Convert the result back to Color format.
            PixelBitmapContent <Color> result;

            result = new PixelBitmapContent <Color>(cubemapSize, cubemapSize);

            BitmapContent.Copy(temp1, result);

            return(result);
        }
コード例 #24
0
        private Texture2DContent CreateContainerTexture(List <KeyValuePair <Texture2DContent, Rectangle> > textures)
        {
            BitmapContent output = new PixelBitmapContent <Color>((int)ContainerSize, (int)ContainerSize);

            foreach (var textureInfo in textures)
            {
                BitmapContent texture = textureInfo.Key.Mipmaps[0];
                int           w       = texture.Width;
                int           h       = texture.Height;

                Rectangle texturePosition = textureInfo.Value;
                int       x = texturePosition.X;
                int       y = texturePosition.Y;

                // Copy the main sprite data to the output sheet
                BitmapContent.Copy(texture, new Rectangle(0, 0, w, h), output, new Rectangle(x + 1, y + 1, w, h));

                // Copy a border strip from each edge of the sprite, creating
                // a one pixel padding area to avoid filtering problems if the
                // sprite is scaled or rotated
                BitmapContent.Copy(texture, new Rectangle(0, 0, 1, h), output, new Rectangle(x, y + 1, 1, h));
                BitmapContent.Copy(texture, new Rectangle(w - 1, 0, 1, h), output, new Rectangle(x + w + 1, y + 1, 1, h));
                BitmapContent.Copy(texture, new Rectangle(0, 0, w, 1), output, new Rectangle(x + 1, y, w, 1));
                BitmapContent.Copy(texture, new Rectangle(0, h - 1, w, 1), output, new Rectangle(x + 1, y + h + 1, w, 1));

                // Copy a single pixel from each corner of the sprite, filling in the corners of the one pixel padding area
                BitmapContent.Copy(texture, new Rectangle(0, 0, 1, 1), output, new Rectangle(x, y, 1, 1));
                BitmapContent.Copy(texture, new Rectangle(w - 1, 0, 1, 1), output, new Rectangle(x + w + 1, y, 1, 1));
                BitmapContent.Copy(texture, new Rectangle(0, h - 1, 1, 1), output, new Rectangle(x, y + h + 1, 1, 1));
                BitmapContent.Copy(texture, new Rectangle(w - 1, h - 1, 1, 1), output, new Rectangle(x + w + 1, y + h + 1, 1, 1));
            }
            Texture2DContent tex2d = new Texture2DContent();

            tex2d.Mipmaps = new MipmapChain(output);
            return(tex2d);
        }
コード例 #25
0
        public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context)
        {
            // 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];

            face.TryGetFormat(out SurfaceFormat faceFormat);
            if (faceFormat != SurfaceFormat.Rgba32)
            {
                var colorFace = new PixelBitmapContent <Color>(face.Width, face.Height);
                BitmapContent.Copy(face, colorFace);
                face = colorFace;
            }

            var output = new SpriteFontContent();
            var glyphs = ExtractGlyphs((PixelBitmapContent <Color>)face);

            // Optimize.
            foreach (var glyph in glyphs)
            {
                GlyphCropper.Crop(glyph);
                output.VerticalLineSpacing = Math.Max(output.VerticalLineSpacing, glyph.Subrect.Height);
            }

            // Get the platform specific texture profile.
            var texProfile = TextureProfile.ForPlatform(context.TargetPlatform);

            texProfile.Requirements(context, TextureFormat, out bool requiresPot, out bool requiresSquare);

            face = GlyphPacker.ArrangeGlyphs(glyphs, requiresPot, requiresSquare);

            foreach (var glyph in glyphs)
            {
                output.CharacterMap.Add(glyph.Character);

                output.Regions.Add(
                    new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height));

                output.Croppings.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);
            }

            // Perform the final texture conversion.
            texProfile.ConvertTexture(context, output.Texture, TextureFormat, true);

            return(output);
        }
コード例 #26
0
        public TextureAtlasContent Process(TextureAtlasContent input, ContentProcessorContext context)
        {
            if (MipmapsPerSprite && GenerateMipmaps)
            {
                foreach (var texture in input.Textures)
                {
                    texture.Texture.GenerateMipmaps(false);
                }
            }

            var output = input;

            if (GenerateMipmaps)
            {
                if (MipmapsPerSprite)
                {
                    var maxSpriteWidth  = 1;
                    var maxSpriteHeight = 1;
                    foreach (var sprite in input.Textures)
                    {
                        var face0 = sprite.Texture.Faces[0];
                        maxSpriteWidth  = Math.Max(maxSpriteWidth, face0[0].Width);
                        maxSpriteHeight = Math.Max(maxSpriteHeight, face0[0].Height);
                    }

                    for (int mipLevel = 1; ; mipLevel++)
                    {
                        int       mipLevel2 = (int)Math.Pow(2, mipLevel);
                        Rectangle size      = new Rectangle(0, 0, input.Width, input.Height);
                        size.Width  /= mipLevel2;
                        size.Height /= mipLevel2;

                        if ((maxSpriteWidth / mipLevel2) < 1 && (maxSpriteHeight / mipLevel2) < 1)
                        {
                            break;
                        }

                        var mipmapBmp = new PixelBitmapContent <Color>(size.Width, size.Height);
                        foreach (var sprite in input.Sprites)
                        {
                            if (mipLevel >= sprite.Texture.Faces[0].Count)
                            {
                                continue;
                            }
                            var srcBmp   = sprite.Texture.Faces[0][mipLevel];
                            var srcRect  = new Rectangle(0, 0, srcBmp.Width, srcBmp.Height);
                            var destRect = sprite.DestinationRectangle;
                            destRect.X      = (int)Math.Ceiling((float)destRect.X / mipLevel2);
                            destRect.Y      = (int)Math.Ceiling((float)destRect.Y / mipLevel2);
                            destRect.Width  = (int)(destRect.Width / mipLevel2);
                            destRect.Height = (int)(destRect.Height / mipLevel2);
                            if (destRect.Width > 1 && destRect.Height > 1)
                            {
                                BitmapContent.Copy(srcBmp, srcRect, mipmapBmp, destRect);
                            }
                        }
                        output.Mipmaps.Add(mipmapBmp);
                    }

                    var outputFace0 = output.Faces[0];
                    while (outputFace0[outputFace0.Count - 1].Width > 1 || outputFace0[outputFace0.Count - 1].Height > 1)
                    {
                        var lastMipmap = outputFace0[outputFace0.Count - 1];
                        var w          = Math.Max(1, lastMipmap.Width / 2);
                        var h          = Math.Max(1, lastMipmap.Height / 2);
                        var mipmapBmp  = new PixelBitmapContent <Color>(w, h);
                        //PixelBitmapContent<Color>.Copy(lastMipmap, mipmapBmp);
                        output.Mipmaps.Add(mipmapBmp);
                    }
                }
                else
                {
                    output.GenerateMipmaps(false);
                }
            }

            base.Process(output, context);

            return(output);
        }
コード例 #27
0
        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);
                }
            }

            // Get the texture profile for the platform and let it convert the texture.
            var texProfile = TextureProfile.ForPlatform(context.TargetPlatform);

            texProfile.ConvertTexture(context, input, TextureFormat, GenerateMipmaps, false);

            return(input);
        }
コード例 #28
0
        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);
        }
コード例 #29
0
        /// <summary>
        /// locates the black pixels from a nine patch image and sets the splits for this image
        /// </summary>
        /// <param name="texture">Texture.</param>
        int[] ProcessNinePatchTexture(TextureContent texture)
        {
            // left, right, top, bottom of nine patch splits
            var splits = new int[4];
            var bitmap = texture.Faces[0][0];
            var data   = bitmap.GetPixelData();

            var padStart = -1;
            var padEnd   = int.MinValue;

            for (var x = 0; x < bitmap.Width * 4; x += 4)
            {
                // we only care about alpha so disregard r/g/b
                var alpha = data[x + 3];
                if (alpha == 255)
                {
                    if (padStart == -1)
                    {
                        padStart = x / 4;
                    }
                    else
                    {
                        padEnd = Math.Max(padEnd, x / 4);
                    }
                }
            }

            splits[0] = padStart;
            splits[1] = bitmap.Width - padEnd;


            padStart = -1;
            padEnd   = int.MinValue;
            var rowStride = bitmap.Width * 4;

            for (var y = 0; y < bitmap.Height * 4; y += 4)
            {
                var pixel = (y / 4) * rowStride;

                // we only care about alpha so disregard r/g/b
                var alpha = data[pixel + 3];
                if (alpha == 255)
                {
                    if (padStart == -1)
                    {
                        padStart = y / 4;
                    }
                    else
                    {
                        padEnd = Math.Max(padEnd, y / 4);
                    }
                }
            }

            splits[2] = padStart;
            splits[3] = bitmap.Height - padEnd;

            Logger.LogMessage("\tnine patch details. l: {0}, r: {1}, t: {2}, b: {3}", splits[0], splits[1], splits[2],
                              splits[3]);

            // copy the data to a new Bitmap excluding the outside 1 pixel border
            var output = new PixelBitmapContent <Color>(bitmap.Width - 2, bitmap.Height - 2);

            BitmapContent.Copy(bitmap, new Rectangle(1, 1, output.Width, output.Height), output,
                               new Rectangle(0, 0, output.Width, output.Height));
            texture.Faces[0][0] = output;

            return(splits);
        }
コード例 #30
0
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            if (input.Faces[0][0].TryGetFormat(out SurfaceFormat 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 || GenerateMipmaps)
            {
                // 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 <RgbaVector>));
                }
                catch (Exception ex)
                {
                    context.Logger.LogImportantMessage("Could not convert input texture for processing. " + ex.ToString());
                    throw;
                }

                if (GenerateMipmaps)
                {
                    input.GenerateMipmaps(true);
                }

                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 <RgbaVector>)face[m];

                        if (ColorKeyEnabled)
                        {
                            var original = new RgbaVector(); // TODO: UNsafe.SkipInit
                            original.FromScaledVector(ColorKeyColor.ToScaledVector4());
                            bmp.ReplaceColor(original, new RgbaVector(0, 0, 0, 0));
                        }

                        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 <RgbaVector>(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 <RgbaVector>(newSize, newSize);
                            BitmapContent.Copy(bmp, resized);
                        }

                        if (PremultiplyAlpha)
                        {
                            var pixels = bmp.GetPixelSpan();
                            for (int i = 0; i < pixels.Length; i++)
                            {
                                ref RgbaVector pixel = ref pixels[i];
                                pixel.R *= pixel.A;
                                pixel.G *= pixel.A;
                                pixel.B *= pixel.A;
                            }
                        }

                        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);
                }
            }