1
\$\begingroup\$

I'm working with Monogame to do a 2d sprite engine. I've gotten it work pretty well where I can move lots of sprites around the screen with the effects and positions that I want.

Last night I tried to add a feature and I can't quite get it to work right.
I'm trying to create permanent trails that the moving sprites can leave behind. So I have a mostly transparent PNG with some white lines on it called "streak". The idea is that I set up a new Texture2d surface (called streakoverlay) and I draw the streaks on to it.

I switch back to the back buffer and draw: The background, the streakoverlay, and finally the sprite on top of it. The streaks should build up over time. It almost works, but the trouble I have is that streakOverlay seems to clear itself every time. How I'd like it to behave would be the same behaviour as having the graphics display without this line "GraphicsDevice.Clear(Color.White);" - everything would just pile up in it.

Instead it resets back to the Purple transparent color that is the default for that texture. Any suggestions? Here's the core piece of the rendering engine:

GraphicsDeviceManager graphics; RenderTarget2D streakOverlay; SpriteBatch spriteBatch; private Texture2D bkg; private Texture2D prototype; private Texture2D streak; //Initialize graphics = new GraphicsDeviceManager(this); GraphicsDevice.Clear(Color.Transparent); streakOverlay = new RenderTarget2D(GraphicsDevice, 200,200); //Load Content bkg = Content.Load<Texture2D>("bkg"); //Background image prototype = Content.Load<Texture2D>("prototype"); //Prototype sprite that moves around streak = Content.Load<Texture2D>("blueStreak"); //Trails being left by Prototype sprite graphics.GraphicsDevice.SetRenderTarget(streakOverlay); GraphicsDevice.Clear(Color.Transparent); //Attempt to make the streakoverlay is fully transparent. graphics.GraphicsDevice.SetRenderTarget(null); //Draw Random r = new Random(); graphics.GraphicsDevice.SetRenderTarget(streakOverlay); //Switch to drawing to the streakoverlay spriteBatch.Begin(); //Draw some streaks that should accumulate spriteBatch.Draw(streak, new Vector2(r.Next(0, 200), r.Next(0, 200)), null, Color.White, 0f, new Vector2(25, 25), 1f, SpriteEffects.None, 1f); spriteBatch.End(); //Switch back to drawing on the back buffer. graphics.GraphicsDevice.SetRenderTarget(null); spriteBatch.Begin(); spriteBatch.Draw(bkg, new Rectangle(0, 0, 2000, 2000), Color.White); //Draw our background spriteBatch.Draw(streakOverlay, new Vector2(0, 0), Color.White); //Put the overlay on top of it spriteBatch.Draw(prototype, new Vector2(_spritePrototype.getX, _spritePrototype.getY), null, Color.White, DegreeToRadian(rotationSprite), new Vector2(25, 25), .5f, SpriteEffects.None, 0f); //Draw the sprite that's moving around. spriteBatch.End(); base.Draw(gameTime); 
\$\endgroup\$
2
  • \$\begingroup\$ I'm not sure, but I suspect one of the calls to the sprite batch (Begin or End) have a parameter you can use to specify "don't clear everything." \$\endgroup\$ Commented Nov 22, 2013 at 18:10
  • \$\begingroup\$ Looks like there is: spriteBatch.Begin(SpriteSortMode.Texture, BlendState.Additive); This blends things better, but the texture is still getting wiped every turn. \$\endgroup\$ Commented Nov 22, 2013 at 18:56

1 Answer 1

2
\$\begingroup\$

In XNA, setting a render target (including the backbuffer) onto a device will, by default, clear that render target to the "uninitialized surface" purple colour.

To avoid this, set the RenderTargetUsage of your render target to PreserveContents when constructing it.

DiscardContents is the default for performance reasons: On mobile systems and on the Xbox 360, retaining the contents of a render target is an expensive operation. This default is used on all platforms to aid portability.

I am not sure whether MonoGame's implementation matches this behaviour exactly.

An alternative approach would be to "bounce" the texture between two render targets, alternating which is rendered to on each frame. (This can also allow you to do effects like fading out the existing streaks.)

\$\endgroup\$
1
  • \$\begingroup\$ This is exactly what I needed, thank you. I also like the idea of using a duplicate texture for fading. I'll implement that. \$\endgroup\$ Commented Nov 26, 2013 at 15:11

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.