0
votes

i am converting a XNA 3.0 cloud effect into XNA 4.0 but i get an error

"The render target must not be set on the device when it is used as a texture."

It happens in the second loop in this line:

mover.Parameters["PressureMap"].SetValue(PressureOffsets);

Code:

for (int i = 0; i < 10; i++)
{
   graf.SetRenderTarget(rt5);

   mover.Parameters["PressureMap"].SetValue(PressureOffsets);
   mover.Parameters["DivergenceMap"].SetValue(Divergence);
   mover.CurrentTechnique = mover.Techniques["Jacobi"];
   mover.CurrentTechnique.Passes[0].Apply();

   sp.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.PointWrap, DepthStencilState.DepthRead, RasterizerState.CullNone);
   sp.Draw(Velocity, new Vector2(0, 0), Color.White);
   sp.End();

   graf.SetRenderTarget(null);
   PressureOffsets = rt5;
}

It seems I cant set in XNA 4.0 an texture as an effect parameter, if its already set as rendertarget. But I dont know how to convert this to work in XNA 4.0 :(

2

2 Answers

0
votes

I solved it. Its necessary to change the rendertarget with a new one. I used a helper Class "RenderTargetState".

    public RenderTargetState SetToDevice()
    {
        oldState = new RenderTargetState(GraphicsDevice);
        GraphicsDevice.SetRenderTarget(new RenderTarget2D(GraphicsDevice, renderTargetWidth, renderTargetHeight));

        return oldState;
    }

    public RenderTargetState BeginRenderToTexture()
    {
        oldState = SetToDevice();

        return oldState;
    }

    public Texture2D EndRenderGetTexture()
    {
        RenderTargetState renderBuffer = oldState.SetToDevice();
        oldState = null;
        return renderBuffer.RenderTarget;
    }

So the code looks like this now:

for (int i = 0; i < 10; i++)
{
  rt5.BeginRenderToTexture();
  graf.SetRenderTarget(rt5.RenderTarget);    

  mover.Parameters["PressureMap"].SetValue(PressureOffsets);
  mover.Parameters["DivergenceMap"].SetValue(Divergence);
  mover.CurrentTechnique = mover.Techniques["Jacobi"];
  mover.CurrentTechnique.Passes[0].Apply();

  sp.Begin(SpriteSortMode.Deferred, BlendState.Opaque);
  sp.Draw(Velocity, new Vector2(0, 0), Color.White);
  sp.End();

  graf.SetRenderTarget(null);
  PressureOffsets = rt5.EndRenderGetTexture();
}
0
votes

There's an easier way to do this.

rt5 = PressureOffsets as RenderTarget2D
graf.SetRenderTarget(null);
PressureOffsets = rt5;