Ejemplo n.º 1
0
        /// <summary>
        /// This function encodes a new texture based on the list of key frame matrices
        /// </summary>
        /// <param name="keyFrameMatrices"></param>
        /// <returns></returns>
        static private PixelBitmapContent <Vector4> GetEncodedTexture(List <Matrix[]> keyFrameMatrices, int bones)
        {
            //We need 4 pixels per bone. We can store each row of the transform matrix in one pixel.
            int width = bones * 4;

            //Create a new bitmap content object
            PixelBitmapContent <Vector4> animationTexture = new PixelBitmapContent <Vector4>(width, keyFrameMatrices.Count);

            int y = 0;

            //Now, we'll write all the rows
            foreach (Matrix[] animationRow in keyFrameMatrices)
            {
                int x = 0;
                foreach (Matrix transform in animationRow)
                {
                    // Pretty trivial - we just right out the matrix data as pixels. Instead of R, G, B, and A, we write matrix values.

                    // However, as mentioned in the article, this could be optimized. We really only need 3 pixels to describe a matrix,
                    // because in a transform matrix, the fourth row is always (0, 0, 0, 1). Thus, we could use the RGB values to describe the 3x3
                    // matrix, and then use the A values to describe the translation values in the 4th column. During runtime, this would save
                    // us a vertex texture fetch per transform!

                    animationTexture.SetPixel(x + 0, y, new Vector4(transform.M11, transform.M12, transform.M13, transform.M14));
                    animationTexture.SetPixel(x + 1, y, new Vector4(transform.M21, transform.M22, transform.M23, transform.M24));
                    animationTexture.SetPixel(x + 2, y, new Vector4(transform.M31, transform.M32, transform.M33, transform.M34));
                    animationTexture.SetPixel(x + 3, y, new Vector4(transform.M41, transform.M42, transform.M43, transform.M44));
                    x += 4;
                }

                y++;
            }

            return(animationTexture);
        }
Ejemplo n.º 2
0
        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>
        /// Applies a single pass of a separable box filter, blurring either
        /// along the x or y axis. This could give much higher quality results
        /// if we used a gaussian filter kernel rather than this simplistic box,
        /// but this is good enough to get the job done.
        /// </summary>
        static void ApplyBlurPass(PixelBitmapContent <Vector4> source,
                                  PixelBitmapContent <Vector4> destination,
                                  int dx, int dy)
        {
            int cubemapCenter = cubemapSize / 2;

            for (int y = 0; y < cubemapSize; y++)
            {
                for (int x = 0; x < cubemapSize; x++)
                {
                    // How far is this texel from the center of the image?
                    int xDist = cubemapCenter - x;
                    int yDist = cubemapCenter - y;

                    int distance = (int)Math.Sqrt(xDist * xDist + yDist * yDist);

                    // Blur more in the center, less near the edges.
                    int blurAmount = Math.Max(cubemapCenter - distance, 0) / 8;

                    // Accumulate source texel values.
                    Vector4 blurredValue = Vector4.Zero;

                    for (int i = -blurAmount; i <= blurAmount; i++)
                    {
                        blurredValue += source.GetPixel(x + dx * i, y + dy * i);
                    }

                    // Average them to calculate a blurred result.
                    blurredValue /= blurAmount * 2 + 1;

                    destination.SetPixel(x, y, blurredValue);
                }
            }
        }
Ejemplo n.º 4
0
        public override TOutput Process(TInput input, ContentProcessorContext context)
        {
            input.ConvertBitmapType(typeof(PixelBitmapContent <Vector4>));
            PixelBitmapContent <Vector4> bm = (PixelBitmapContent <Vector4>)(((Texture2DContent)input).Mipmaps[0]);

            for (int y = 0, ym = bm.Height; y != ym; ++y)
            {
                for (int x = 0, xm = bm.Width; x != xm; ++x)
                {
                    Vector4 v = bm.GetPixel(x, y);
                    float   w = 1 - v.W;
                    if (v.Z > w)
                    {
                        v.Z = w;
                    }
                    w -= v.Z;
                    if (v.Y > w)
                    {
                        v.Y = w;
                    }
                    w -= v.Y;
                    if (v.X > w)
                    {
                        v.X = w;
                    }
                    System.Diagnostics.Debug.Assert(v.X + v.Y + v.Z + v.W <= 1.001f);
                    //  it's OK for w to be > 0 here, as that means the base layer weight
                    bm.SetPixel(x, y, v);
                }
            }
            input.ConvertBitmapType(typeof(PixelBitmapContent <Color>));
            input.GenerateMipmaps(true);
            return(input);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 指定された単色ビットマップ画像をDXT3テクスチャへ変換する
        /// </summary>
        /// <param name="source">変換元画像</param>
        /// <param name="color0">単色カラー</param>
        /// <returns>DXT3圧縮された画像</returns>
        public static Dxt3BitmapContent Compress(PixelBitmapContent<Color> source,
                                                    Color color0)
        {
            // DXT3ブロックデータを格納するためのバッファを確保
            byte[] outputData = new byte[source.Width * source.Height];

            // 単色カラーをBGR565に変換する
            ushort packedColor = new Bgr565(color0.ToVector3()).PackedValue;

            // 指定された画像を圧縮ブロック単位に処理をする
            int outputIndex = 0;
            for (int blockY = 0; blockY < source.Height; blockY += 4)
            {
                for (int blockX = 0; blockX < source.Width; blockX += 4)
                {
                    CompressDxt3Block(source, blockX, blockY, packedColor,
                                        outputData, outputIndex);
                    outputIndex += 16;
                }
            }

            // DXT3テクスチャの生成と圧縮したブロックデータの設定
            var result = new Dxt3BitmapContent(source.Width, source.Height);
            result.SetPixelData(outputData);

            return result;
        }
Ejemplo n.º 6
0
        protected string BuildTexture(Color color, IDictionary <string, object> processorParameters = null)
        {
            PixelBitmapContent <Color> bitmap = new PixelBitmapContent <Color>(1, 1);

            bitmap.SetPixel(0, 0, color);
            return(BuildTexture(bitmap, processorParameters));
        }
        /// <summary>
        /// 指定された単色ビットマップ画像をDXT3テクスチャへ変換する
        /// </summary>
        /// <param name="source">変換元画像</param>
        /// <param name="color0">単色カラー</param>
        /// <returns>DXT3圧縮された画像</returns>
        public static Dxt3BitmapContent Compress(PixelBitmapContent <Color> source,
                                                 Color color0)
        {
            // DXT3ブロックデータを格納するためのバッファを確保
            byte[] outputData = new byte[source.Width * source.Height];

            // 単色カラーをBGR565に変換する
            ushort packedColor = new Bgr565(color0.ToVector3()).PackedValue;

            // 指定された画像を圧縮ブロック単位に処理をする
            int outputIndex = 0;

            for (int blockY = 0; blockY < source.Height; blockY += 4)
            {
                for (int blockX = 0; blockX < source.Width; blockX += 4)
                {
                    CompressDxt3Block(source, blockX, blockY, packedColor,
                                      outputData, outputIndex);
                    outputIndex += 16;
                }
            }

            // DXT3テクスチャの生成と圧縮したブロックデータの設定
            var result = new Dxt3BitmapContent(source.Width, source.Height);

            result.SetPixelData(outputData);

            return(result);
        }
Ejemplo n.º 8
0
        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");
        }
