Método 1
No tienes que crear una versión blanca sólida de cada sprite en tu juego de forma manual ; también podrías automatizar el proceso en el momento de la carga. En otras palabras, puede usar Texture2D.GetData()
para acceder a los píxeles de su textura (y recuperarlos como un simple Color[]
), iterar sobre ellos reemplazando cualquier píxel no transparente con blanco sólido y luego guardarlo en una nueva textura usando y Texture2D.SetData()
.
Método 2
Traté de jugar con, BlendState
pero no pude encontrar una manera de hacer que todo sea blanco, al menos no dentro de las limitaciones del perfil Reach. Pero si alguien sabe una manera, hágamelo saber. Lo que sí encontré, sin embargo, fue una forma de hacerlo utilizando el búfer de plantilla y la AlphaTestEffect
clase incorporada . La idea es la siguiente:
- Cree un búfer de respaldo que tenga un búfer de plantilla.
- Borre el búfer de la plantilla a cero.
- Dibuje los sprites que desea teñir de blanco y cada vez que pasen la prueba alfa, configure el búfer de la plantilla en esa ubicación en 1.
- Dibuje un quad blanco que cubra toda la pantalla, pero solo donde el valor del búfer de la plantilla es 1.
Aquí está el código que usé:
(Paso 1) Primero asegúrese de que el backbuffer se esté creando con espacio para un búfer de plantilla:
graphics = new GraphicsDeviceManager(this) { PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8 };
(Paso 2) Cree una textura blanca 1x1 que se escalará para llenar toda la pantalla:
private Texture2D pixel;
pixel = new Texture2D(GraphicsDevice, 1, 1);
pixel.SetData(new[] { Color.White });
(Paso 3) Y ahora la parte difícil: representarlo. Bueno, no es realmente difícil, pero requiere dos DepthStencilState
objetos y un AlphaTestEffect
objeto. Debe crearlos solo una 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();
Y el resultado: