Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Colours are wrong when using RenderTarget2D in XNA

Tags:

c#

xna

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?

like image 397
Jela Avatar asked Nov 05 '22 08:11

Jela


1 Answers

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.

like image 181
Jela Avatar answered Nov 13 '22 06:11

Jela