Ejemplo n.º 9
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]);
        }
Ejemplo n.º 10
0
        public override Texture2DContent Import(string filename, ContentImporterContext context)
        {
            // Load Arena2Path.txt
            arena2Path = File.ReadAllText(
                Path.Combine(Path.GetDirectoryName(filename), Arena2PathTxt));

            // Read input text
            string input = File.ReadAllText(filename);

            // Remove new lines
            input = input.Replace('\n', ' ').Trim();
            input = input.Replace('\r', ' ').Trim();

            // Get source information
            string[] lines           = input.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            string   textureFilename = lines[0].Trim();
            int      record          = Convert.ToInt32(lines[1].Trim());
            int      frame           = Convert.ToInt32(lines[2].Trim());

            // Get bitmap in RGBA format
            ImageFileReader fileReader = new ImageFileReader(arena2Path);
            DFImageFile     imageFile  = fileReader.LoadFile(textureFilename);
            DFBitmap        dfBitmap   = imageFile.GetBitmapFormat(record, frame, 0, DFBitmap.Formats.RGBA);

            // Set bitmap data
            BitmapContent bitmapContent = new PixelBitmapContent <Color>(dfBitmap.Width, dfBitmap.Height);

            bitmapContent.SetPixelData(dfBitmap.Data);
            Texture2DContent tc = new Texture2DContent();

            tc.Faces[0] = bitmapContent;

            return(tc);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Using height data stored in the alpha channel, computes normalmap
        /// vectors and stores them in the RGB portion of the bitmap.
        /// </summary>
        static void ConvertAlphaToNormals(PixelBitmapContent <Vector4> bitmap)
        {
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    // Look up the heights to either side of this pixel.
                    float left  = GetHeight(bitmap, x - 1, y);
                    float right = GetHeight(bitmap, x + 1, y);

                    float top    = GetHeight(bitmap, x, y - 1);
                    float bottom = GetHeight(bitmap, x, y + 1);

                    // Compute gradient vectors, then cross them to get the normal.
                    Vector3 dx = new Vector3(1, 0, (right - left) * bumpSize);
                    Vector3 dy = new Vector3(0, 1, (bottom - top) * bumpSize);

                    Vector3 normal = Vector3.Cross(dx, dy);

                    normal.Normalize();

                    // Store the result.
                    float alpha = GetHeight(bitmap, x, y);

                    bitmap.SetPixel(x, y, new Vector4(normal, alpha));
                }
            }
        }
Ejemplo n.º 12
0
        /// <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);
        }
Ejemplo n.º 13
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);
 }
Ejemplo n.º 14
0
        static PixelBitmapContent <Color> CreateAlphaChannel(PixelBitmapContent <Color> input)
        {
            int width  = input.Width;
            int height = input.Height;

            PixelBitmapContent <Color> result = new PixelBitmapContent <Color>(width, height);

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    Color color = input.GetPixel(x, y);

                    // Adds/Replaces Alpha channel with the "Brightest color channel value
                    // A better way would be to average all three colors and use that for alpha.
                    // This will work just fine for grey scale textures and is simpler...
                    byte resultAlpha1 = (byte)(color.PackedValue & 0xff);
                    byte resultAlpha2 = (byte)(color.PackedValue & 0xff00);
                    byte resultAlpha3 = (byte)(color.PackedValue & 0xff0000);

                    byte resultAlpha = Math.Max(Math.Max(resultAlpha1, resultAlpha2), resultAlpha3);
                    color.PackedValue = (uint)(resultAlpha << 24) + (0x00ffffff);

                    result.SetPixel(x, y, color);
                }
            }

            return(result);
        }
Ejemplo n.º 15
0
        public override Vertices Process(Texture2DContent input, ContentProcessorContext context)
        {
            if (ScaleFactor < 1)
            {
                throw new Exception("Pixel to meter ratio must be greater than zero.");
            }

            PixelBitmapContent <Color> bitmapContent = (PixelBitmapContent <Color>)input.Faces[0][0];

            uint[] colorData = new uint[bitmapContent.Width * bitmapContent.Height];
            for (int i = 0; i < bitmapContent.Height; i++)
            {
                for (int j = 0; j < bitmapContent.Width; j++)
                {
                    Color c = bitmapContent.GetPixel(j, i);
                    c.R *= c.A;
                    c.G *= c.A;
                    c.B *= c.A;
                    colorData[i * bitmapContent.Width + j] = c.PackedValue;
                }
            }

            Vertices outline = PolygonUtils.CreatePolygon(colorData, bitmapContent.Width, HoleDetection);

            Vector2 centroid = -outline.GetCentroid();

            outline.Translate(ref centroid);

            Vector2 scale = new Vector2(_scaleFactor);

            outline.Scale(ref scale);

            return(outline);
        }
Ejemplo n.º 16
0
        /// <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);
        }
        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);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Generates a terrain mesh from an input heightfield texture.
        /// </summary>
        public override TerrainModelContent Process(Texture2DContent input,
                                                    ContentProcessorContext context)
        {
            Texture2DContent texture = context.Convert <Texture2DContent, Texture2DContent>(input, "FloatingPointTextureProcessor");

            PixelBitmapContent <float> heightfield = (PixelBitmapContent <float>)texture.Mipmaps[0];

            float[,] heights = new float[heightfield.Width, heightfield.Height];
            for (int y = 0; y < heightfield.Height; y++)
            {
                for (int x = 0; x < heightfield.Width; x++)
                {
                    heights[x, y] = heightfield.GetPixel(x, y);
                }
            }

            HeightMapContent heightMap = new HeightMapContent(heightfield.Width, heightfield.Height, heights, VerticalScale, HorizontalScale);

            string directory = Path.GetDirectoryName(input.Identity.SourceFilename);
            string texture1  = Path.Combine(directory, ColorTexture);
            string texture2  = Path.Combine(directory, DetailTexture);

            // Create a material, and point it at our terrain texture.
            DualTextureMaterialContent material = new DualTextureMaterialContent
            {
                Texture  = context.BuildAsset <TextureContent, TextureContent>(new ExternalReference <TextureContent>(texture1), null),
                Texture2 = context.BuildAsset <TextureContent, TextureContent>(new ExternalReference <TextureContent>(texture2), null),
            };

            TerrainModelContentBuilder terrainModelContentBuilder = new TerrainModelContentBuilder(PatchSize, Tau, heightMap, material, DetailTextureTiling, HorizontalScale);

            return(terrainModelContentBuilder.Build(context));
        }
Ejemplo n.º 19
0
        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);
        }
Ejemplo n.º 20
0
 protected virtual void BuildNormalMap(PixelBitmapContent <Single> bm, PixelBitmapContent <Color> n)
 {
     unchecked
     {
         int ww = n.Width;
         int hh = n.Height;
         for (int y = 0; y < hh; ++y)
         {
             for (int x = 0; x < ww; ++x)
             {
                 float v00 = bm.GetPixel(x, y);
                 float v01 = bm.GetPixel(x, y + 1);
                 float v10 = bm.GetPixel(x + 1, y);
                 float v11 = bm.GetPixel(x + 1, y + 1);
                 //  80 meters up/down for the renderer
                 //  two dx-es means divide by 2 (to average)
                 //  two meters per triangle side means divide by 2 to normalize to meters
                 //  That is crappy resolution. I should probably use floats instead of bytes
                 //  for the underlying storage pixmap...
                 float   ddx = (v10 + v11 - v00 - v01) * Page.DynamicRange * 0.5f * 0.5f;
                 float   ddy = (v01 + v11 - v00 - v10) * Page.DynamicRange * 0.5f * 0.5f;
                 Vector3 v   = new Vector3(-ddx, -ddy, 1.0f);
                 v.Normalize();
                 v = v * 0.5f + new Vector3(0.5f, 0.5f, 0.5f);
                 Color c = new Color(v);
                 n.SetPixel(x, y, c);
             }
         }
     }
 }
Ejemplo n.º 21
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);
        }
        /// <summary>
        /// Flattens vectors from a normal map into a 2D displacement map
        /// and stores them in the RG portion of the bitmap.
        /// </summary>
        public static void ConvertNormalsToDisplacement(
            PixelBitmapContent <NormalizedByte4> bitmap, float distortionScale)
        {
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    // Get the normal from the normal map
                    Vector4 normal4 = bitmap.GetPixel(x, y).ToVector4();
                    Vector3 normal3 = new Vector3(normal4.X, normal4.Y, normal4.Z);

                    // Determine the magnitude of the distortion at this pixel
                    float amount = Vector3.Dot(normal3, Vector3.Backward) *
                                   distortionScale;

                    // Create a displacement vector of that magnitude in the direction
                    // of the normal projected onto the plane of the texture.
                    Vector2 normal2      = new Vector2(normal3.X, normal3.Y);
                    Vector2 displacement = normal2 * amount + new Vector2(.5f, .5f);

                    // Store the result
                    bitmap.SetPixel(x, y,
                                    new NormalizedByte4(displacement.X, displacement.Y, 0, 0));
                }
            }
        }
Ejemplo n.º 23
0
        unsafe private static BitmapContent ConvertToColor(BitmapContent input)
        {
            var width  = input.Width;
            var height = input.Height;

            SurfaceFormat format;

            input.TryGetFormat(out format);
            var formatSize = DDSImporter.GetBitmapSize(format, width, height);
            var blocks     = formatSize;
            var inData     = input.GetPixelData();

            var output = new PixelBitmapContent <Color>(width, height);

            fixed(byte *p = &inData[0])
            {
                DXT1Block *block = (DXT1Block *)p;

                //convert DXT1 to color
                for (int y = 0; y < height; ++y)
                {
                    for (int x = 0; x < width; ++x)
                    {
                        int blockIdx   = (x / 4) + (y / 4) * (width / 4);
                        int colorIndex = x % 4 + (y % 4) * 4;

                        Color color = block[blockIdx].GetColor(colorIndex);
                        output.SetPixel(x, y, color);
                    }
                }
            }

            return(output);
        }
Ejemplo n.º 24
0
        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);
        }
Ejemplo n.º 25
0
 private static void Fill(PixelBitmapContent<Color> content, Color color)
 {
     var src = Enumerable.Repeat(color.PackedValue, content.Width * content.Height).ToArray();
     var dest = new byte[Marshal.SizeOf(typeof(Color)) * content.Width * content.Height];
     Buffer.BlockCopy(src, 0, dest, 0, dest.Length);
     content.SetPixelData(dest);
 }
Ejemplo n.º 26
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);
        }
Ejemplo n.º 27
0
        static void Fill <T>(PixelBitmapContent <T> content, T color)
            where T : struct, IEquatable <T>
        {
            var src  = Enumerable.Repeat(color, content.Width * content.Height).ToArray();
            var dest = ToByteArray(src);

            content.SetPixelData(dest);
        }
Ejemplo n.º 28
0
 private bool IsNullTileSafe(PixelBitmapContent <Color> bitmap, int x, int y)
 {
     if (IsNotInBitmap(bitmap, x, y))
     {
         return(true);
     }
     return(IsNullTile(bitmap, x, y));
 }
Ejemplo n.º 29
0
        private static void Fill(PixelBitmapContent <Color> content, Color color)
        {
            var src  = Enumerable.Repeat(color.PackedValue, content.Width * content.Height).ToArray();
            var dest = new byte[Marshal.SizeOf(typeof(Color)) * content.Width * content.Height];

            Buffer.BlockCopy(src, 0, dest, 0, dest.Length);
            content.SetPixelData(dest);
        }
Ejemplo n.º 30
0
        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);
            }
        }
Ejemplo n.º 31
0
        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);
        }
Ejemplo n.º 32
0
		protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            SurfaceFormat sourceFormat;
            if (!sourceBitmap.TryGetFormat(out sourceFormat))
                return false;

            SurfaceFormat format;
            TryGetFormat(out format);

            // A shortcut for copying the entire bitmap to another bitmap of the same type and format
            if (format == sourceFormat && (sourceRegion == new Rectangle(0, 0, Width, Height)) && sourceRegion == destinationRegion)
            {
                SetPixelData(sourceBitmap.GetPixelData());
                return true;
            }

            // Destination region copy is not yet supported
            if (destinationRegion != new Rectangle(0, 0, Width, Height))
                return false;

            // If the source is not Vector4 or requires resizing, send it through BitmapContent.Copy
            if (!(sourceBitmap is PixelBitmapContent<Vector4>) || sourceRegion.Width != destinationRegion.Width || sourceRegion.Height != destinationRegion.Height)
            {
                try
                {
                    BitmapContent.Copy(sourceBitmap, sourceRegion, this, destinationRegion);
                    return true;
                }
                catch (InvalidOperationException)
                {
                    return false;
                }
            }

            // Convert to full colour 32-bit format. Floating point would be preferred for processing, but it appears the ATICompressor does not support this
            var colorBitmap = new PixelBitmapContent<Color>(sourceRegion.Width, sourceRegion.Height);
            BitmapContent.Copy(sourceBitmap, sourceRegion, colorBitmap, new Rectangle(0, 0, colorBitmap.Width, colorBitmap.Height));
            sourceBitmap = colorBitmap;

			ATICompressor.CompressionFormat targetFormat;
			switch (format)
            {
				case SurfaceFormat.RgbaAtcExplicitAlpha:
					targetFormat = ATICompressor.CompressionFormat.AtcRgbaExplicitAlpha;
					break;
				case SurfaceFormat.RgbaAtcInterpolatedAlpha:
					targetFormat = ATICompressor.CompressionFormat.AtcRgbaInterpolatedAlpha;
					break;
				default:
					return false;
			}

			var sourceData = sourceBitmap.GetPixelData();
			var compressedData = ATICompressor.Compress(sourceData, Width, Height, targetFormat);
			SetPixelData(compressedData);

			return true;
        }
Ejemplo n.º 33
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);
        }
Ejemplo n.º 34
0
        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;
                }
            }
        }
Ejemplo n.º 35
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);
        }
Ejemplo n.º 36
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));
        }
Ejemplo n.º 37
0
        public void BitmapCopySameRegionNoResize()
        {
            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, 4, 4));

            for (var y = 0; y < b2.Height; y++)
                for (var x = 0; x < b2.Width; x++)
                    Assert.AreEqual(x < 4 && y < 4 ? Color.Red : Color.Blue, b2.GetPixel(x, y));
        }
Ejemplo n.º 38
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));
        }
Ejemplo n.º 39
0
        public CubeHeightmapContent(PixelBitmapContent<float> bitmap, float unitScale, int blockScale, int altitudeScale)
        {
            scale = unitScale * (float) blockScale;
            var xLength = bitmap.Width;
            var zLength = bitmap.Height;
            heights = new float[xLength, zLength];
            for (int z = 0; z < zLength; z++)
            {
                for (int x = 0; x < xLength; x++)
                {
                    //Heights[x, z] = altitudeScale * (spriteBitmap.GetPixel(x, z) - 1);

                    int y = (int) (bitmap.GetPixel(x, z) * (float) altitudeScale);
                    Heights[x, z] = y * Scale;
                }
            }
        }
Ejemplo n.º 40
0
        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;
            }
        }
Ejemplo n.º 41
0
		// Once arranging is complete, copies each glyph to its chosen position in the single larger output bitmap.
		static BitmapContent CopyGlyphsToOutput(List<ArrangedGlyph> glyphs, int width, int height)
		{
            var output = new PixelBitmapContent<Color>(width, height);

			foreach (var glyph in glyphs)
			{
				var sourceGlyph = glyph.Source;
				var sourceRegion = sourceGlyph.Subrect;
				var destinationRegion = new Rectangle(glyph.X + 1, glyph.Y + 1, sourceRegion.Width, sourceRegion.Height);

				BitmapContent.Copy(sourceGlyph.Bitmap, sourceRegion, output, destinationRegion);

				// TODO: This causes artifacts around borders.
				//BitmapUtils.PadBorderPixels(output, destinationRegion);

				sourceGlyph.Bitmap = output;
				sourceGlyph.Subrect = destinationRegion;
			}

			return output;
		}
