2012-01-03 13 views
5

Comencé a hacer un juego de Windows en 2D basado en sprites utilizando XNA. Todavía no tengo mucha experiencia pero estoy aprendiendo. Permítanme comenzar diciendo que estoy usando XNA game studio 3.1, no actualicé a 4.0 (todavía).Los colores son incorrectos al usar RenderTarget2D en XNA

Lo que estoy tratando de lograr es poder dibujar todos mis sprites en un búfer de tamaño fijo que luego, al final del pase de renderizado, se escala al tamaño del backbuffer real y luego se dibuja en ese . No estoy seguro de cómo se soportan varias resoluciones, pero me pareció una solución adecuada.

Intenté lograr esto usando un objeto RenderTarget2D para dibujar todo mi material, luego obtengo el Texture2D de eso y lo dibujo en el backbuffer.

Mi código es el siguiente:

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); 
} 

El problema que encuentro es que los colores están mal. A continuación se muestra una imagen que muestra dos capturas de pantalla: la primera es una captura de pantalla de cómo se supone que debe verse (escribí mi propio algoritmo de escala antes de escalar cada sprite por sí mismo) y a la derecha es lo que parece cuando se utiliza RenderTarget2D.

Example of what's wrong

¿Alguien sabe lo que estoy haciendo mal?

+1

Eso es desconcertante ... intente guardar Texture2D del rendertarget en un archivo (Texture2D contiene métodos para guardar) y ver si todavía es azul para identificar si el problema es o no cuando está dibujando su juego al objetivo o dibujando el objetivo en la pantalla (es decir, si la imagen guardada se ve bien, el problema es dibujar en la pantalla). –

+0

Hola, hice lo que dijiste y el texture2D de Rendertarget se ve exactamente como está en la captura de pantalla con los colores incorrectos. Entonces, obviamente, el problema radica en llegar a este rendertarget. – Jerry

Respuesta

2

Oh, descubrí lo que hice mal (más o menos). Creo que utilicé el SurfaceFormat equivocado al crear la nueva instancia de RenderTarget2D. Usé SurfaceFormat.Single pero debería haber usado SurfaceFormat.Color.

Me di cuenta de esto por echar un vistazo a las PresentationParameters del GraphicsDevice a través de un reloj durante la depuración antes de establecer el nuevo RenderTarget:

GraphicsDevice.PresentationParameters.BackBufferFormat 

Este me dijo que se establece en SurfaceFormat.Color. Así que reemplacé SurfaceFormat.Single con SurfaceFormat.Color y ahora funciona como debería.

+0

Para futuros lectores: es bastante obvio lo que salió mal al leer esto: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.surfaceformat.aspx SurfaceFormat.Color es un simple Espacio de color RGBA de 32 bits, mientras que SurfaceFormat.Single es un formato flotante de 32 bits con 32 bits para el canal rojo. – Jerry

+0

Supongo que en general es mejor usar el [RenderTarget2D constructor] (http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.rendertarget2d.rendertarget2d.aspx) sin especificar explícitamente la presentación parámetros. – user1306322

Cuestiones relacionadas