Why RenderTarget2D overwrites other objects when trying to put some text in a model?

I am trying to draw an object composited by two cubes (A & B) (one on top of the other, but for now I have them a little bit more open). I am able to do it and this is the result.

(Cube A is the blue and Cube B is the one with brown text that comes from a png texture)

But I want to have any text as parameter in the cube B. I have tried what @alecnash suggested in his question, but for some reason when I try to draw cube B, cube A dissapears and everything turns purple.

This is my draw code:

public void Draw(GraphicsDevice graphicsDevice, SpriteBatch spriteBatch, Matrix viewMatrix, Matrix projectionMatrix)
{
graphicsDevice.BlendState = BlendState.Opaque;
graphicsDevice.DepthStencilState = DepthStencilState.Default;
graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
graphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;

// CUBE A
basicEffect.View = viewMatrix;
basicEffect.Projection = projectionMatrix;
basicEffect.World = Matrix.CreateTranslation(ModelPosition);
basicEffect.VertexColorEnabled = true;
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
pass.Apply();
drawCUBE_TOP(graphicsDevice);
drawCUBE_Floor(graphicsDevice);
DrawFullSquareStripesFront(graphicsDevice, _numStrips, Color.Red, Color.Blue, _levelPercentage);
DrawFullSquareStripesLeft(graphicsDevice, _numStrips, Color.Red, Color.Blue, _levelPercentage);
DrawFullSquareStripesRight(graphicsDevice, _numStrips, Color.Red, Color.Blue, _levelPercentage);
DrawFullSquareStripesBack(graphicsDevice, _numStrips, Color.Red, Color.Blue, _levelPercentage);

}

// CUBE B
// Set the World matrix which defines the position of the cube
texturedCubeEffect.World = Matrix.CreateTranslation(ModelPosition);
// Set the View matrix which defines the camera and what it's looking at
texturedCubeEffect.View = viewMatrix;
// Set the Projection matrix which defines how we see the scene (Field of view)
texturedCubeEffect.Projection = projectionMatrix;
// Enable textures on the Cube Effect. this is necessary to texture the model
texturedCubeEffect.TextureEnabled = true;
Texture2D a = SpriteFontTextToTexture(graphicsDevice, spriteBatch, arialFont, "TEST ", Color.Black, Color.GhostWhite);
texturedCubeEffect.Texture = a;
//texturedCubeEffect.Texture = cubeTexture;
// Enable some pretty lights
texturedCubeEffect.EnableDefaultLighting();
// apply the effect and render the cube
foreach (EffectPass pass in texturedCubeEffect.CurrentTechnique.Passes)
{
pass.Apply();
cubeToDraw.RenderToDevice(graphicsDevice);
}

}

private Texture2D SpriteFontTextToTexture(GraphicsDevice graphicsDevice, SpriteBatch spriteBatch, SpriteFont font, string text, Color backgroundColor, Color textColor)
{
Vector2 Size = font.MeasureString(text);
RenderTarget2D renderTarget = new RenderTarget2D(graphicsDevice, (int)Size.X, (int)Size.Y);
graphicsDevice.SetRenderTarget(renderTarget);

graphicsDevice.Clear(Color.Transparent);

spriteBatch.Begin();
//have to redo the ColorTexture
//spriteBatch.Draw(ColorTexture.Create(graphicsDevice, 1024, 1024, backgroundColor), Vector2.Zero, Color.White);

spriteBatch.DrawString(font, text, Vector2.Zero, textColor);
spriteBatch.End();

graphicsDevice.SetRenderTarget(null);

return renderTarget;
}


The way I generate texture with dynamic text is:

 Texture2D a = SpriteFontTextToTexture(graphicsDevice, spriteBatch, arialFont, "TEST ", Color.Black, Color.GhostWhite);


After commenting several parts to see what caused the problem, it seems to be located in this line

graphicsDevice.SetRenderTarget(renderTarget);

• I have commented the line in SpriteFontTextToTexture because it is killing my fps and makes no cube appear in screen. Nov 25 '12 at 17:25

That purple colour is the "uninitialized surface" colour.

Basically whenever you call GraphicsDevice.SetRenderTarget, the render target that you set gets cleared (by default). In this case, the back-buffer counts as a render target (setting null).

You could set RenderTargetUsage.PreserveContents on the backbuffer. But preserving the contents of a render target is slow on Xbox 360 and Windows Phone. The default is to clear in order to be fast on those devices (and Windows matches that behaviour to make your life easier when porting).

The recommended way to solve this is to order your drawing so that you fill your render targets before you draw anything to the backbuffer.

This is explained in detail in this blog post. And also in my answer here.

Also it looks like you are creating a fresh render-target each frame. That's a big no-no. Create it once and re-use it!

• I've tried quickly to use PreserveContents (as I am doing my project in windows) by changing declaration of rendertarget with RenderTarget2D renderTarget = new RenderTarget2D(graphicsDevice, (int)Size.X, (int)Size.Y,false,SurfaceFormat.Color,DepthFormat.None,1,RenderTargetUsage.PreserveContents); and doesn't seem to work. This night I will read deeply the blog post... Nov 26 '12 at 6:49
• @cad The target you need to be preserving is the backbuffer itself. When you call SetRenderTarget(null) you are clearing it. You have to mess around with PreparingDeviceSettings to make this change. Nov 26 '12 at 8:38
• I've changed the order as you suggested and draw first cube B and later cube A. It worked :) Also did as you suggested and only create render targer once with this: if (renderTarget==null) { renderTarget = new RenderTarget2D(graphicsDevice, (int)Size.X, (int)Size.Y, false, SurfaceFormat.Color, DepthFormat.None, 1, RenderTargetUsage.PreserveContents); } Dec 1 '12 at 15:46