Ejemplo n.º 42
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 PixelBitmapContent<Color> copySpritesToOutput( List<ArrangedSprite> sprites, IList<BitmapContent> sourceSprites,
		                                               ICollection<Rectangle> outputSprites, int width, int height )
		{
			var output = new PixelBitmapContent<Color>( width, height );

			foreach( var sprite in sprites )
			{
				var source = sourceSprites[sprite.index];

				var x = sprite.x;
				var y = sprite.y;

				var w = source.Width;
				var 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;
		}
Ejemplo n.º 43
0
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            input.ConvertBitmapType(typeof(PixelBitmapContent<Color>));
            foreach (var mipmapChain in input.Faces)
            {
                for (int i = 0; i < mipmapChain.Count; i++)
                {
                    var bitmap = mipmapChain[i] as PixelBitmapContent<Color>;

                    int newWidth = (int) ((float) bitmap.Width * Scale);
                    int newHeight = (int) ((float) bitmap.Height * Scale);

                    var newBitmap = new PixelBitmapContent<Color>(newWidth, newHeight);

                    for (int y = 0; y < bitmap.Height; y++)
                    {
                        for (int x = 0; x < bitmap.Width; x++)
                        {
                            for (int scaleY = 0; scaleY < Scale; scaleY++)
                            {
                                for (int scaleX = 0; scaleX < Scale; scaleX++)
                                {
                                    newBitmap.SetPixel(
                                        (int) (x * Scale) + scaleX,
                                        (int) (y * Scale) + scaleY,
                                        bitmap.GetPixel(x, y));
                                }
                            }
                        }
                    }

                    mipmapChain[i] = newBitmap;
                }
            }

            return base.Process(input, context);
        }
Ejemplo n.º 44
0
        internal static BitmapContent Resize(this BitmapContent bitmap, int newWidth, int newHeight)
        {
            BitmapContent src = bitmap;
            SurfaceFormat format;
            src.TryGetFormat(out format);
            if (format != SurfaceFormat.Vector4)
            {
                var v4 = new PixelBitmapContent<Vector4>(src.Width, src.Height);
                BitmapContent.Copy(src, v4);
                src = v4;
            }

            // Convert to FreeImage bitmap
            var bytes = src.GetPixelData();
            var fi = FreeImage.ConvertFromRawBits(bytes, FREE_IMAGE_TYPE.FIT_RGBAF, src.Width, src.Height, SurfaceFormat.Vector4.GetSize() * src.Width, 128, 0, 0, 0, true);

            // Resize
            var newfi = FreeImage.Rescale(fi, newWidth, newHeight, FREE_IMAGE_FILTER.FILTER_BICUBIC);
            FreeImage.UnloadEx(ref fi);

            // Convert back to PixelBitmapContent<Vector4>
            src = new PixelBitmapContent<Vector4>(newWidth, newHeight);
            bytes = new byte[SurfaceFormat.Vector4.GetSize() * newWidth * newHeight];
            FreeImage.ConvertToRawBits(bytes, newfi, SurfaceFormat.Vector4.GetSize() * newWidth, 128, 0, 0, 0, true);
            src.SetPixelData(bytes);
            FreeImage.UnloadEx(ref newfi);
            // Convert back to source type if required
            if (format != SurfaceFormat.Vector4)
            {
                var s = (BitmapContent)Activator.CreateInstance(bitmap.GetType(), new object[] { newWidth, newHeight });
                BitmapContent.Copy(src, s);
                src = s;
            }

            return src;
        }
        /// <summary>
        /// Converts a DigitalRune <see cref="Image"/> to an XNA <see cref="BitmapContent"/>.
        /// </summary>
        /// <param name="image">The <see cref="Image"/>.</param>
        /// <returns>The <see cref="BitmapContent"/>.</returns>
        public static BitmapContent ToContent(Image image)
        {
            BitmapContent content;
              switch (image.Format)
              {
            case DataFormat.R8G8B8A8_UNORM:
            case DataFormat.R8G8B8A8_UNORM_SRGB:
              content = new PixelBitmapContent<Color>(image.Width, image.Height);
              break;
            case DataFormat.B5G6R5_UNORM:
              content = new PixelBitmapContent<Bgr565>(image.Width, image.Height);
              break;
            #if !MONOGAME
            case DataFormat.B5G5R5A1_UNORM:
              content = new PixelBitmapContent<Bgra5551>(image.Width, image.Height);
              break;
            #endif
            case DataFormat.B4G4R4A4_UNORM:
              content = new PixelBitmapContent<Bgra4444>(image.Width, image.Height);
              break;
            case DataFormat.BC1_UNORM:
            case DataFormat.BC1_UNORM_SRGB:
              content = new Dxt1BitmapContent(image.Width, image.Height);
              break;
            case DataFormat.BC2_UNORM:
            case DataFormat.BC2_UNORM_SRGB:
              content = new Dxt3BitmapContent(image.Width, image.Height);
              break;
            case DataFormat.BC3_UNORM:
            case DataFormat.BC3_UNORM_SRGB:
            content = new Dxt5BitmapContent(image.Width, image.Height);
            break;
            case DataFormat.R8G8_SNORM:
            content = new PixelBitmapContent<NormalizedByte2>(image.Width, image.Height);
            break;
            case DataFormat.R8G8B8A8_SNORM:
            content = new PixelBitmapContent<NormalizedByte4>(image.Width, image.Height);
            break;
            #if !MONOGAME
            case DataFormat.R10G10B10A2_UNORM:
              content = new PixelBitmapContent<Rgba1010102>(image.Width, image.Height);
              break;
            case DataFormat.R16G16_UNORM:
              content = new PixelBitmapContent<Rg32>(image.Width, image.Height);
              break;
            case DataFormat.R16G16B16A16_UNORM:
              content = new PixelBitmapContent<Rgba64>(image.Width, image.Height);
              break;
            case DataFormat.A8_UNORM:
            case DataFormat.R8_UNORM:
              content = new PixelBitmapContent<Alpha8>(image.Width, image.Height);
              break;
            #endif
            case DataFormat.R32_FLOAT:
            content = new PixelBitmapContent<float>(image.Width, image.Height);
            break;
            case DataFormat.R32G32_FLOAT:
            content = new PixelBitmapContent<Vector2>(image.Width, image.Height);
            break;
            case DataFormat.R32G32B32A32_FLOAT:
            content = new PixelBitmapContent<Vector4>(image.Width, image.Height);
            break;
            case DataFormat.R16_FLOAT:
            content = new PixelBitmapContent<HalfSingle>(image.Width, image.Height);
            break;
            case DataFormat.R16G16_FLOAT:
            content = new PixelBitmapContent<HalfVector2>(image.Width, image.Height);
            break;
            case DataFormat.R16G16B16A16_FLOAT:
            content = new PixelBitmapContent<HalfVector4>(image.Width, image.Height);
            break;
            #if MONOGAME
            case DataFormat.PVRTCI_2bpp_RGB:
            content = new PvrtcRgb2BitmapContent(image.Width, image.Height);
            break;
            case DataFormat.PVRTCI_4bpp_RGB:
            content = new PvrtcRgb4BitmapContent(image.Width, image.Height);
            break;
            case DataFormat.PVRTCI_2bpp_RGBA:
            content = new PvrtcRgba2BitmapContent(image.Width, image.Height);
            break;
            case DataFormat.PVRTCI_4bpp_RGBA:
            content = new PvrtcRgba4BitmapContent(image.Width, image.Height);
            break;

            case DataFormat.ETC1:
            content = new Etc1BitmapContent(image.Width, image.Height);
            break;

            //case DataFormat.ATC_RGB: Not supported in MonoGame.
            case DataFormat.ATC_RGBA_EXPLICIT_ALPHA:
            content = new AtcExplicitBitmapContent(image.Width, image.Height);
            break;
            case DataFormat.ATC_RGBA_INTERPOLATED_ALPHA:
            content = new AtcInterpolatedBitmapContent(image.Width, image.Height);
            break;
            #endif

            default:
              string message = string.Format("The texture format {0} is not supported in MonoGame.", image.Format);
              throw new NotSupportedException(message);

            // Not supported:
            //  SurfaceFormat.HdrBlendable  // Only needed as render target format.
            //  SurfaceFormat.Bgr32         // Only used as WPF render target.
            //  SurfaceFormat.Bgra32        // Only used as WPF render target.
            //  SurfaceFormat.Dxt1a
              }

              Debug.Assert(content != null);
            #if !MONOGAME
              // content.GetPixelData() is null in MonoGame.
              Debug.Assert(image.Data.Length == content.GetPixelData().Length);
            #endif

              content.SetPixelData(image.Data);
              return content;
        }
