Updated libraries

This commit is contained in:
Joonas Rikkonen
2021-10-27 18:57:04 +03:00
parent 234fb6bc06
commit 4b5b6c5ee6
5 changed files with 709 additions and 71 deletions
@@ -3,6 +3,9 @@
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Microsoft.Xna.Framework.Graphics
@@ -25,15 +28,58 @@ namespace Microsoft.Xna.Framework.Graphics
/// </summary>
public class SpriteBatch : GraphicsResource, ISpriteBatch
{
public struct EffectWithParams
{
private static readonly Dictionary<Type, MethodInfo> parameterSetters;
private static readonly object[] setterParams = new object[1];
static EffectWithParams()
{
parameterSetters = new Dictionary<Type, MethodInfo>();
foreach (var method in typeof(EffectParameter).GetMethods())
{
if (method.Name.Equals("SetValue", StringComparison.InvariantCulture)
&& method.GetParameters() is { Length: 1 } parameters)
{
var type = parameters[0].ParameterType;
parameterSetters[type] = method;
foreach (var derived in Assembly.GetAssembly(type).GetTypes().Where(t => t.IsSubclassOf(type)))
{
parameterSetters[derived] = method;
}
}
}
}
public Effect Effect;
public Dictionary<string, object> Params;
public EffectWithParams(Effect effect, Dictionary<string, object> parameters = null)
{
Effect = effect;
Params = parameters;
}
internal void Apply()
{
foreach (var (paramName, paramValue) in Params)
{
setterParams[0] = paramValue;
parameterSetters[paramValue.GetType()].Invoke(Effect.Parameters[paramName], setterParams);
}
Effect.CurrentTechnique.Passes[0].Apply();
}
}
#region Private Fields
readonly SpriteBatcher _batcher;
SpriteSortMode _sortMode;
BlendState _blendState;
SamplerState _samplerState;
DepthStencilState _depthStencilState;
RasterizerState _rasterizerState;
Effect _effect;
DepthStencilState _depthStencilState;
RasterizerState _rasterizerState;
EffectWithParams _effect;
bool _beginCalled;
Effect _spriteEffect;
@@ -60,7 +106,7 @@ namespace Microsoft.Xna.Framework.Graphics
if (graphicsDevice == null)
{
throw new ArgumentNullException ("graphicsDevice", FrameworkResources.ResourceCreationWhenDeviceIsNull);
}
}
this.GraphicsDevice = graphicsDevice;
@@ -107,7 +153,7 @@ namespace Microsoft.Xna.Framework.Graphics
_samplerState = samplerState ?? SamplerState.LinearClamp;
_depthStencilState = depthStencilState ?? DepthStencilState.None;
_rasterizerState = rasterizerState ?? RasterizerState.CullCounterClockwise;
_effect = effect;
_effect = new EffectWithParams(effect);
_matrix = transformMatrix;
// Setup things now so a user can change them.
@@ -119,6 +165,11 @@ namespace Microsoft.Xna.Framework.Graphics
_beginCalled = true;
}
/// <summary>
/// Returns the current effect.
/// </summary>
public Effect GetCurrentEffect() => _effect.Effect;
/// <summary>
/// Flushes all batched text and sprites to the screen.
/// </summary>
@@ -132,18 +183,31 @@ namespace Microsoft.Xna.Framework.Graphics
if (_sortMode != SpriteSortMode.Immediate)
Setup();
_batcher.DrawBatch(_sortMode, _effect);
_batcher.DrawBatch(_sortMode, _spritePass);
}
void Setup()
/// <summary>
/// Swaps the current effect.
/// </summary>
public void SwapEffect(Effect effect = null, Dictionary<string, object> parameters = null)
{
_effect = new EffectWithParams(effect, parameters);
}
public void SwapEffect(EffectWithParams effectWithParams)
{
_effect = effectWithParams;
}
void Setup()
{
var gd = GraphicsDevice;
gd.BlendState = _blendState;
gd.DepthStencilState = _depthStencilState;
gd.RasterizerState = _rasterizerState;
gd.SamplerStates[0] = _samplerState;
var vp = gd.Viewport;
if ((vp.Width != _lastViewport.Width) || (vp.Height != _lastViewport.Height))
{
@@ -169,7 +233,7 @@ namespace Microsoft.Xna.Framework.Graphics
_spritePass.Apply();
}
void CheckValid(Texture2D texture)
{
if (texture == null)
@@ -279,6 +343,7 @@ namespace Microsoft.Xna.Framework.Graphics
{
var item = _batcher.CreateBatchItem();
item.Texture = texture;
item.Effect = _effect;
item.SortKey = sortKey;
@@ -315,6 +380,7 @@ namespace Microsoft.Xna.Framework.Graphics
var item = _batcher.CreateBatchItem();
item.Texture = texture;
item.Effect = _effect;
// set SortKey based on SpriteSortMode.
switch ( _sortMode )
@@ -332,9 +398,9 @@ namespace Microsoft.Xna.Framework.Graphics
item.SortKey = -layerDepth;
break;
}
origin = origin * scale;
float w, h;
if (sourceRectangle.HasValue)
{
@@ -353,7 +419,7 @@ namespace Microsoft.Xna.Framework.Graphics
_texCoordTL = Vector2.Zero;
_texCoordBR = Vector2.One;
}
if ((effects & SpriteEffects.FlipVertically) != 0)
{
var temp = _texCoordBR.Y;
@@ -366,7 +432,7 @@ namespace Microsoft.Xna.Framework.Graphics
_texCoordBR.X = _texCoordTL.X;
_texCoordTL.X = temp;
}
if (rotation == 0f)
{
item.Set(position.X - origin.X,
@@ -393,7 +459,7 @@ namespace Microsoft.Xna.Framework.Graphics
_texCoordBR,
layerDepth);
}
FlushIfNeeded();
}
@@ -444,9 +510,10 @@ namespace Microsoft.Xna.Framework.Graphics
float layerDepth)
{
CheckValid(texture);
var item = _batcher.CreateBatchItem();
item.Texture = texture;
item.Effect = _effect;
// set SortKey based on SpriteSortMode.
switch ( _sortMode )
@@ -478,7 +545,7 @@ namespace Microsoft.Xna.Framework.Graphics
else
origin.X = origin.X * (float)destinationRectangle.Width * texture.TexelWidth;
if(srcRect.Height != 0)
origin.Y = origin.Y * (float)destinationRectangle.Height / (float)srcRect.Height;
origin.Y = origin.Y * (float)destinationRectangle.Height / (float)srcRect.Height;
else
origin.Y = origin.Y * (float)destinationRectangle.Height * texture.TexelHeight;
}
@@ -486,11 +553,11 @@ namespace Microsoft.Xna.Framework.Graphics
{
_texCoordTL = Vector2.Zero;
_texCoordBR = Vector2.One;
origin.X = origin.X * (float)destinationRectangle.Width * texture.TexelWidth;
origin.Y = origin.Y * (float)destinationRectangle.Height * texture.TexelHeight;
}
if ((effects & SpriteEffects.FlipVertically) != 0)
{
var temp = _texCoordBR.Y;
@@ -539,7 +606,7 @@ namespace Microsoft.Xna.Framework.Graphics
{
if (_sortMode == SpriteSortMode.Immediate)
{
_batcher.DrawBatch(_sortMode, _effect);
_batcher.DrawBatch(_sortMode, _spritePass);
}
}
@@ -553,10 +620,11 @@ namespace Microsoft.Xna.Framework.Graphics
public void Draw (Texture2D texture, Vector2 position, Rectangle? sourceRectangle, Color color)
{
CheckValid(texture);
var item = _batcher.CreateBatchItem();
item.Texture = texture;
item.Effect = _effect;
// set SortKey based on SpriteSortMode.
item.SortKey = _sortMode == SpriteSortMode.Texture ? texture.SortingKey : 0;
@@ -600,13 +668,14 @@ namespace Microsoft.Xna.Framework.Graphics
public void Draw (Texture2D texture, Rectangle destinationRectangle, Rectangle? sourceRectangle, Color color)
{
CheckValid(texture);
var item = _batcher.CreateBatchItem();
item.Texture = texture;
item.Effect = _effect;
// set SortKey based on SpriteSortMode.
item.SortKey = _sortMode == SpriteSortMode.Texture ? texture.SortingKey : 0;
if (sourceRectangle.HasValue)
{
var srcRect = sourceRectangle.GetValueOrDefault();
@@ -629,7 +698,7 @@ namespace Microsoft.Xna.Framework.Graphics
_texCoordTL,
_texCoordBR,
0);
FlushIfNeeded();
}
@@ -642,13 +711,14 @@ namespace Microsoft.Xna.Framework.Graphics
public void Draw (Texture2D texture, Vector2 position, Color color)
{
CheckValid(texture);
var item = _batcher.CreateBatchItem();
item.Texture = texture;
item.Effect = _effect;
// set SortKey based on SpriteSortMode.
item.SortKey = _sortMode == SpriteSortMode.Texture ? texture.SortingKey : 0;
item.Set(position.X,
position.Y,
texture.Width,
@@ -670,13 +740,14 @@ namespace Microsoft.Xna.Framework.Graphics
public void Draw(Texture2D texture, Rectangle destinationRectangle, Color color)
{
CheckValid(texture);
var item = _batcher.CreateBatchItem();
item.Texture = texture;
item.Effect = _effect;
// set SortKey based on SpriteSortMode.
item.SortKey = _sortMode == SpriteSortMode.Texture ? texture.SortingKey : 0;
item.Set(destinationRectangle.X,
destinationRectangle.Y,
destinationRectangle.Width,
@@ -685,7 +756,7 @@ namespace Microsoft.Xna.Framework.Graphics
Vector2.Zero,
Vector2.One,
0);
FlushIfNeeded();
}
@@ -699,7 +770,7 @@ namespace Microsoft.Xna.Framework.Graphics
public unsafe void DrawString (SpriteFont spriteFont, string text, Vector2 position, Color color)
{
CheckValid(spriteFont, text);
float sortKey = (_sortMode == SpriteSortMode.Texture) ? spriteFont.Texture.SortingKey : 0;
var offset = Vector2.Zero;
@@ -720,7 +791,7 @@ namespace Microsoft.Xna.Framework.Graphics
firstGlyphOfLine = true;
continue;
}
var currentGlyphIndex = spriteFont.GetGlyphIndexOrDefault(c);
var pCurrentGlyph = pGlyphs + currentGlyphIndex;
@@ -737,15 +808,16 @@ namespace Microsoft.Xna.Framework.Graphics
offset.X += spriteFont.Spacing + pCurrentGlyph->LeftSideBearing;
}
var p = offset;
var p = offset;
p.X += pCurrentGlyph->Cropping.X;
p.Y += pCurrentGlyph->Cropping.Y;
p += position;
var item = _batcher.CreateBatchItem();
item.Texture = spriteFont.Texture;
item.Effect = _effect;
item.SortKey = sortKey;
_texCoordTL.X = pCurrentGlyph->BoundsInTexture.X * spriteFont.Texture.TexelWidth;
_texCoordTL.Y = pCurrentGlyph->BoundsInTexture.Y * spriteFont.Texture.TexelHeight;
_texCoordBR.X = (pCurrentGlyph->BoundsInTexture.X + pCurrentGlyph->BoundsInTexture.Width) * spriteFont.Texture.TexelWidth;
@@ -759,7 +831,7 @@ namespace Microsoft.Xna.Framework.Graphics
_texCoordTL,
_texCoordBR,
0);
offset.X += pCurrentGlyph->Width + pCurrentGlyph->RightSideBearing;
}
@@ -804,7 +876,7 @@ namespace Microsoft.Xna.Framework.Graphics
float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
{
CheckValid(spriteFont, text);
float sortKey = 0;
// set SortKey based on SpriteSortMode.
switch (_sortMode)
@@ -831,7 +903,7 @@ namespace Microsoft.Xna.Framework.Graphics
if (flippedVert || flippedHorz)
{
Vector2 size;
var source = new SpriteFont.CharacterSource(text);
spriteFont.MeasureString(ref source, out size);
@@ -847,7 +919,7 @@ namespace Microsoft.Xna.Framework.Graphics
flipAdjustment.Y = spriteFont.LineSpacing - size.Y;
}
}
Matrix transformation = Matrix.Identity;
float cos = 0, sin = 0;
if (rotation == 0)
@@ -866,7 +938,7 @@ namespace Microsoft.Xna.Framework.Graphics
transformation.M21 = (flippedVert ? -scale.Y : scale.Y) * (-sin);
transformation.M22 = (flippedVert ? -scale.Y : scale.Y) * cos;
transformation.M41 = (((flipAdjustment.X - origin.X) * transformation.M11) + (flipAdjustment.Y - origin.Y) * transformation.M21) + position.X;
transformation.M42 = (((flipAdjustment.X - origin.X) * transformation.M12) + (flipAdjustment.Y - origin.Y) * transformation.M22) + position.Y;
transformation.M42 = (((flipAdjustment.X - origin.X) * transformation.M12) + (flipAdjustment.Y - origin.Y) * transformation.M22) + position.Y;
}
var offset = Vector2.Zero;
@@ -916,15 +988,16 @@ namespace Microsoft.Xna.Framework.Graphics
Vector2.Transform(ref p, ref transformation, out p);
var item = _batcher.CreateBatchItem();
var item = _batcher.CreateBatchItem();
item.Texture = spriteFont.Texture;
item.Effect = _effect;
item.SortKey = sortKey;
_texCoordTL.X = pCurrentGlyph->BoundsInTexture.X * spriteFont.Texture.TexelWidth;
_texCoordTL.Y = pCurrentGlyph->BoundsInTexture.Y * spriteFont.Texture.TexelHeight;
_texCoordBR.X = (pCurrentGlyph->BoundsInTexture.X + pCurrentGlyph->BoundsInTexture.Width) * spriteFont.Texture.TexelWidth;
_texCoordBR.Y = (pCurrentGlyph->BoundsInTexture.Y + pCurrentGlyph->BoundsInTexture.Height) * spriteFont.Texture.TexelHeight;
if ((effects & SpriteEffects.FlipVertically) != 0)
{
var temp = _texCoordBR.Y;
@@ -964,7 +1037,7 @@ namespace Microsoft.Xna.Framework.Graphics
_texCoordBR,
layerDepth);
}
offset.X += pCurrentGlyph->Width + pCurrentGlyph->RightSideBearing;
}
@@ -982,7 +1055,7 @@ namespace Microsoft.Xna.Framework.Graphics
public unsafe void DrawString (SpriteFont spriteFont, StringBuilder text, Vector2 position, Color color)
{
CheckValid(spriteFont, text);
float sortKey = (_sortMode == SpriteSortMode.Texture) ? spriteFont.Texture.SortingKey : 0;
var offset = Vector2.Zero;
@@ -1020,15 +1093,16 @@ namespace Microsoft.Xna.Framework.Graphics
offset.X += spriteFont.Spacing + pCurrentGlyph->LeftSideBearing;
}
var p = offset;
var p = offset;
p.X += pCurrentGlyph->Cropping.X;
p.Y += pCurrentGlyph->Cropping.Y;
p += position;
var item = _batcher.CreateBatchItem();
item.Texture = spriteFont.Texture;
item.Effect = _effect;
item.SortKey = sortKey;
_texCoordTL.X = pCurrentGlyph->BoundsInTexture.X * spriteFont.Texture.TexelWidth;
_texCoordTL.Y = pCurrentGlyph->BoundsInTexture.Y * spriteFont.Texture.TexelHeight;
_texCoordBR.X = (pCurrentGlyph->BoundsInTexture.X + pCurrentGlyph->BoundsInTexture.Width) * spriteFont.Texture.TexelWidth;
@@ -1087,7 +1161,7 @@ namespace Microsoft.Xna.Framework.Graphics
float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
{
CheckValid(spriteFont, text);
float sortKey = 0;
// set SortKey based on SpriteSortMode.
switch (_sortMode)
@@ -1129,7 +1203,7 @@ namespace Microsoft.Xna.Framework.Graphics
flipAdjustment.Y = spriteFont.LineSpacing - size.Y;
}
}
Matrix transformation = Matrix.Identity;
float cos = 0, sin = 0;
if (rotation == 0)
@@ -1148,7 +1222,7 @@ namespace Microsoft.Xna.Framework.Graphics
transformation.M21 = (flippedVert ? -scale.Y : scale.Y) * (-sin);
transformation.M22 = (flippedVert ? -scale.Y : scale.Y) * cos;
transformation.M41 = (((flipAdjustment.X - origin.X) * transformation.M11) + (flipAdjustment.Y - origin.Y) * transformation.M21) + position.X;
transformation.M42 = (((flipAdjustment.X - origin.X) * transformation.M12) + (flipAdjustment.Y - origin.Y) * transformation.M22) + position.Y;
transformation.M42 = (((flipAdjustment.X - origin.X) * transformation.M12) + (flipAdjustment.Y - origin.Y) * transformation.M22) + position.Y;
}
var offset = Vector2.Zero;
@@ -1197,16 +1271,17 @@ namespace Microsoft.Xna.Framework.Graphics
p.Y += pCurrentGlyph->Cropping.Y;
Vector2.Transform(ref p, ref transformation, out p);
var item = _batcher.CreateBatchItem();
var item = _batcher.CreateBatchItem();
item.Texture = spriteFont.Texture;
item.Effect = _effect;
item.SortKey = sortKey;
_texCoordTL.X = pCurrentGlyph->BoundsInTexture.X * (float)spriteFont.Texture.TexelWidth;
_texCoordTL.Y = pCurrentGlyph->BoundsInTexture.Y * (float)spriteFont.Texture.TexelHeight;
_texCoordBR.X = (pCurrentGlyph->BoundsInTexture.X + pCurrentGlyph->BoundsInTexture.Width) * (float)spriteFont.Texture.TexelWidth;
_texCoordBR.Y = (pCurrentGlyph->BoundsInTexture.Y + pCurrentGlyph->BoundsInTexture.Height) * (float)spriteFont.Texture.TexelHeight;
if ((effects & SpriteEffects.FlipVertically) != 0)
{
var temp = _texCoordBR.Y;