Methode 1
Sie müssen nicht manuell eine solide weiße Version jedes Sprites in Ihrem Spiel erstellen - Sie können den Prozess auch beim Laden automatisieren. Mit anderen Worten, Sie können Texture2D.GetData()
auf die Pixel Ihrer Textur zugreifen (und sie einfach abrufen Color[]
), sie durchlaufen und nicht transparente Pixel durch festes Weiß ersetzen und sie dann mit und in einer neuen Textur speichern Texture2D.SetData()
.
Methode 2
Ich habe versucht, damit herumzuspielen BlendState
, konnte aber keinen Weg finden, alles weiß zu machen, zumindest nicht innerhalb der Grenzen des Reach-Profils. Aber wenn jemand einen Weg kennt, lass es mich wissen. Was ich jedoch gefunden habe, war eine Möglichkeit, dies mit dem Schablonenpuffer und der eingebauten AlphaTestEffect
Klasse zu tun . Die Idee ist die folgende:
- Erstellen Sie einen Backbuffer mit einem Schablonenpuffer.
- Löschen Sie den Schablonenpuffer auf Null.
- Zeichnen Sie die Sprites, die Sie weiß tönen möchten, und setzen Sie den Schablonenpuffer an dieser Stelle auf 1, wenn sie den Alpha-Test bestehen.
- Zeichnen Sie ein weißes Quad, das den gesamten Bildschirm abdeckt, jedoch nur, wenn der Wert des Schablonenpuffers 1 beträgt.
Hier ist der Code, den ich verwendet habe:
(Schritt 1) Stellen Sie zunächst sicher, dass der Backbuffer mit Platz für einen Schablonenpuffer erstellt wird:
graphics = new GraphicsDeviceManager(this) { PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8 };
(Schritt 2) Erstellen Sie eine 1x1 weiße Textur, die so skaliert wird, dass sie den gesamten Bildschirm ausfüllt:
private Texture2D pixel;
pixel = new Texture2D(GraphicsDevice, 1, 1);
pixel.SetData(new[] { Color.White });
(Schritt 3) Und jetzt der schwierige Teil - das Rendern. Nun, nicht wirklich schwer, erfordert aber zwei DepthStencilState
Objekte und ein AlphaTestEffect
Objekt. Sie sollten diese nur einmal erstellen.
// 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();
Und das Ergebnis: