2019-08-06 14:20:11 +02:00
|
|
|
using Microsoft.Xna.Framework;
|
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
2019-11-02 14:53:59 +01:00
|
|
|
using MLEM.Misc;
|
2019-12-31 14:08:13 +01:00
|
|
|
using MLEM.Textures;
|
2019-08-06 14:20:11 +02:00
|
|
|
|
|
|
|
namespace MLEM.Extensions {
|
2020-05-21 12:53:42 +02:00
|
|
|
/// <summary>
|
|
|
|
/// A set of extensions for dealing with <see cref="SpriteBatch"/>
|
|
|
|
/// </summary>
|
2019-08-06 14:20:11 +02:00
|
|
|
public static class SpriteBatchExtensions {
|
|
|
|
|
|
|
|
private static Texture2D blankTexture;
|
|
|
|
|
2020-05-20 23:59:40 +02:00
|
|
|
/// <summary>
|
|
|
|
/// Returns a 1x1 pixel white texture that can be used for drawing solid color shapes.
|
|
|
|
/// This texture is automatically disposed of when the batch is disposed.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="batch">The sprite batch</param>
|
|
|
|
/// <returns>A 1x1 pixel white texture</returns>
|
2019-08-06 14:46:43 +02:00
|
|
|
public static Texture2D GetBlankTexture(this SpriteBatch batch) {
|
2019-08-06 14:20:11 +02:00
|
|
|
if (blankTexture == null) {
|
2019-08-10 21:37:10 +02:00
|
|
|
blankTexture = new Texture2D(batch.GraphicsDevice, 1, 1);
|
2019-08-06 14:20:11 +02:00
|
|
|
blankTexture.SetData(new[] {Color.White});
|
2020-07-12 19:41:25 +02:00
|
|
|
AutoDispose(batch, blankTexture);
|
2019-08-06 14:20:11 +02:00
|
|
|
}
|
|
|
|
return blankTexture;
|
|
|
|
}
|
|
|
|
|
2020-05-20 23:59:40 +02:00
|
|
|
/// <summary>
|
2020-07-12 19:41:25 +02:00
|
|
|
/// Generates a <see cref="NinePatch"/> that has a texture with a given color and outline color.
|
|
|
|
/// This texture is automatically disposed of when the batch is disposed.
|
2020-05-20 23:59:40 +02:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="batch">The sprite batch</param>
|
|
|
|
/// <param name="color">The fill color of the texture</param>
|
|
|
|
/// <param name="outlineColor">The outline color of the texture</param>
|
|
|
|
/// <returns>A <see cref="NinePatch"/> containing a 3x3 texture with an outline</returns>
|
2019-12-31 14:08:13 +01:00
|
|
|
public static NinePatch GenerateTexture(this SpriteBatch batch, Color color, Color? outlineColor = null) {
|
|
|
|
var outli = outlineColor ?? Color.Black;
|
|
|
|
var tex = new Texture2D(batch.GraphicsDevice, 3, 3);
|
|
|
|
tex.SetData(new[] {
|
|
|
|
outli, outli, outli,
|
|
|
|
outli, color, outli,
|
|
|
|
outli, outli, outli
|
|
|
|
});
|
2020-07-12 19:41:25 +02:00
|
|
|
AutoDispose(batch, tex);
|
2019-12-31 14:08:13 +01:00
|
|
|
return new NinePatch(tex, 1);
|
|
|
|
}
|
|
|
|
|
2020-07-12 19:41:25 +02:00
|
|
|
/// <summary>
|
|
|
|
/// Generates a 1x1 texture with the given color.
|
|
|
|
/// This texture is automatically disposed of when the batch is disposed.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="batch">The sprite batch</param>
|
|
|
|
/// <param name="color">The color of the texture</param>
|
|
|
|
/// <returns>A new texture with the given data</returns>
|
|
|
|
public static Texture2D GenerateSquareTexture(this SpriteBatch batch, Color color) {
|
|
|
|
var tex = new Texture2D(batch.GraphicsDevice, 1, 1);
|
|
|
|
tex.SetData(new[] {color});
|
|
|
|
AutoDispose(batch, tex);
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Generates a texture with the given size that contains a circle.
|
|
|
|
/// The circle's center will be the center of the texture, and the circle will lead up to the edges of the texture.
|
|
|
|
/// This texture is automatically disposed of when the batch is disposed.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="batch">The sprite batch</param>
|
|
|
|
/// <param name="color">The color of the texture</param>
|
|
|
|
/// <param name="size">The width and height of the texture, and the diameter of the circle</param>
|
|
|
|
/// <returns>A new texture with the given data</returns>
|
|
|
|
public static Texture2D GenerateCircleTexture(this SpriteBatch batch, Color color, int size) {
|
|
|
|
var tex = new Texture2D(batch.GraphicsDevice, size, size);
|
|
|
|
using (var data = tex.GetTextureData()) {
|
|
|
|
for (var x = 0; x < tex.Width; x++) {
|
|
|
|
for (var y = 0; y < tex.Height; y++) {
|
|
|
|
var dist = Vector2.Distance(new Vector2(size / 2), new Vector2(x, y));
|
|
|
|
data[x, y] = dist <= size / 2 ? color : Color.Transparent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
AutoDispose(batch, tex);
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
2021-06-03 21:33:09 +02:00
|
|
|
/// <summary>
|
|
|
|
/// Generates a texture with the given size that contains a gradient between the four specified corner colors.
|
|
|
|
/// If the same color is specified for two pairs of corners, a horizontal, vertical or diagonal gradient can be achieved.
|
|
|
|
/// This texture is automatically disposed of when the batch is disposed.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="batch">The sprite batch</param>
|
|
|
|
/// <param name="topLeft">The color of the texture's top left corner</param>
|
|
|
|
/// <param name="topRight">The color of the texture's top right corner</param>
|
|
|
|
/// <param name="bottomLeft">The color of the texture's bottom left corner</param>
|
|
|
|
/// <param name="bottomRight">The color of the texture's bottom right corner</param>
|
|
|
|
/// <param name="width">The width of the resulting texture, or 256 by default</param>
|
|
|
|
/// <param name="height">The height of the resulting texture, or 256 by default</param>
|
|
|
|
/// <returns>A new texture with the given data</returns>
|
|
|
|
public static Texture2D GenerateGradientTexture(this SpriteBatch batch, Color topLeft, Color topRight, Color bottomLeft, Color bottomRight, int width = 256, int height = 256) {
|
|
|
|
var tex = new Texture2D(batch.GraphicsDevice, width, height);
|
|
|
|
using (var data = tex.GetTextureData()) {
|
|
|
|
for (var x = 0; x < width; x++) {
|
|
|
|
var top = Color.Lerp(topLeft, topRight, x / (float) width);
|
|
|
|
var btm = Color.Lerp(bottomLeft, bottomRight, x / (float) width);
|
|
|
|
for (var y = 0; y < height; y++)
|
|
|
|
data[x, y] = Color.Lerp(top, btm, y / (float) height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
AutoDispose(batch, tex);
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
2020-05-20 23:59:40 +02:00
|
|
|
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Rectangle?,Color,float,Vector2,SpriteEffects,float)"/>
|
2019-11-02 14:53:59 +01:00
|
|
|
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth) {
|
|
|
|
var source = sourceRectangle ?? new Rectangle(0, 0, texture.Width, texture.Height);
|
|
|
|
var scale = new Vector2(1F / source.Width, 1F / source.Height) * destinationRectangle.Size;
|
|
|
|
batch.Draw(texture, destinationRectangle.Location, sourceRectangle, color, rotation, origin, scale, effects, layerDepth);
|
|
|
|
}
|
|
|
|
|
2020-05-20 23:59:40 +02:00
|
|
|
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Rectangle?,Color)"/>
|
2019-11-02 14:53:59 +01:00
|
|
|
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color) {
|
|
|
|
batch.Draw(texture, destinationRectangle, sourceRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0);
|
|
|
|
}
|
|
|
|
|
2020-05-20 23:59:40 +02:00
|
|
|
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Color)"/>
|
2019-11-02 14:53:59 +01:00
|
|
|
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Color color) {
|
|
|
|
batch.Draw(texture, destinationRectangle, null, color);
|
|
|
|
}
|
|
|
|
|
2020-07-12 19:41:25 +02:00
|
|
|
private static void AutoDispose(SpriteBatch batch, Texture2D texture) {
|
|
|
|
batch.Disposing += (sender, ars) => {
|
|
|
|
if (texture != null) {
|
|
|
|
texture.Dispose();
|
|
|
|
texture = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-08-06 14:20:11 +02:00
|
|
|
}
|
|
|
|
}
|