Ejemplo n.º 46
0
        /// <summary>
        /// 圧縮ブロックの処理
        /// </summary>
        /// <param name="source">元画像</param>
        /// <param name="blockX">Xブロック位置</param>
        /// <param name="blockY">Yブロック位置</param>
        /// <param name="color0">単色カラー</param>
        /// <param name="outputData">出力先</param>
        /// <param name="outputIndex">出力オフセット</param>
        private static void CompressDxt3Block(PixelBitmapContent<Color> source,
            int blockX, int blockY, ushort color0, byte[] outputData, int outputIndex)
        {
            long alphaBits = 0;
            int rgbBits = 0;
            int pixelCount = 0;

            // 4x4ブロック内の処理
            for (int y = 0; y < 4; ++y)
            {
                for (int x = 0; x < 4; ++x)
                {
                    // 元のアルファ値の取得
                    int value = source.GetPixel(blockX + x, blockY + y).A;
                    int alpha = 0;
                    int rgb = 0;

                    // アルファ値によって、出力値を決定。
                    // ここでは単純にアルファ値領域を4分割するのではなく、6分割にして
                    // 1/6、1/2、5/6の非線形の閾値を使っている
                    if (value < 256 / 6)
                    {
                        alpha = 0;
                        rgb = 1;    // c1色 = 0
                    }
                    else if (value < 256 * 3 / 6)
                    {
                        alpha = 5;
                        rgb = 3;    // c3色 = 1/3(c0) + 2/3(c1) = 85
                    }
                    else if (value < 256 * 5 / 6)
                    {
                        alpha = 10;
                        rgb = 2;    // c2色 = 1/2(c0) + 1/2(c1) = 127
                    }
                    else
                    {
                        alpha = 15;
                        rgb = 0;    // c0色 = 255
                    }

                    // 計算結果ビットを格納
                    alphaBits |= (long)alpha << (pixelCount * 4);
                    rgbBits |= rgb << (pixelCount * 2);

                    pixelCount++;
                }
            }

            // DXT3ブロック情報の出力

            // アルファ 8バイト
            for (int i = 0; i < 8; ++i)
            {
                outputData[outputIndex + i] = (byte)(alphaBits >> (i * 8));
            }

            // カラー値(c0, c1) 4バイト
            // c0
            outputData[outputIndex + 8] = (byte)(color0 & 0xff);
            outputData[outputIndex + 9] = (byte)((color0 >> 8) & 0xff);
            // c1
            outputData[outputIndex + 10] = 0x00;
            outputData[outputIndex + 11] = 0x00;

            // RGB情報 4バイト
            for (int i = 0; i < 4; ++i)
            {
                outputData[outputIndex + 12 + i] = (byte)(rgbBits >> (i * 8));
            }
        }
