0
\$\begingroup\$

I'm generating a Texture2D object using RenderTarget2D as in the following code

public static Texture2D GetTextTexture(string text, Vector2 position, SpriteFont font, Color foreColor, Color backColor, Texture2D background=null)
{
            int width = (int)font.MeasureString(text).X;
            int height = (int)font.MeasureString(text).Y;

            GraphicsDevice device = Settings.game.GraphicsDevice;
            SpriteBatch spriteBatch = Settings.game.spriteBatch;

            RenderTarget2D renderTarget = new RenderTarget2D(device, width,
            height, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8,
            device.PresentationParameters.MultiSampleCount, RenderTargetUsage.DiscardContents);

            device.SetRenderTarget(renderTarget);
                device.Clear(backColor);
                spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
                if (background != null) spriteBatch.Draw(background, new Rectangle(0, 0, 70, 70), Color.White);
                spriteBatch.End();
                spriteBatch.Begin();
                spriteBatch.DrawString(font, text, position, foreColor, 0, new Vector2(0), 0.8f, SpriteEffects.None, 0);
                spriteBatch.End();
            device.SetRenderTarget(null);
            ResetGraphicsDeviceSettings();
            return (Texture2D)renderTarget;
}

It's working all fine. But when I ToggleFullScreen() (and vice-versa), the previous textures are getting transparent. However, the new textures after that are being generated correctly.

What can be the reason for this?

\$\endgroup\$
1
\$\begingroup\$

ToggleFullScreen() causes the GraphicsDevice to be reset and when the GraphicsDevice is reset the default behavior of the RenderTarget2D is to loose its data.

You have 2 options.

  1. You can copy the color data into a Texture2D.

    Color[] texdata = new Color[Width * Height];
    renderTarget.GetData(texdata);
    texture.SetData(texdata); //<-- you would want to return this texture
    
  2. You can hook into the Content Lost Event and rebuild the RenderTarget2D when needed.

Personally I recommend #1, especially it its a one time operation such as at level loading, since it helps keep things simple since you're back to only dealing with standard Texture2Ds and everything is back on CPU side memory.

\$\endgroup\$
4
  • \$\begingroup\$ I have already tried option 1, it was not working. For option 2, Shawn Hargreaves at this link says that its slow. But I'm not much concerned about performance. I'm trying to resolve The size of the data passed in is too large or too small for this resource issue. Read at many places, still I'm trying to figure out this issue. \$\endgroup\$
    – Shashwat
    Jun 12 '14 at 15:22
  • \$\begingroup\$ I still didn't understand option 3. Which RenderTarget2D shall I built inside the handler? Are you asking me to reset the GraphicsDevice settings? \$\endgroup\$
    – Shashwat
    Jun 12 '14 at 15:24
  • \$\begingroup\$ Option 2 is slow if you do it every frame. It's reasonably fast if you do it once at start-up. Your exception is because you're using the API wrong (ask a new question if you need help). Option 3 requires a handler on every render target that doesn't get refreshed every frame. \$\endgroup\$ Jun 12 '14 at 16:08
  • \$\begingroup\$ And option 1 is actually incorrect. It allows you to set the render target back onto the device without clearing it. It has nothing to do with content-lost and does not solve that problem. (I have taken the liberty of editing the answer to reflect this.) \$\endgroup\$ Jun 12 '14 at 16:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .