Question

I would like to flip an image and create a new Texture2D of that flipped image.

I have done some research and found that this code will create a new Texture2D;

RenderTarget2D newTarget = new RenderTarget2D(GraphicsDevice, partWidth, partHeight)

GraphicsDevice.SetRenderTarget(newTarget);

SpriteBatch.Draw(original, Vector2.Zero, partSourceRectangle, ... )

GraphicsDevice.SetRenderTarget(null);

Texture2D newTexture = (Texture2D)newTarget;

I understand that the newTexture is susceptible to being removed from memory so I am advised that I need to use getData/SetData to create a more permanent texture. Could anyone advise me on the specific syntax to do this?

Was it helpful?

Solution

The next method saves flipped texture to new texture2D:

    public Texture2D SaveAsFlippedTexture2D(Texture2D input, bool vertical, bool horizontal)
    {
        Texture2D flipped = new Texture2D(input.GraphicsDevice, input.Width, input.Height);
        Color[] data = new Color[input.Width * input.Height];
        Color[] flipped_data = new Color[data.Length];

        input.GetData<Color>(data);

        for (int x = 0; x < input.Width; x++)
        {
            for (int y = 0; y < input.Height; y++)
            {
                int index = 0;
                if (horizontal && vertical)
                    index = input.Width - 1 - x + (input.Height - 1 - y) * input.Width;
                else if (horizontal && !vertical)
                    index = input.Width - 1 - x + y * input.Width;
                else if (!horizontal && vertical)
                    index = x + (input.Height - 1 - y) * input.Width;
                else if (!horizontal && !vertical)
                    index = x + y * input.Width;

                flipped_data[x + y * input.Width] = data[index];
            }
        }

        flipped.SetData<Color>(flipped_data);

        return flipped;
    }  

Example: Load our texture then use the method, pass our texture as parameter to return new flipped texture to another texture. You can load your content inside game Update() method as well.

    Texture2D texture;
    Texture2D flippedTextureHorizontal;
    Texture2D flippedTextureVertical;
    Texture2D flippedTextureVerticalHorizontal;
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);
        texture = Content.Load<Texture2D>("kitty-cat");
        flippedTextureHorizontal = SaveAsFlippedTexture2D(texture, false, true);
        flippedTextureVertical = SaveAsFlippedTexture2D(texture, true, false);
        flippedTextureVerticalHorizontal = SaveAsFlippedTexture2D(texture, true, true);
    }

Draw method:

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap, DepthStencilState.None, RasterizerState.CullCounterClockwise);
        spriteBatch.Draw(texture, Vector2.Zero, null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
        spriteBatch.Draw(flippedTextureHorizontal, new Vector2(texture.Width + offset, 0), null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
        spriteBatch.Draw(flippedTextureVertical, new Vector2(texture.Width * 2 + offset * 2, 0), null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
        spriteBatch.Draw(flippedTextureVerticalHorizontal, new Vector2(texture.Width * 3 + offset * 3, 0), null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0);
        spriteBatch.End();
        base.Draw(gameTime);
    }

Ouput: Output

The alghorithm can be found Here as well. The same result as above can be achieved by using code below for horizontal and vertical flipping at the same time: But not sure it will be 100% correct

test = new Texture2D(GraphicsDevice, texture.Width, texture.Height);
int size = texture.Width * texture.Height;
Color[] data = new Color[size];
texture.GetData<Color>(data);
Array.Reverse(data, texture.Width, size - texture.Width);
test.SetData<Color>(data);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top