Ejemplo n.º 47
0
		// Rasterizes a single character glyph.
		private Glyph ImportGlyph(char character, Face face)
		{
			uint glyphIndex = face.GetCharIndex(character);
			face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
			face.Glyph.RenderGlyph(RenderMode.Normal);

			// Render the character.
            BitmapContent glyphBitmap = null;
			if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0)
            {
                glyphBitmap = new PixelBitmapContent<byte>(face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows);
				byte[] gpixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows];
                //if the character bitmap has 1bpp we have to expand the buffer data to get the 8bpp pixel data
                //each byte in bitmap.bufferdata contains the value of to 8 pixels in the row
                //if bitmap is of width 10, each row has 2 bytes with 10 valid bits, and the last 6 bits of 2nd byte must be discarded
                if(face.Glyph.Bitmap.PixelMode == PixelMode.Mono)
                {
                    //variables needed for the expansion, amount of written data, length of the data to write
                    int written = 0, length = face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows;
                    for(int i = 0; written < length; i++)
                    {
                        //width in pixels of each row
                        int width = face.Glyph.Bitmap.Width;
                        while(width > 0)
                        {
                            //valid data in the current byte
                            int stride = MathHelper.Min(8, width);
                            //copy the valid bytes to pixeldata
                            //System.Array.Copy(ExpandByte(face.Glyph.Bitmap.BufferData[i]), 0, gpixelAlphas, written, stride);
                            ExpandByteAndCopy(face.Glyph.Bitmap.BufferData[i], stride, gpixelAlphas, written);
                            written += stride;
                            width -= stride;
                            if(width > 0)
                                i++;
                        }
                    }
                }
                else
                    Marshal.Copy(face.Glyph.Bitmap.Buffer, gpixelAlphas, 0, gpixelAlphas.Length);
                glyphBitmap.SetPixelData(gpixelAlphas);
			}

            if (glyphBitmap == null) 
			{
				var gHA = face.Glyph.Metrics.HorizontalAdvance >> 6;
				var gVA = face.Size.Metrics.Height >> 6;

				gHA = gHA > 0 ? gHA : gVA;
				gVA = gVA > 0 ? gVA : gHA;

                glyphBitmap = new PixelBitmapContent<byte>(gHA, gVA);
			}

			// not sure about this at all
			var abc = new ABCFloat ();
			abc.A = face.Glyph.Metrics.HorizontalBearingX >> 6;
			abc.B = face.Glyph.Metrics.Width >> 6;
			abc.C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (abc.A + abc.B);

			// Construct the output Glyph object.
			return new Glyph(character, glyphBitmap)
			{
				XOffset = -(face.Glyph.Advance.X >> 6),
				XAdvance = face.Glyph.Metrics.HorizontalAdvance >> 6,
                YOffset = -(face.Glyph.Metrics.HorizontalBearingY >> 6),
				CharacterWidths = abc
			};
		}
Ejemplo n.º 48
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);
        }
Ejemplo n.º 49
0
        public static BitmapContent ToXnaBitmap(this Bitmap systemBitmap, bool flipColors)
        {
            // Any bitmap using this function should use 32bpp ARGB pixel format, since we have to
            // swizzle the channels later
            System.Diagnostics.Debug.Assert(systemBitmap.PixelFormat == PixelFormat.Format32bppArgb);

            var bitmapData = systemBitmap.LockBits(new System.Drawing.Rectangle(0, 0, systemBitmap.Width, systemBitmap.Height),
                                    ImageLockMode.ReadOnly,
                                    systemBitmap.PixelFormat);

            var length = bitmapData.Stride * bitmapData.Height;
            var pixelData = new byte[length];

            // Copy bitmap to byte[]
            Marshal.Copy(bitmapData.Scan0, pixelData, 0, length);
            systemBitmap.UnlockBits(bitmapData);

            // NOTE: According to http://msdn.microsoft.com/en-us/library/dd183449%28VS.85%29.aspx
            // and http://stackoverflow.com/questions/8104461/pixelformat-format32bppargb-seems-to-have-wrong-byte-order
            // Image data from any GDI based function are stored in memory as BGRA/BGR, even if the format says RGBA.
            // Because of this we flip the R and B channels.

            if(flipColors)
                BGRAtoRGBA(pixelData);

            var xnaBitmap = new PixelBitmapContent<Color>(systemBitmap.Width, systemBitmap.Height);
            xnaBitmap.SetPixelData(pixelData);

            return xnaBitmap;
        }
