Problem 1: I solved this by using a render target that was larger than the area. It should be able to encompass the halfwidth/halfheight of your biggest sprite. In my example, I just decided to use a size three times as high and wide as the game render area. I cut the render target into nine pieces, and render them all on top of each other. Here's the code:
private const Int32 WIDTH = 320;
private const Int32 HEIGHT = 240;
private RenderTarget2D wrapTarget;
protected override void LoadContent()
{
this.wrapTarget = new RenderTarget2D(this.GraphicsDevice, WIDTH * 3, HEIGHT * 3);
}
protected override void Draw(GameTime gameTime)
{
this.GraphicsDevice.SetRenderTarget(this.wrapTarget);
this.GraphicsDevice.Clear(Color.Transparent); // has to be transparent, to allow all segments to overlap properly.
// the translation matrix saves you from offsetting all coordinates, since we want to draw at the center segment of the wrapTarget rendertarget.
this.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, Matrix.CreateTranslation(WIDTH, HEIGHT, 0.00f));
this.spriteBatch.Draw(this.circle, this.circlePosition, null, Color.White, 0.00f, new Vector2(this.circle.Width / 2.00f, this.circle.Height / 2.00f), Vector2.One, SpriteEffects.None, 0);
this.spriteBatch.Draw(this.square, this.squarePosition, null, Color.White, 0.00f, new Vector2(this.square.Width / 2.00f, this.square.Height / 2.00f), Vector2.One, SpriteEffects.None, 0);
this.spriteBatch.End();
this.GraphicsDevice.SetRenderTarget(null);
this.GraphicsDevice.Clear(Color.LightYellow); // this is the actual background color you want.
this.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
this.spriteBatch.Draw(this.wrapTarget, Vector2.Zero, new Rectangle(0, 0, WIDTH, HEIGHT), Color.White);
this.spriteBatch.Draw(this.wrapTarget, Vector2.Zero, new Rectangle(WIDTH, 0, WIDTH, HEIGHT), Color.White);
this.spriteBatch.Draw(this.wrapTarget, Vector2.Zero, new Rectangle(WIDTH * 2, 0, WIDTH, HEIGHT), Color.White);
this.spriteBatch.Draw(this.wrapTarget, Vector2.Zero, new Rectangle(0, HEIGHT, WIDTH, HEIGHT), Color.White);
this.spriteBatch.Draw(this.wrapTarget, Vector2.Zero, new Rectangle(WIDTH, HEIGHT, WIDTH, HEIGHT), Color.White);
this.spriteBatch.Draw(this.wrapTarget, Vector2.Zero, new Rectangle(WIDTH * 2, HEIGHT, WIDTH, HEIGHT), Color.White);
this.spriteBatch.Draw(this.wrapTarget, Vector2.Zero, new Rectangle(0, HEIGHT * 2, WIDTH, HEIGHT), Color.White);
this.spriteBatch.Draw(this.wrapTarget, Vector2.Zero, new Rectangle(WIDTH, HEIGHT * 2, WIDTH, HEIGHT), Color.White);
this.spriteBatch.Draw(this.wrapTarget, Vector2.Zero, new Rectangle(WIDTH * 2, HEIGHT * 2, WIDTH, HEIGHT), Color.White);
this.spriteBatch.End();
base.Draw(gameTime);
}
Problem 2: This I have no idea how to solve.
Problem 3: This method automatically does that. You can replace the Vector2.Zero in the nine SpriteBatch.Draw inside the second SpriteBatch.Begin/End block to draw it wherever you'd like.
You can try out my version here. Use the arrow keys to move the square, the mouse to move the circle.