1
votes

Im just experimenting with pixel shader. I found a nice blur effect and now Im trying to create an effect of blurring an image over and over.

HOW I want to do that: I want to render my image hellokittyTexture in a RenderTarget applying the blur effect, then replace hellokittyTexture with the result of that render and do it over and over again every Draw iteration:

protected override void Draw(GameTime gameTime)
    {

        GraphicsDevice.Clear(Color.CornflowerBlue);


        GraphicsDevice.SetRenderTarget(buffer1);

        // Begin the sprite batch, using our custom effect.
        spriteBatch.Begin(0, null, null, null, null, blur);
        spriteBatch.Draw(hellokittyTexture , Vector2.Zero, Color.White);
        spriteBatch.End();
        GraphicsDevice.SetRenderTarget(null);

        hellokittyTexture = (Texture2D) buffer1;

        // Draw the texture in the screen
        spriteBatch.Begin(0, null, null, null, null, null);
        spriteBatch.Draw(hellokittyTexture , Vector2.Zero, Color.White);
        spriteBatch.End();

        base.Draw(gameTime);
    }

But I get this error "The render target must not be set on the device when it is used as a texture." Because hellokittyTexture = (Texture2D) buffer1; is not copying the texture but the reference to the RenderTarget (basicly they are the same object after the asignation)

Do you know a nice way to get the Texture inside the RenderTarget? or a more elegant way to do what Im trying?

2
renderTarget must have some field or property or method that allows to set its texture data, either use that or simply draw your texture to ituser1306322

2 Answers

3
votes
    spriteBatch.Draw(hellokittyTexture , Vector2.Zero, Color.White);

In this line, you're drawing the texture... to itself... That can't happen.

Assuming buffer1 and hellokittyTexture have been properly initialized, replace this line:

    hellokittyTexture = (Texture2D) buffer1;

with this:

        Color[] texdata = new Color[hellokittyTexture.Width * hellokittyTexture.Height];
        buffer1.GetData(texdata);
        hellokittyTexture.SetData(texdata);

This way, hellokittyTexture will be set as a copy of buffer1, rather than a pointer to it.

1
votes

Just a little addition to McMonkey answer:

I get this error: "You may not call SetData on a resource while it is actively set on the GraphicsDevice. Unset it from the device before calling SetData." I solved it by creating a new texture. Dont know if this could be a performance problem, but its working now:

        Color[] texdata = new Color[buffer1.Width * buffer1.Height];
        buffer1.GetData(texdata);
        hellokittyTexture= new Texture2D(GraphicsDevice, buffer1.Width, buffer1.Height);
        hellokittyTexture.SetData(texdata);