Ejemplo n.º 50
0
        protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            SurfaceFormat sourceFormat;
            if (!sourceBitmap.TryGetFormat(out sourceFormat))
                return false;

            SurfaceFormat format;
            TryGetFormat(out format);

            // A shortcut for copying the entire bitmap to another bitmap of the same type and format
            if (format == sourceFormat && (sourceRegion == new Rectangle(0, 0, Width, Height)) && sourceRegion == destinationRegion)
            {
                SetPixelData(sourceBitmap.GetPixelData());
                return true;
            }

            // Destination region copy is not yet supported
            if (destinationRegion != new Rectangle(0, 0, Width, Height))
                return false;

            // If the source is not Vector4 or requires resizing, send it through BitmapContent.Copy
            if (!(sourceBitmap is PixelBitmapContent<Vector4>) || sourceRegion.Width != destinationRegion.Width || sourceRegion.Height != destinationRegion.Height)
            {
                try
                {
                    BitmapContent.Copy(sourceBitmap, sourceRegion, this, destinationRegion);
                    return true;
                }
                catch (InvalidOperationException)
                {
                    return false;
                }
            }

            //SquishFlags targetFormat = SquishFlags.ColourClusterFit;
            Format outputFormat = Format.DXT1;
            switch (format)
            {
                case SurfaceFormat.Dxt1:
                    outputFormat = Format.DXT1;
                    break;
                case SurfaceFormat.Dxt1SRgb:
                    outputFormat = Format.DXT1;
                    break;
                case SurfaceFormat.Dxt3:
                    outputFormat = Format.DXT3;
                    break;
                case SurfaceFormat.Dxt3SRgb:
                    outputFormat = Format.DXT3;
                    break;
                case SurfaceFormat.Dxt5:
                    outputFormat = Format.DXT5;
                    break;
                case SurfaceFormat.Dxt5SRgb:
                    outputFormat = Format.DXT5;
                    break;
                default:
                    return false;
            }

            // libsquish requires RGBA8888
            var colorBitmap = new PixelBitmapContent<Color>(sourceBitmap.Width, sourceBitmap.Height);
            BitmapContent.Copy(sourceBitmap, colorBitmap);

            var sourceData = colorBitmap.GetPixelData();
            /*
            var dataSize = Squish.GetStorageRequirements(colorBitmap.Width, colorBitmap.Height, targetFormat);
            var data = new byte[dataSize];
            var metric = new float[] { 1.0f, 1.0f, 1.0f };
            Squish.CompressImage(sourceData, colorBitmap.Width, colorBitmap.Height, data, targetFormat, metric);
            SetPixelData(data);
            */

            var dxtCompressor = new Compressor();
            var inputOptions = new InputOptions();
            if (outputFormat != Format.DXT1)           
                inputOptions.SetAlphaMode(AlphaMode.Premultiplied);
            else
                inputOptions.SetAlphaMode(AlphaMode.None);
            inputOptions.SetTextureLayout(TextureType.Texture2D, colorBitmap.Width, colorBitmap.Height, 1);

            // Small hack here. NVTT wants 8bit data in BGRA. Flip the B and R channels
            // again here.
            GraphicsUtil.BGRAtoRGBA(sourceData);
            var dataHandle = GCHandle.Alloc(sourceData, GCHandleType.Pinned);
            try
            {
                var dataPtr = dataHandle.AddrOfPinnedObject();

                inputOptions.SetMipmapData(dataPtr, colorBitmap.Width, colorBitmap.Height, 1, 0, 0);
                inputOptions.SetMipmapGeneration(false);
                inputOptions.SetGamma(1.0f, 1.0f);

                var outputOptions = new OutputOptions();
                outputOptions.SetOutputHeader(false);

                var handler = new DxtDataHandler(this);
                outputOptions.SetOutputHandler(handler.BeginImage, handler.WriteData);

                var compressionOptions = new CompressionOptions();
                compressionOptions.SetFormat(outputFormat);
                compressionOptions.SetQuality(Quality.Normal);

                dxtCompressor.Compress(inputOptions, compressionOptions, outputOptions);
            }
            finally
            {
                dataHandle.Free ();
            }
            return true;
        }
Ejemplo n.º 51
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> 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;
        }
Ejemplo n.º 52
0
        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]);
        }
        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;
        }
Ejemplo n.º 54
0
        /// <summary>
        /// Copies one bitmap into another.
        /// The destination bitmap can be in any format and size. If the destination is larger or smaller, the source bitmap is scaled accordingly.
        /// </summary>
        /// <param name="sourceBitmap">BitmapContent being copied.</param>
        /// <param name="sourceRegion">Region of sourceBitmap.</param>
        /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
        /// <param name="destinationRegion">Region of bitmap to be overwritten.</param>
        public static void Copy(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
        {
            ValidateCopyArguments(sourceBitmap, sourceRegion, destinationBitmap, destinationRegion);

            SurfaceFormat sourceFormat;
            if (!sourceBitmap.TryGetFormat(out sourceFormat))
                throw new InvalidOperationException("Could not retrieve surface format of source bitmap");
            SurfaceFormat destinationFormat;
            if (!destinationBitmap.TryGetFormat(out destinationFormat))
                throw new InvalidOperationException("Could not retrieve surface format of destination bitmap");

            // If the formats are the same and the regions are the full bounds of the bitmaps and they are the same size, do a simpler copy
            if (sourceFormat == destinationFormat && sourceRegion == destinationRegion
                && sourceRegion == new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height)
                && destinationRegion == new Rectangle(0, 0, destinationBitmap.Width, destinationBitmap.Height))
            {
                destinationBitmap.SetPixelData(sourceBitmap.GetPixelData());
                return;
            }

            // The basic process is
            // 1. Copy from source bitmap region to a new PixelBitmapContent<Vector4> using sourceBitmap.TryCopyTo()
            // 2. If source and destination regions are a different size, resize Vector4 version
            // 3. Copy from Vector4 to destination region using destinationBitmap.TryCopyFrom()

            // Copy from the source to the intermediate Vector4 format
            var intermediate = new PixelBitmapContent<Vector4>(sourceRegion.Width, sourceRegion.Height);
            var intermediateRegion = new Rectangle(0, 0, intermediate.Width, intermediate.Height);
            if (sourceBitmap.TryCopyTo(intermediate, sourceRegion, intermediateRegion))
            {
                // Resize the intermediate if required
                if (intermediate.Width != destinationRegion.Width || intermediate.Height != destinationRegion.Height)
                    intermediate = intermediate.Resize(destinationRegion.Width, destinationRegion.Height) as PixelBitmapContent<Vector4>;
                // Copy from the intermediate to the destination
                if (destinationBitmap.TryCopyFrom(intermediate, new Rectangle(0, 0, intermediate.Width, intermediate.Height), destinationRegion))
                    return;
            }

            // If we got here, one of the above steps didn't work
            throw new InvalidOperationException("Could not copy between " + sourceFormat + " and " + destinationFormat);
        }
Ejemplo n.º 55
0
        internal static void Resize(this TextureContent content, int newWidth, int newHeight)
        {
            var resizedBmp = new Bitmap(newWidth, newHeight);

            using (var graphics = System.Drawing.Graphics.FromImage(resizedBmp))
            {
                graphics.DrawImage(content._bitmap, 0, 0, newWidth, newHeight);

                content._bitmap.Dispose();
                content._bitmap = resizedBmp;
            }

            var imageData = content._bitmap.GetData();

            var bitmapContent = new PixelBitmapContent<Color>(content._bitmap.Width, content._bitmap.Height);
            bitmapContent.SetPixelData(imageData);

            content.Faces.Clear();
            content.Faces.Add(new MipmapChain(bitmapContent));
        }