5
votes

I've begun making a 2D sprite based Windows game using XNA. I'm not very experienced with it yet but I'm learning. Let me start off with saying that I'm using XNA game studio 3.1, I haven't updated to 4.0 (yet).

What I'm trying to accomplish is to be able to draw all my sprites to a fixed size buffer which is then, at the end of the rendering pass, scaled to the size of the actual backbuffer and then drawn to that. I'm not sure how multiple resolutions are usually supported, but it seemed like an adequate solution to me.

I tried to achieve this by using a RenderTarget2D object to draw all my stuff to, then get the Texture2D from that and draw that to the backbuffer.

My code looks like this:

private RenderTarget2D RenderTarget;
private DepthStencilBuffer DepthStencilBufferRenderTarget;
private DepthStencilBuffer DepthStencilBufferOriginal;
private SpriteBatch SpriteBatch;

protected override void Initialize()
{
  base.Initialize();
  RenderTarget = new RenderTarget2D(GraphicsDevice, 1920, 1080, 1, SurfaceFormat.Single);

  DepthStencilBufferRenderTarget = new DepthStencilBuffer(GraphicsDevice, 
  1920, 1080, GraphicsDevice.DepthStencilBuffer.Format);

  DepthStencilBufferOriginal = GraphicsDevice.DepthStencilBuffer;
  SpriteBatch = new SpriteBatch(GraphicsDevice);
}

protected override void Draw(GameTime gameTime)
{
  GraphicsDevice.DepthStencilBuffer = DepthStencilBufferRenderTarget;
  GraphicsDevice.SetRenderTarget(0, RenderTarget);
  GraphicsDevice.Clear(Color.Black);

  SpriteBatch.Begin();
  //drawing all stuff here
  SpriteBatch.End();

  GraphicsDevice.DepthStencilBuffer = DepthStencilBufferOriginal;
  GraphicsDevice.SetRenderTarget(0, null);
  GraphicsDevice.Clear(Color.Black);
  Texture2D output = RenderTarget.GetTexture();

  SpriteBatch.Begin();
  Rectangle backbuffer = new Rectangle(0, 0, m_Options.DisplayWidth, m_Options.DisplayHeight);
  SpriteBatch.Draw(output, backbuffer, Color.White);
  SpriteBatch.End();

  base.Draw(gameTime);
}

The problem I encounter is that the colours are all wrong. Below is a picture that shows two screenshots: the first is a screenshot of how it's supposed to look (I wrote my own scaling algorithm before which simply scaled each sprite by itself) and to the right it's how it looks when using the RenderTarget2D.

Example of what's wrong

Does anyone know what I'm doing wrong?

1
That is perplexing... try saving the rendertarget's Texture2D to a file (Texture2D contains methods for saving) and see if it's still blue in order to identify whether or not the problem is when you're drawing your game to the target or drawing the target on the screen (i.e., if the saved image looks fine, the problem is drawing to screen).A-Type
Hi, I did what you said and the rendertarget's texture2D looks exactly as it is in the screenshot with the wrong colours. So obviously the problem lies in drawing to this rendertarget.Jela

1 Answers

2
votes

Oh I figured out what I did wrong (kind of). I think I used the wrong SurfaceFormat when creating the new RenderTarget2D instance. I used SurfaceFormat.Single but I should have used SurfaceFormat.Color.

I figured this out by taking a look at the PresentationParameters of the GraphicsDevice through a watch while debugging before setting the new RenderTarget:

GraphicsDevice.PresentationParameters.BackBufferFormat

This told me it was set to SurfaceFormat.Color. So I replaced SurfaceFormat.Single with SurfaceFormat.Color and now it works as it should.