Método 1
Você não precisa criar uma versão branca sólida de todos os sprites do seu jogo manualmente - você também pode automatizar o processo no tempo de carregamento. Em outras palavras, você pode usar Texture2D.GetData()
para acessar os pixels de sua textura (e recuperá-los como simples Color[]
), iterar sobre eles substituindo qualquer pixel não transparente por branco sólido e salvá-lo em uma nova textura usando e Texture2D.SetData()
.
Método 2
Tentei brincar, BlendState
mas não consegui encontrar uma maneira de tornar tudo branco, pelo menos não dentro das limitações do perfil Reach. Mas se alguém souber uma maneira, me avise. O que encontrei, no entanto, foi uma maneira de fazer isso usando o buffer de estêncil e a AlphaTestEffect
classe interna. A ideia é a seguinte:
- Crie um backbuffer que tenha um buffer de estêncil.
- Limpe o buffer de estêncil para zero.
- Desenhe os sprites que você deseja pintar de branco e, sempre que eles passarem no teste alfa, defina o buffer de estêncil nesse local como 1.
- Desenhe um quad branco cobrindo a tela inteira, mas apenas onde o valor do buffer de estêncil é 1.
Aqui está o código que eu usei:
(Etapa 1) Primeiro verifique se o backbuffer está sendo criado com espaço para um buffer de estêncil:
graphics = new GraphicsDeviceManager(this) { PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8 };
(Etapa 2) Crie uma textura branca 1x1 que será dimensionada para preencher a tela inteira:
private Texture2D pixel;
pixel = new Texture2D(GraphicsDevice, 1, 1);
pixel.SetData(new[] { Color.White });
(Etapa 3) E agora a parte mais difícil - renderizar. Bem, não é muito difícil, mas requer dois DepthStencilState
objetos e um AlphaTestEffect
objeto. Você deve criá-los apenas uma vez.
// Clear stencil buffer
GraphicsDevice.Clear(ClearOptions.Stencil, Color.Black, 0f, 0);
// Prepare the alpha test effect object (create it only once on initilization)
AlphaTestEffect alphaTestEffect = new AlphaTestEffect(GraphicsDevice)
{
DiffuseColor = Color.White.ToVector3(),
AlphaFunction = CompareFunction.Greater,
ReferenceAlpha = 0, World = Matrix.Identity,
View = Matrix.Identity,
Projection = Matrix.CreateTranslation(-0.5f, -0.5f, 0) *
Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 0, 1)
};
// Prepare the first DepthStencilState (create only once, or put it in a static class)
DepthStencilState beforeDepthStencilState = new DepthStencilState
{
StencilEnable = true,
StencilFunction = CompareFunction.Always,
StencilPass = StencilOperation.Replace,
ReferenceStencil = 1
};
// Draw your sprites using the structures above
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, beforeDepthStencilState, null, alphaTestEffect);
spriteBatch.Draw(sprite, new Vector2(300, 150), Color.White);
spriteBatch.End();
// Prepare the second DepthStencilState (create only once, or put it in a static class)
DepthStencilState afterDepthStencilState = new DepthStencilState
{
StencilEnable = true,
StencilFunction = CompareFunction.Equal,
ReferenceStencil = 1
};
// Draw a full screen white quad with the structure above
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, afterDepthStencilState, null);
spriteBatch.Draw(pixel, GraphicsDevice.Viewport.Bounds, Color.White);
spriteBatch.End();
E o resultado: